use crate::*;
use core::fmt;
pub trait Mappable: Valuable {
fn size_hint(&self) -> (usize, Option<usize>);
}
macro_rules! deref {
(
$(
$(#[$attrs:meta])*
$ty:ty,
)*
) => {
$(
$(#[$attrs])*
impl<T: ?Sized + Mappable> Mappable for $ty {
fn size_hint(&self) -> (usize, Option<usize>) {
T::size_hint(&**self)
}
}
)*
};
}
deref! {
&T,
&mut T,
#[cfg(feature = "alloc")]
alloc::boxed::Box<T>,
#[cfg(feature = "alloc")]
alloc::rc::Rc<T>,
#[cfg(not(valuable_no_atomic_cas))]
#[cfg(feature = "alloc")]
alloc::sync::Arc<T>,
}
#[cfg(feature = "std")]
impl<K: Valuable, V: Valuable, S> Valuable for std::collections::HashMap<K, V, S> {
fn as_value(&self) -> Value<'_> {
Value::Mappable(self)
}
fn visit(&self, visit: &mut dyn Visit) {
for (key, value) in self.iter() {
visit.visit_entry(key.as_value(), value.as_value());
}
}
}
#[cfg(feature = "std")]
impl<K: Valuable, V: Valuable, S> Mappable for std::collections::HashMap<K, V, S> {
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter().size_hint()
}
}
#[cfg(feature = "alloc")]
impl<K: Valuable, V: Valuable> Valuable for alloc::collections::BTreeMap<K, V> {
fn as_value(&self) -> Value<'_> {
Value::Mappable(self)
}
fn visit(&self, visit: &mut dyn Visit) {
for (key, value) in self.iter() {
visit.visit_entry(key.as_value(), value.as_value());
}
}
}
#[cfg(feature = "alloc")]
impl<K: Valuable, V: Valuable> Mappable for alloc::collections::BTreeMap<K, V> {
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter().size_hint()
}
}
impl fmt::Debug for dyn Mappable + '_ {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
struct DebugMappable<'a, 'b> {
fmt: fmt::DebugMap<'a, 'b>,
}
impl Visit for DebugMappable<'_, '_> {
fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
self.fmt.entry(&key, &value);
}
fn visit_value(&mut self, _: Value<'_>) {}
}
let mut debug = DebugMappable {
fmt: fmt.debug_map(),
};
self.visit(&mut debug);
debug.fmt.finish()
}
}