From a0340af67f45024c887a6f521f11ddb5c6095b77 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 12 May 2021 06:47:03 +0900 Subject: [PATCH 1/2] impl Listable for std collections --- valuable/src/listable.rs | 144 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/valuable/src/listable.rs b/valuable/src/listable.rs index 011340e..6f27a8d 100644 --- a/valuable/src/listable.rs +++ b/valuable/src/listable.rs @@ -46,6 +46,42 @@ impl Listable for alloc::boxed::Box<[T]> { } } +#[cfg(feature = "alloc")] +impl Valuable for alloc::rc::Rc<[T]> { + fn as_value(&self) -> Value<'_> { + Value::Listable(self) + } + + fn visit(&self, visit: &mut dyn Visit) { + T::visit_slice(self, visit); + } +} + +#[cfg(feature = "alloc")] +impl Listable for alloc::rc::Rc<[T]> { + fn size_hint(&self) -> (usize, Option) { + (self.len(), Some(self.len())) + } +} + +#[cfg(feature = "alloc")] +impl Valuable for alloc::sync::Arc<[T]> { + fn as_value(&self) -> Value<'_> { + Value::Listable(self) + } + + fn visit(&self, visit: &mut dyn Visit) { + T::visit_slice(self, visit); + } +} + +#[cfg(feature = "alloc")] +impl Listable for alloc::sync::Arc<[T]> { + fn size_hint(&self) -> (usize, Option) { + (self.len(), Some(self.len())) + } +} + impl Listable for [T; N] { fn size_hint(&self) -> (usize, Option) { (self.len(), Some(self.len())) @@ -59,6 +95,114 @@ impl Listable for alloc::vec::Vec { } } +#[cfg(feature = "alloc")] +impl Valuable for alloc::collections::VecDeque { + fn as_value(&self) -> Value<'_> { + Value::Listable(self) + } + + fn visit(&self, visit: &mut dyn Visit) { + for value in self.iter() { + visit.visit_value(value.as_value()); + } + } +} + +#[cfg(feature = "alloc")] +impl Listable for alloc::collections::VecDeque { + fn size_hint(&self) -> (usize, Option) { + (self.len(), Some(self.len())) + } +} + +#[cfg(feature = "alloc")] +impl Valuable for alloc::collections::LinkedList { + fn as_value(&self) -> Value<'_> { + Value::Listable(self) + } + + fn visit(&self, visit: &mut dyn Visit) { + for value in self.iter() { + visit.visit_value(value.as_value()); + } + } +} + +#[cfg(feature = "alloc")] +impl Listable for alloc::collections::LinkedList { + fn size_hint(&self) -> (usize, Option) { + (self.len(), Some(self.len())) + } +} + +#[cfg(feature = "alloc")] +impl Valuable for alloc::collections::BinaryHeap { + fn as_value(&self) -> Value<'_> { + Value::Listable(self) + } + + fn visit(&self, visit: &mut dyn Visit) { + for value in self.iter() { + visit.visit_value(value.as_value()); + } + } +} + +#[cfg(feature = "alloc")] +impl Listable for alloc::collections::BinaryHeap { + fn size_hint(&self) -> (usize, Option) { + (self.len(), Some(self.len())) + } +} + +#[cfg(feature = "alloc")] +impl Valuable for alloc::collections::BTreeSet { + fn as_value(&self) -> Value<'_> { + Value::Listable(self) + } + + fn visit(&self, visit: &mut dyn Visit) { + for value in self.iter() { + visit.visit_value(value.as_value()); + } + } +} + +#[cfg(feature = "alloc")] +impl Listable for alloc::collections::BTreeSet { + fn size_hint(&self) -> (usize, Option) { + (self.len(), Some(self.len())) + } +} + +#[cfg(feature = "std")] +impl Valuable for std::collections::HashSet +where + T: Valuable + Eq + std::hash::Hash, + H: std::hash::BuildHasher, +{ + fn as_value(&self) -> Value<'_> { + Value::Listable(self) + } + + fn visit(&self, visit: &mut dyn Visit) { + for value in self.iter() { + visit.visit_value(value.as_value()); + } + } +} + +#[cfg(feature = "std")] +impl Listable for std::collections::HashSet +where + T: Valuable + Eq + std::hash::Hash, + H: std::hash::BuildHasher, +{ + fn size_hint(&self) -> (usize, Option) { + (self.len(), Some(self.len())) + } +} + impl fmt::Debug for dyn Listable + '_ { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { struct DebugListable<'a, 'b> { From e1a9a473864c6228d9356e140f4324b744144ebd Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 12 May 2021 06:48:51 +0900 Subject: [PATCH 2/2] use macros for Listable impls --- valuable/src/listable.rs | 244 +++++++++++++-------------------------- valuable/src/valuable.rs | 44 +------ 2 files changed, 81 insertions(+), 207 deletions(-) diff --git a/valuable/src/listable.rs b/valuable/src/listable.rs index 6f27a8d..9521dff 100644 --- a/valuable/src/listable.rs +++ b/valuable/src/listable.rs @@ -33,174 +33,90 @@ impl Listable for alloc::sync::Arc { } } -impl Listable for &'_ [T] { - fn size_hint(&self) -> (usize, Option) { - (self.len(), Some(self.len())) - } -} - -#[cfg(feature = "alloc")] -impl Listable for alloc::boxed::Box<[T]> { - fn size_hint(&self) -> (usize, Option) { - (self.len(), Some(self.len())) - } -} - -#[cfg(feature = "alloc")] -impl Valuable for alloc::rc::Rc<[T]> { - fn as_value(&self) -> Value<'_> { - Value::Listable(self) - } - - fn visit(&self, visit: &mut dyn Visit) { - T::visit_slice(self, visit); - } -} - -#[cfg(feature = "alloc")] -impl Listable for alloc::rc::Rc<[T]> { - fn size_hint(&self) -> (usize, Option) { - (self.len(), Some(self.len())) - } -} - -#[cfg(feature = "alloc")] -impl Valuable for alloc::sync::Arc<[T]> { - fn as_value(&self) -> Value<'_> { - Value::Listable(self) - } - - fn visit(&self, visit: &mut dyn Visit) { - T::visit_slice(self, visit); - } -} - -#[cfg(feature = "alloc")] -impl Listable for alloc::sync::Arc<[T]> { - fn size_hint(&self) -> (usize, Option) { - (self.len(), Some(self.len())) - } -} - -impl Listable for [T; N] { - fn size_hint(&self) -> (usize, Option) { - (self.len(), Some(self.len())) - } -} - -#[cfg(feature = "alloc")] -impl Listable for alloc::vec::Vec { - fn size_hint(&self) -> (usize, Option) { - (self.len(), Some(self.len())) - } -} - -#[cfg(feature = "alloc")] -impl Valuable for alloc::collections::VecDeque { - fn as_value(&self) -> Value<'_> { - Value::Listable(self) - } - - fn visit(&self, visit: &mut dyn Visit) { - for value in self.iter() { - visit.visit_value(value.as_value()); - } - } -} - -#[cfg(feature = "alloc")] -impl Listable for alloc::collections::VecDeque { - fn size_hint(&self) -> (usize, Option) { - (self.len(), Some(self.len())) - } -} - -#[cfg(feature = "alloc")] -impl Valuable for alloc::collections::LinkedList { - fn as_value(&self) -> Value<'_> { - Value::Listable(self) - } - - fn visit(&self, visit: &mut dyn Visit) { - for value in self.iter() { - visit.visit_value(value.as_value()); - } - } -} - -#[cfg(feature = "alloc")] -impl Listable for alloc::collections::LinkedList { - fn size_hint(&self) -> (usize, Option) { - (self.len(), Some(self.len())) - } -} - -#[cfg(feature = "alloc")] -impl Valuable for alloc::collections::BinaryHeap { - fn as_value(&self) -> Value<'_> { - Value::Listable(self) - } - - fn visit(&self, visit: &mut dyn Visit) { - for value in self.iter() { - visit.visit_value(value.as_value()); - } - } -} - -#[cfg(feature = "alloc")] -impl Listable for alloc::collections::BinaryHeap { - fn size_hint(&self) -> (usize, Option) { - (self.len(), Some(self.len())) - } -} - -#[cfg(feature = "alloc")] -impl Valuable for alloc::collections::BTreeSet { - fn as_value(&self) -> Value<'_> { - Value::Listable(self) - } - - fn visit(&self, visit: &mut dyn Visit) { - for value in self.iter() { - visit.visit_value(value.as_value()); - } - } -} +macro_rules! slice { + ( + $( + $(#[$attrs:meta])* + ($($generics:tt)*) $ty:ty, + )* + ) => { + $( + $(#[$attrs])* + impl<$($generics)*> Valuable for $ty { + fn as_value(&self) -> Value<'_> { + Value::Listable(self as &dyn Listable) + } -#[cfg(feature = "alloc")] -impl Listable for alloc::collections::BTreeSet { - fn size_hint(&self) -> (usize, Option) { - (self.len(), Some(self.len())) - } -} + fn visit(&self, visit: &mut dyn Visit) { + T::visit_slice(self, visit); + } + } -#[cfg(feature = "std")] -impl Valuable for std::collections::HashSet -where - T: Valuable + Eq + std::hash::Hash, - H: std::hash::BuildHasher, -{ - fn as_value(&self) -> Value<'_> { - Value::Listable(self) - } + $(#[$attrs])* + impl<$($generics)*> Listable for $ty { + fn size_hint(&self) -> (usize, Option) { + (self.len(), Some(self.len())) + } + } + )* + }; +} + +slice! { + (T: Valuable) &'_ [T], + #[cfg(feature = "alloc")] + (T: Valuable) alloc::boxed::Box<[T]>, + #[cfg(feature = "alloc")] + (T: Valuable) alloc::rc::Rc<[T]>, + #[cfg(feature = "alloc")] + (T: Valuable) alloc::sync::Arc<[T]>, + (T: Valuable, const N: usize) [T; N], + #[cfg(feature = "alloc")] + (T: Valuable) alloc::vec::Vec, +} + +macro_rules! collection { + ( + $( + $(#[$attrs:meta])* + ($($generics:tt)*) $ty:ty, + )* + ) => { + $( + $(#[$attrs])* + impl<$($generics)*> Valuable for $ty { + fn as_value(&self) -> Value<'_> { + Value::Listable(self as &dyn Listable) + } - fn visit(&self, visit: &mut dyn Visit) { - for value in self.iter() { - visit.visit_value(value.as_value()); - } - } -} + fn visit(&self, visit: &mut dyn Visit) { + for value in self.iter() { + visit.visit_value(value.as_value()); + } + } + } -#[cfg(feature = "std")] -impl Listable for std::collections::HashSet -where - T: Valuable + Eq + std::hash::Hash, - H: std::hash::BuildHasher, -{ - fn size_hint(&self) -> (usize, Option) { - (self.len(), Some(self.len())) - } + $(#[$attrs])* + impl<$($generics)*> Listable for $ty { + fn size_hint(&self) -> (usize, Option) { + (self.len(), Some(self.len())) + } + } + )* + }; +} + +collection! { + #[cfg(feature = "alloc")] + (T: Valuable) alloc::collections::VecDeque, + #[cfg(feature = "alloc")] + (T: Valuable) alloc::collections::LinkedList, + #[cfg(feature = "alloc")] + (T: Valuable + Ord) alloc::collections::BinaryHeap, + #[cfg(feature = "alloc")] + (T: Valuable + Ord) alloc::collections::BTreeSet , + #[cfg(feature = "std")] + (T: Valuable + Eq + std::hash::Hash, H: std::hash::BuildHasher) std::collections::HashSet, } impl fmt::Debug for dyn Listable + '_ { diff --git a/valuable/src/valuable.rs b/valuable/src/valuable.rs index fb596e1..0f74ba0 100644 --- a/valuable/src/valuable.rs +++ b/valuable/src/valuable.rs @@ -1,4 +1,4 @@ -use crate::{Listable, Slice, Value, Visit}; +use crate::{Slice, Value, Visit}; use core::fmt; @@ -179,48 +179,6 @@ impl Valuable for alloc::string::String { } } -impl Valuable for &'_ [T] { - fn as_value(&self) -> Value<'_> { - Value::Listable(self as &dyn Listable) - } - - fn visit(&self, visit: &mut dyn Visit) { - T::visit_slice(self, visit); - } -} - -#[cfg(feature = "alloc")] -impl Valuable for alloc::boxed::Box<[T]> { - fn as_value(&self) -> Value<'_> { - Value::Listable(self as &dyn Listable) - } - - fn visit(&self, visit: &mut dyn Visit) { - T::visit_slice(self, visit); - } -} - -impl Valuable for [T; N] { - fn as_value(&self) -> Value<'_> { - Value::Listable(self) - } - - fn visit(&self, visit: &mut dyn Visit) { - T::visit_slice(self, visit); - } -} - -#[cfg(feature = "alloc")] -impl Valuable for alloc::vec::Vec { - fn as_value(&self) -> Value<'_> { - Value::Listable(self) - } - - fn visit(&self, visit: &mut dyn Visit) { - T::visit_slice(self, visit); - } -} - #[cfg(feature = "std")] impl Valuable for dyn std::error::Error + '_ { fn as_value(&self) -> Value<'_> {