Skip to content

Commit

Permalink
Working on support of BTreeMap
Browse files Browse the repository at this point in the history
This commit adds reflection support for it, but it is not used yet.
Taken from PR #700.
  • Loading branch information
stepancheg committed Jun 25, 2024
1 parent 87e0b10 commit 7f9f60d
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 6 deletions.
57 changes: 52 additions & 5 deletions protobuf/src/reflect/map/generated.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::collections::btree_map;
use std::collections::hash_map;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::hash::Hash;

Expand All @@ -19,7 +21,9 @@ where
K::RuntimeType: RuntimeTypeMapKey,
{
fn reflect_iter<'a>(&'a self) -> ReflectMapIter<'a> {
ReflectMapIter::new(GeneratedMapIterImpl::<'a, K, V> { iter: self.iter() })
ReflectMapIter::new(GeneratedMapIterImpl::<'a, K, V, hash_map::Iter<'a, K, V>> {
iter: self.iter(),
})
}

fn len(&self) -> usize {
Expand Down Expand Up @@ -53,12 +57,55 @@ where
}
}

struct GeneratedMapIterImpl<'a, K: Eq + Hash + 'static, V: 'static> {
iter: hash_map::Iter<'a, K, V>,
impl<K, V> ReflectMap for BTreeMap<K, V>
where
K: ProtobufValue + Ord,
V: ProtobufValue,
K::RuntimeType: RuntimeTypeMapKey,
{
fn reflect_iter<'a>(&'a self) -> ReflectMapIter<'a> {
ReflectMapIter::new(
GeneratedMapIterImpl::<'a, K, V, btree_map::Iter<'a, K, V>> { iter: self.iter() },
)
}

fn len(&self) -> usize {
BTreeMap::len(self)
}

fn is_empty(&self) -> bool {
self.is_empty()
}

fn get<'a>(&'a self, key: ReflectValueRef) -> Option<ReflectValueRef<'a>> {
<K::RuntimeType as RuntimeTypeMapKey>::btree_map_get(self, key).map(V::RuntimeType::as_ref)
}

fn insert(&mut self, key: ReflectValueBox, value: ReflectValueBox) {
let key: K = key.downcast().expect("wrong key type");
let value: V = value.downcast().expect("wrong value type");
self.insert(key, value);
}

fn clear(&mut self) {
self.clear();
}

fn key_type(&self) -> RuntimeType {
K::RuntimeType::runtime_type_box()
}

fn value_type(&self) -> RuntimeType {
V::RuntimeType::runtime_type_box()
}
}

struct GeneratedMapIterImpl<'a, K: 'static, V: 'static, I: Iterator<Item = (&'a K, &'a V)>> {
iter: I,
}

impl<'a, K: ProtobufValue + Eq + Hash, V: ProtobufValue> ReflectMapIterTrait<'a>
for GeneratedMapIterImpl<'a, K, V>
impl<'a, K: ProtobufValue, V: ProtobufValue, I: Iterator<Item = (&'a K, &'a V)>>
ReflectMapIterTrait<'a> for GeneratedMapIterImpl<'a, K, V, I>
{
fn next(&mut self) -> Option<(ReflectValueRef<'a>, ReflectValueRef<'a>)> {
match self.iter.next() {
Expand Down
76 changes: 75 additions & 1 deletion protobuf/src/reflect/runtime_types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Implementations of `RuntimeType` for all types.
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::fmt;
use std::marker;
Expand Down Expand Up @@ -123,6 +124,12 @@ pub trait RuntimeTypeMapKey: RuntimeTypeTrait {
/// Query hash map with a given key.
fn hash_map_get<'a, V>(map: &'a HashMap<Self::Value, V>, key: ReflectValueRef)
-> Option<&'a V>;

/// Query btree map with a given key.
fn btree_map_get<'a, V>(
map: &'a BTreeMap<Self::Value, V>,
key: ReflectValueRef,
) -> Option<&'a V>;
}

/// Implementation for `f32`
Expand Down Expand Up @@ -318,6 +325,16 @@ impl RuntimeTypeMapKey for RuntimeTypeI32 {
_ => None,
}
}

fn btree_map_get<'a, V>(
map: &'a BTreeMap<Self::Value, V>,
key: ReflectValueRef,
) -> Option<&'a V> {
match key {
ReflectValueRef::I32(i) => map.get(&i),
_ => None,
}
}
}

impl RuntimeTypeTrait for RuntimeTypeI64 {
Expand Down Expand Up @@ -371,7 +388,20 @@ impl RuntimeTypeTrait for RuntimeTypeI64 {
}
}
impl RuntimeTypeMapKey for RuntimeTypeI64 {
fn hash_map_get<'a, V>(map: &'a HashMap<i64, V>, key: ReflectValueRef) -> Option<&'a V> {
fn hash_map_get<'a, V>(
map: &'a HashMap<Self::Value, V>,
key: ReflectValueRef,
) -> Option<&'a V> {
match key {
ReflectValueRef::I64(i) => map.get(&i),
_ => None,
}
}

fn btree_map_get<'a, V>(
map: &'a BTreeMap<Self::Value, V>,
key: ReflectValueRef,
) -> Option<&'a V> {
match key {
ReflectValueRef::I64(i) => map.get(&i),
_ => None,
Expand Down Expand Up @@ -435,6 +465,13 @@ impl RuntimeTypeMapKey for RuntimeTypeU32 {
_ => None,
}
}

fn btree_map_get<'a, V>(map: &'a BTreeMap<u32, V>, key: ReflectValueRef) -> Option<&'a V> {
match key {
ReflectValueRef::U32(i) => map.get(&i),
_ => None,
}
}
}

impl RuntimeTypeTrait for RuntimeTypeU64 {
Expand Down Expand Up @@ -493,6 +530,13 @@ impl RuntimeTypeMapKey for RuntimeTypeU64 {
_ => None,
}
}

fn btree_map_get<'a, V>(map: &'a BTreeMap<u64, V>, key: ReflectValueRef) -> Option<&'a V> {
match key {
ReflectValueRef::U64(i) => map.get(&i),
_ => None,
}
}
}

impl RuntimeTypeTrait for RuntimeTypeBool {
Expand Down Expand Up @@ -548,6 +592,16 @@ impl RuntimeTypeMapKey for RuntimeTypeBool {
_ => None,
}
}

fn btree_map_get<'a, V>(
map: &'a BTreeMap<Self::Value, V>,
key: ReflectValueRef,
) -> Option<&'a V> {
match key {
ReflectValueRef::Bool(i) => map.get(&i),
_ => None,
}
}
}

impl RuntimeTypeTrait for RuntimeTypeString {
Expand Down Expand Up @@ -606,6 +660,20 @@ impl RuntimeTypeMapKey for RuntimeTypeString {
_ => None,
}
}

/// Query btree map with a given key.
fn btree_map_get<'a, V>(
map: &'a BTreeMap<Self::Value, V>,
key: ReflectValueRef,
) -> Option<&'a V>
where
Self::Value: Ord,
{
match key {
ReflectValueRef::String(s) => map.get(s),
_ => None,
}
}
}

impl RuntimeTypeTrait for RuntimeTypeVecU8 {
Expand Down Expand Up @@ -770,6 +838,12 @@ impl RuntimeTypeMapKey for RuntimeTypeTokioChars {
_ => None,
}
}
fn btree_map_get<'a, V>(map: &'a BTreeMap<Chars, V>, key: ReflectValueRef) -> Option<&'a V> {
match key {
ReflectValueRef::String(s) => map.get(&*s),
_ => None,
}
}
}

impl<E> RuntimeTypeTrait for RuntimeTypeEnumOrUnknown<E>
Expand Down

0 comments on commit 7f9f60d

Please sign in to comment.