aboutsummaryrefslogtreecommitdiff
path: root/src/reflect/map.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect/map.rs')
-rw-r--r--src/reflect/map.rs66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/reflect/map.rs b/src/reflect/map.rs
new file mode 100644
index 0000000..9f03123
--- /dev/null
+++ b/src/reflect/map.rs
@@ -0,0 +1,66 @@
+use std::collections::hash_map;
+use std::collections::HashMap;
+use std::hash::Hash;
+
+use super::value::ProtobufValue;
+
+/// Implemented for `HashMap` with appropriate keys and values
+pub trait ReflectMap: 'static {
+ fn reflect_iter(&self) -> ReflectMapIter;
+
+ fn len(&self) -> usize;
+}
+
+impl<K: ProtobufValue + Eq + Hash + 'static, V: ProtobufValue + 'static> ReflectMap
+ for HashMap<K, V>
+{
+ fn reflect_iter<'a>(&'a self) -> ReflectMapIter<'a> {
+ ReflectMapIter {
+ imp: Box::new(ReflectMapIterImpl::<'a, K, V> { iter: self.iter() }),
+ }
+ }
+
+ fn len(&self) -> usize {
+ HashMap::len(self)
+ }
+}
+
+trait ReflectMapIterTrait<'a> {
+ fn next(&mut self) -> Option<(&'a ProtobufValue, &'a ProtobufValue)>;
+}
+
+struct ReflectMapIterImpl<'a, K: Eq + Hash + 'static, V: 'static> {
+ iter: hash_map::Iter<'a, K, V>,
+}
+
+impl<'a, K: ProtobufValue + Eq + Hash + 'static, V: ProtobufValue + 'static> ReflectMapIterTrait<'a>
+ for ReflectMapIterImpl<'a, K, V>
+{
+ fn next(&mut self) -> Option<(&'a ProtobufValue, &'a ProtobufValue)> {
+ match self.iter.next() {
+ Some((k, v)) => Some((k as &ProtobufValue, v as &ProtobufValue)),
+ None => None,
+ }
+ }
+}
+
+pub struct ReflectMapIter<'a> {
+ imp: Box<ReflectMapIterTrait<'a> + 'a>,
+}
+
+impl<'a> Iterator for ReflectMapIter<'a> {
+ type Item = (&'a ProtobufValue, &'a ProtobufValue);
+
+ fn next(&mut self) -> Option<(&'a ProtobufValue, &'a ProtobufValue)> {
+ self.imp.next()
+ }
+}
+
+impl<'a> IntoIterator for &'a ReflectMap {
+ type IntoIter = ReflectMapIter<'a>;
+ type Item = (&'a ProtobufValue, &'a ProtobufValue);
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.reflect_iter()
+ }
+}