Skip to content

Commit 7a38168

Browse files
authored
impl valuable traits for more types, fix build error on no_std + alloc (#6)
1 parent 38da307 commit 7a38168

File tree

8 files changed

+194
-8
lines changed

8 files changed

+194
-8
lines changed

valuable/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ default = ["std"]
1313
derive = ["valuable-derive"]
1414

1515
# Provide impls for common standard library types like Vec<T> and HashMap<K, V>.
16-
std = []
16+
std = ["alloc"]
1717

1818
# Provide imps for types in Rust's `alloc` library.
1919
alloc = []
@@ -26,4 +26,4 @@ criterion = "0.3"
2626

2727
[[bench]]
2828
name = "structable"
29-
harness = false
29+
harness = false

valuable/src/enumerable.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::field::*;
22
use crate::*;
33

4+
#[cfg(feature = "alloc")]
5+
use alloc::format;
46
use core::fmt;
57

68
pub trait Enumerable: Valuable {
@@ -141,3 +143,30 @@ impl fmt::Debug for dyn Enumerable + '_ {
141143
visit.res
142144
}
143145
}
146+
147+
impl<E: ?Sized + Enumerable> Enumerable for &E {
148+
fn definition(&self) -> EnumDef<'_> {
149+
E::definition(*self)
150+
}
151+
}
152+
153+
#[cfg(feature = "alloc")]
154+
impl<E: ?Sized + Enumerable> Enumerable for alloc::boxed::Box<E> {
155+
fn definition(&self) -> EnumDef<'_> {
156+
E::definition(&**self)
157+
}
158+
}
159+
160+
#[cfg(feature = "alloc")]
161+
impl<E: ?Sized + Enumerable> Enumerable for alloc::rc::Rc<E> {
162+
fn definition(&self) -> EnumDef<'_> {
163+
E::definition(&**self)
164+
}
165+
}
166+
167+
#[cfg(feature = "alloc")]
168+
impl<E: ?Sized + Enumerable> Enumerable for alloc::sync::Arc<E> {
169+
fn definition(&self) -> EnumDef<'_> {
170+
E::definition(&**self)
171+
}
172+
}

valuable/src/listable.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,22 @@ impl<L: ?Sized + Listable> Listable for &L {
1212
}
1313
}
1414

15-
impl<L: ?Sized + Listable> Listable for Box<L> {
15+
#[cfg(feature = "alloc")]
16+
impl<L: ?Sized + Listable> Listable for alloc::boxed::Box<L> {
17+
fn size_hint(&self) -> (usize, Option<usize>) {
18+
L::size_hint(&**self)
19+
}
20+
}
21+
22+
#[cfg(feature = "alloc")]
23+
impl<L: ?Sized + Listable> Listable for alloc::rc::Rc<L> {
24+
fn size_hint(&self) -> (usize, Option<usize>) {
25+
L::size_hint(&**self)
26+
}
27+
}
28+
29+
#[cfg(feature = "alloc")]
30+
impl<L: ?Sized + Listable> Listable for alloc::sync::Arc<L> {
1631
fn size_hint(&self) -> (usize, Option<usize>) {
1732
L::size_hint(&**self)
1833
}
@@ -24,7 +39,21 @@ impl<T: Valuable> Listable for &'_ [T] {
2439
}
2540
}
2641

27-
impl<T: Valuable> Listable for Vec<T> {
42+
#[cfg(feature = "alloc")]
43+
impl<T: Valuable> Listable for alloc::boxed::Box<[T]> {
44+
fn size_hint(&self) -> (usize, Option<usize>) {
45+
(self.len(), Some(self.len()))
46+
}
47+
}
48+
49+
impl<T: Valuable, const N: usize> Listable for [T; N] {
50+
fn size_hint(&self) -> (usize, Option<usize>) {
51+
(self.len(), Some(self.len()))
52+
}
53+
}
54+
55+
#[cfg(feature = "alloc")]
56+
impl<T: Valuable> Listable for alloc::vec::Vec<T> {
2857
fn size_hint(&self) -> (usize, Option<usize>) {
2958
(self.len(), Some(self.len()))
3059
}

valuable/src/mappable.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,33 @@ pub trait Mappable: Valuable {
66
fn size_hint(&self) -> (usize, Option<usize>);
77
}
88

9+
impl<M: ?Sized + Mappable> Mappable for &M {
10+
fn size_hint(&self) -> (usize, Option<usize>) {
11+
M::size_hint(*self)
12+
}
13+
}
14+
15+
#[cfg(feature = "alloc")]
16+
impl<M: ?Sized + Mappable> Mappable for alloc::boxed::Box<M> {
17+
fn size_hint(&self) -> (usize, Option<usize>) {
18+
M::size_hint(&**self)
19+
}
20+
}
21+
22+
#[cfg(feature = "alloc")]
23+
impl<M: ?Sized + Mappable> Mappable for alloc::rc::Rc<M> {
24+
fn size_hint(&self) -> (usize, Option<usize>) {
25+
M::size_hint(&**self)
26+
}
27+
}
28+
29+
#[cfg(feature = "alloc")]
30+
impl<M: ?Sized + Mappable> Mappable for alloc::sync::Arc<M> {
31+
fn size_hint(&self) -> (usize, Option<usize>) {
32+
M::size_hint(&**self)
33+
}
34+
}
35+
936
#[cfg(feature = "std")]
1037
impl<K: Valuable, V: Valuable> Valuable for std::collections::HashMap<K, V> {
1138
fn as_value(&self) -> Value<'_> {
@@ -26,6 +53,26 @@ impl<K: Valuable, V: Valuable> Mappable for std::collections::HashMap<K, V> {
2653
}
2754
}
2855

56+
#[cfg(feature = "alloc")]
57+
impl<K: Valuable, V: Valuable> Valuable for alloc::collections::BTreeMap<K, V> {
58+
fn as_value(&self) -> Value<'_> {
59+
Value::Mappable(self)
60+
}
61+
62+
fn visit(&self, visit: &mut dyn Visit) {
63+
for (key, value) in self.iter() {
64+
visit.visit_entry(key.as_value(), value.as_value());
65+
}
66+
}
67+
}
68+
69+
#[cfg(feature = "alloc")]
70+
impl<K: Valuable, V: Valuable> Mappable for alloc::collections::BTreeMap<K, V> {
71+
fn size_hint(&self) -> (usize, Option<usize>) {
72+
self.iter().size_hint()
73+
}
74+
}
75+
2976
impl fmt::Debug for dyn Mappable + '_ {
3077
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
3178
struct DebugMappable<'a, 'b> {

valuable/src/slice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ slice! {
115115
I128(i128),
116116
Isize(isize),
117117
Str(&'a str),
118-
String(String),
118+
String(alloc::string::String),
119119
U8(u8),
120120
U16(u16),
121121
U32(u32),

valuable/src/structable.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use core::fmt;
66
pub trait Structable: Valuable {
77
fn definition(&self) -> StructDef<'_>;
88
}
9+
910
pub struct StructDef<'a> {
1011
/// Type name
1112
name: &'a str,
@@ -80,3 +81,30 @@ impl<'a> StructDef<'a> {
8081
self.is_dynamic
8182
}
8283
}
84+
85+
impl<S: ?Sized + Structable> Structable for &S {
86+
fn definition(&self) -> StructDef<'_> {
87+
S::definition(*self)
88+
}
89+
}
90+
91+
#[cfg(feature = "alloc")]
92+
impl<S: ?Sized + Structable> Structable for alloc::boxed::Box<S> {
93+
fn definition(&self) -> StructDef<'_> {
94+
S::definition(&**self)
95+
}
96+
}
97+
98+
#[cfg(feature = "alloc")]
99+
impl<S: ?Sized + Structable> Structable for alloc::rc::Rc<S> {
100+
fn definition(&self) -> StructDef<'_> {
101+
S::definition(&**self)
102+
}
103+
}
104+
105+
#[cfg(feature = "alloc")]
106+
impl<S: ?Sized + Structable> Structable for alloc::sync::Arc<S> {
107+
fn definition(&self) -> StructDef<'_> {
108+
S::definition(&**self)
109+
}
110+
}

valuable/src/valuable.rs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,30 @@ impl<V: ?Sized + Valuable> Valuable for &V {
4747
}
4848
}
4949

50-
impl<V: ?Sized + Valuable> Valuable for Box<V> {
50+
#[cfg(feature = "alloc")]
51+
impl<V: ?Sized + Valuable> Valuable for alloc::boxed::Box<V> {
52+
fn as_value(&self) -> Value<'_> {
53+
(&**self).as_value()
54+
}
55+
56+
fn visit(&self, visit: &mut dyn Visit) {
57+
V::visit(&**self, visit);
58+
}
59+
}
60+
61+
#[cfg(feature = "alloc")]
62+
impl<V: ?Sized + Valuable> Valuable for alloc::rc::Rc<V> {
63+
fn as_value(&self) -> Value<'_> {
64+
(&**self).as_value()
65+
}
66+
67+
fn visit(&self, visit: &mut dyn Visit) {
68+
V::visit(&**self, visit);
69+
}
70+
}
71+
72+
#[cfg(feature = "alloc")]
73+
impl<V: ?Sized + Valuable> Valuable for alloc::sync::Arc<V> {
5174
fn as_value(&self) -> Value<'_> {
5275
(&**self).as_value()
5376
}
@@ -138,7 +161,8 @@ impl Valuable for &'_ str {
138161
}
139162
}
140163

141-
impl Valuable for String {
164+
#[cfg(feature = "alloc")]
165+
impl Valuable for alloc::string::String {
142166
fn as_value(&self) -> Value<'_> {
143167
Value::String(&self[..])
144168
}
@@ -165,7 +189,29 @@ impl<T: Valuable> Valuable for &'_ [T] {
165189
}
166190
}
167191

168-
impl<T: Valuable> Valuable for Vec<T> {
192+
#[cfg(feature = "alloc")]
193+
impl<T: Valuable> Valuable for alloc::boxed::Box<[T]> {
194+
fn as_value(&self) -> Value<'_> {
195+
Value::Listable(self as &dyn Listable)
196+
}
197+
198+
fn visit(&self, visit: &mut dyn Visit) {
199+
T::visit_slice(self, visit);
200+
}
201+
}
202+
203+
impl<T: Valuable, const N: usize> Valuable for [T; N] {
204+
fn as_value(&self) -> Value<'_> {
205+
Value::Listable(self)
206+
}
207+
208+
fn visit(&self, visit: &mut dyn Visit) {
209+
T::visit_slice(self, visit);
210+
}
211+
}
212+
213+
#[cfg(feature = "alloc")]
214+
impl<T: Valuable> Valuable for alloc::vec::Vec<T> {
169215
fn as_value(&self) -> Value<'_> {
170216
Value::Listable(self)
171217
}
@@ -175,6 +221,7 @@ impl<T: Valuable> Valuable for Vec<T> {
175221
}
176222
}
177223

224+
#[cfg(feature = "std")]
178225
impl Valuable for dyn std::error::Error + '_ {
179226
fn as_value(&self) -> Value<'_> {
180227
Value::Error(self)

valuable/src/value.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,22 @@ use core::fmt;
55
macro_rules! value {
66
(
77
$(
8+
$(#[$attrs:meta])*
89
$variant:ident($ty:ty),
910
)*
1011
) => {
1112
#[non_exhaustive]
1213
#[derive(Clone, Copy)]
1314
pub enum Value<'a> {
1415
$(
16+
$(#[$attrs])*
1517
$variant($ty),
1618
)*
1719
Unit, // TODO: None?
1820
}
1921

2022
$(
23+
$(#[$attrs])*
2124
impl<'a> From<$ty> for Value<'a> {
2225
fn from(src: $ty) -> Value<'a> {
2326
Value::$variant(src)
@@ -37,6 +40,7 @@ macro_rules! value {
3740

3841
match self {
3942
$(
43+
$(#[$attrs])*
4044
$variant(v) => fmt::Debug::fmt(v, fmt),
4145
)*
4246
Unit => ().fmt(fmt),
@@ -64,6 +68,7 @@ value! {
6468
U64(u64),
6569
U128(u128),
6670
Usize(usize),
71+
#[cfg(feature = "std")]
6772
Error(&'a dyn std::error::Error),
6873
Listable(&'a dyn Listable),
6974
Mappable(&'a dyn Mappable),
@@ -159,6 +164,7 @@ macro_rules! convert {
159164
}
160165
}
161166

167+
#[cfg(feature = "std")]
162168
pub fn as_error(&self) -> Option<&dyn std::error::Error> {
163169
match *self {
164170
Value::Error(v) => Some(v),

0 commit comments

Comments
 (0)