diff --git a/src/kv/source.rs b/src/kv/source.rs index 2a26c4a05..c8e7a05a3 100644 --- a/src/kv/source.rs +++ b/src/kv/source.rs @@ -30,14 +30,10 @@ pub trait Source { /// /// A source that can provide a more efficient implementation of this method /// should override it. - #[cfg(not(test))] fn get(&self, key: Key) -> Option> { get_default(self, key) } - #[cfg(test)] - fn get(&self, key: Key) -> Option>; - /// Count the number of key-value pairs that can be visited. /// /// # Implementation notes @@ -47,17 +43,13 @@ pub trait Source { /// /// A subsequent call to `visit` should yield the same number of key-value pairs /// to the visitor, unless that visitor fails part way through. - #[cfg(not(test))] fn count(&self) -> usize { count_default(self) } - - #[cfg(test)] - fn count(&self) -> usize; } /// The default implementation of `Source::get` -pub(crate) fn get_default<'v>(source: &'v (impl Source + ?Sized), key: Key) -> Option> { +fn get_default<'v>(source: &'v (impl Source + ?Sized), key: Key) -> Option> { struct Get<'k, 'v> { key: Key<'k>, found: Option>, @@ -80,7 +72,7 @@ pub(crate) fn get_default<'v>(source: &'v (impl Source + ?Sized), key: Key) -> O } /// The default implementation of `Source::count`. -pub(crate) fn count_default(source: impl Source) -> usize { +fn count_default(source: impl Source) -> usize { struct Count(usize); impl<'kvs> Visitor<'kvs> for Count { @@ -158,7 +150,7 @@ where } fn count(&self) -> usize { - self.len() + self.iter().map(Source::count).sum() } } @@ -167,7 +159,7 @@ where S: Source, { fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - if let Some(ref source) = *self { + if let Some(source) = self { source.visit(visitor)?; } @@ -233,6 +225,8 @@ mod std_support { use std::borrow::Borrow; use std::collections::{BTreeMap, HashMap}; use std::hash::{BuildHasher, Hash}; + use std::rc::Rc; + use std::sync::Arc; impl Source for Box where @@ -251,6 +245,40 @@ mod std_support { } } + impl Source for Arc + where + S: Source + ?Sized, + { + fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { + Source::visit(&**self, visitor) + } + + fn get(&self, key: Key) -> Option> { + Source::get(&**self, key) + } + + fn count(&self) -> usize { + Source::count(&**self) + } + } + + impl Source for Rc + where + S: Source + ?Sized, + { + fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { + Source::visit(&**self, visitor) + } + + fn get(&self, key: Key) -> Option> { + Source::get(&**self, key) + } + + fn count(&self) -> usize { + Source::count(&**self) + } + } + impl Source for Vec where S: Source, @@ -714,14 +742,6 @@ mod tests { fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { visitor.visit_pair(self.key.to_key(), self.value.to_value()) } - - fn get(&self, key: Key) -> Option> { - get_default(self, key) - } - - fn count(&self) -> usize { - count_default(self) - } } assert_eq!(1, Source::count(&("a", 1))); diff --git a/src/kv/value.rs b/src/kv/value.rs index d4c45ea7f..352f965ea 100644 --- a/src/kv/value.rs +++ b/src/kv/value.rs @@ -470,14 +470,14 @@ impl<'v> From<&'v i128> for Value<'v> { impl<'v> From<&'v std::num::NonZeroU128> for Value<'v> { fn from(v: &'v std::num::NonZeroU128) -> Value<'v> { // SAFETY: `NonZeroU128` and `u128` have the same ABI - Value::from_value_bag(unsafe { std::mem::transmute::<&std::num::NonZeroU128, &u128>(v) }) + Value::from_value_bag(unsafe { &*(v as *const std::num::NonZeroU128 as *const u128) }) } } impl<'v> From<&'v std::num::NonZeroI128> for Value<'v> { fn from(v: &'v std::num::NonZeroI128) -> Value<'v> { // SAFETY: `NonZeroI128` and `i128` have the same ABI - Value::from_value_bag(unsafe { std::mem::transmute::<&std::num::NonZeroI128, &i128>(v) }) + Value::from_value_bag(unsafe { &*(v as *const std::num::NonZeroI128 as *const i128) }) } } @@ -589,6 +589,8 @@ impl<'v> Value<'v> { #[cfg(feature = "kv_unstable_std")] mod std_support { use std::borrow::Cow; + use std::rc::Rc; + use std::sync::Arc; use super::*; @@ -601,6 +603,24 @@ mod std_support { } } + impl ToValue for Arc + where + T: ToValue + ?Sized, + { + fn to_value(&self) -> Value { + (**self).to_value() + } + } + + impl ToValue for Rc + where + T: ToValue + ?Sized, + { + fn to_value(&self) -> Value { + (**self).to_value() + } + } + impl ToValue for String { fn to_value(&self) -> Value { Value::from(&**self)