Skip to main content

alux_shape/
std_shapes.rs

1//! What the standard types describe.
2//!
3//! Each states what `serde` writes for that type and nothing more: an integer is a number of its
4//! width, not a number written some particular way, because how a quantity should appear is a
5//! domain's statement rather than a width's. A domain that writes a `u128` as decimal text says so
6//! in its own shape.
7
8use crate::{ShapeAlg, ShapeOf};
9use std::collections::{BTreeMap, HashMap};
10
11/// States a shape for one integer width.
12macro_rules! int_shapes {
13    ($($ty:ty => ($signed:literal, $bits:literal)),* $(,)?) => {
14        $(
15            impl<A> ShapeOf<A> for $ty
16            where
17                A: ShapeAlg,
18            {
19                type Shape = A::Ty;
20
21                fn shape_of(alg: &A) -> A::Ty {
22                    alg.int($signed, $bits)
23                }
24            }
25        )*
26    };
27}
28
29int_shapes! {
30    u8 => (false, 8), u16 => (false, 16), u32 => (false, 32), u64 => (false, 64), u128 => (false, 128),
31    i8 => (true, 8), i16 => (true, 16), i32 => (true, 32), i64 => (true, 64), i128 => (true, 128),
32    usize => (false, 64), isize => (true, 64),
33}
34
35impl<A> ShapeOf<A> for bool
36where
37    A: ShapeAlg,
38{
39    type Shape = A::Ty;
40
41    fn shape_of(alg: &A) -> A::Ty {
42        alg.truth()
43    }
44}
45
46impl<A> ShapeOf<A> for f32
47where
48    A: ShapeAlg,
49{
50    type Shape = A::Ty;
51
52    fn shape_of(alg: &A) -> A::Ty {
53        alg.float(32)
54    }
55}
56
57impl<A> ShapeOf<A> for f64
58where
59    A: ShapeAlg,
60{
61    type Shape = A::Ty;
62
63    fn shape_of(alg: &A) -> A::Ty {
64        alg.float(64)
65    }
66}
67
68impl<A> ShapeOf<A> for String
69where
70    A: ShapeAlg,
71{
72    type Shape = A::Ty;
73
74    fn shape_of(alg: &A) -> A::Ty {
75        alg.text()
76    }
77}
78
79impl<A> ShapeOf<A> for str
80where
81    A: ShapeAlg,
82{
83    type Shape = A::Ty;
84
85    fn shape_of(alg: &A) -> A::Ty {
86        alg.text()
87    }
88}
89
90impl<A> ShapeOf<A> for ()
91where
92    A: ShapeAlg,
93{
94    type Shape = A::Ty;
95
96    fn shape_of(alg: &A) -> A::Ty {
97        alg.unit()
98    }
99}
100
101impl<A, T> ShapeOf<A> for Option<T>
102where
103    A: ShapeAlg,
104    T: ShapeOf<A, Shape = A::Ty>,
105{
106    type Shape = A::Ty;
107
108    fn shape_of(alg: &A) -> A::Ty {
109        alg.opt(T::shape_of(alg))
110    }
111}
112
113impl<A, T> ShapeOf<A> for Vec<T>
114where
115    A: ShapeAlg,
116    T: ShapeOf<A, Shape = A::Ty>,
117{
118    type Shape = A::Ty;
119
120    fn shape_of(alg: &A) -> A::Ty {
121        alg.seq(T::shape_of(alg))
122    }
123}
124
125impl<A, T> ShapeOf<A> for [T]
126where
127    A: ShapeAlg,
128    T: ShapeOf<A, Shape = A::Ty>,
129{
130    type Shape = A::Ty;
131
132    fn shape_of(alg: &A) -> A::Ty {
133        alg.seq(T::shape_of(alg))
134    }
135}
136
137impl<A, T, const N: usize> ShapeOf<A> for [T; N]
138where
139    A: ShapeAlg,
140    T: ShapeOf<A, Shape = A::Ty>,
141{
142    type Shape = A::Ty;
143
144    fn shape_of(alg: &A) -> A::Ty {
145        alg.seq(T::shape_of(alg))
146    }
147}
148
149impl<A, T> ShapeOf<A> for Box<T>
150where
151    A: ShapeAlg,
152    T: ShapeOf<A, Shape = A::Ty>,
153{
154    type Shape = A::Ty;
155
156    fn shape_of(alg: &A) -> A::Ty {
157        T::shape_of(alg)
158    }
159}
160
161impl<A, K, V> ShapeOf<A> for HashMap<K, V>
162where
163    A: ShapeAlg,
164    K: ShapeOf<A, Shape = A::Ty>,
165    V: ShapeOf<A, Shape = A::Ty>,
166{
167    type Shape = A::Ty;
168
169    fn shape_of(alg: &A) -> A::Ty {
170        alg.map(K::shape_of(alg), V::shape_of(alg))
171    }
172}
173
174impl<A, K, V> ShapeOf<A> for BTreeMap<K, V>
175where
176    A: ShapeAlg,
177    K: ShapeOf<A, Shape = A::Ty>,
178    V: ShapeOf<A, Shape = A::Ty>,
179{
180    type Shape = A::Ty;
181
182    fn shape_of(alg: &A) -> A::Ty {
183        alg.map(K::shape_of(alg), V::shape_of(alg))
184    }
185}