structdoc/
impls.rs

1use std::borrow::Cow;
2use std::cell::{Cell, RefCell};
3use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
4use std::ffi::{CStr, CString, OsStr, OsString};
5use std::marker::PhantomData;
6use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
7use std::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, Wrapping};
8use std::path::{Path, PathBuf};
9use std::rc::Rc;
10use std::sync::{Arc, Mutex, RwLock};
11use std::time::{Duration, Instant, SystemTime};
12
13use crate::{Arity, Documentation, Flags, StructDoc};
14
15// TODO: Impls for other crates, if feature flags are turned on?
16
17macro_rules! arity {
18    ($container: ident, $arity: ident) => {
19        impl<T: StructDoc> StructDoc for $container<T> {
20            fn document() -> Documentation {
21                T::document().with_arity(Arity::$arity)
22            }
23        }
24    };
25}
26
27arity!(Vec, ManyOrdered);
28arity!(LinkedList, ManyOrdered);
29arity!(VecDeque, ManyOrdered);
30arity!(BinaryHeap, ManyUnordered);
31arity!(BTreeSet, ManyUnordered);
32
33macro_rules! array {
34    ($($len: expr,)*) => {
35        $(
36            impl<T: StructDoc> StructDoc for [T; $len] {
37                fn document() -> Documentation {
38                    T::document().with_arity(Arity::ManyOrdered)
39                }
40            }
41        )*
42    }
43}
44
45array! {
46    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
47    17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
48}
49
50impl<T: StructDoc, S> StructDoc for HashSet<T, S> {
51    fn document() -> Documentation {
52        T::document().with_arity(Arity::ManyUnordered)
53    }
54}
55
56impl<T: StructDoc> StructDoc for [T] {
57    fn document() -> Documentation {
58        T::document().with_arity(Arity::ManyOrdered)
59    }
60}
61
62impl<T: StructDoc> StructDoc for Option<T> {
63    fn document() -> Documentation {
64        // A hack ‒ force a new level/wrapper.
65        let mut doc = T::document().with_arity(Arity::One);
66        doc.set_flag(Flags::OPTIONAL);
67        doc
68    }
69}
70
71impl<K: StructDoc, V: StructDoc, S> StructDoc for HashMap<K, V, S> {
72    fn document() -> Documentation {
73        Documentation::map(K::document(), V::document())
74    }
75}
76
77impl<K: StructDoc, V: StructDoc> StructDoc for BTreeMap<K, V> {
78    fn document() -> Documentation {
79        Documentation::map(K::document(), V::document())
80    }
81}
82
83macro_rules! transparent {
84    ($($ty: ident,)*) => {
85        $(
86            impl<T: StructDoc> StructDoc for $ty<T> {
87                fn document() -> Documentation {
88                    T::document()
89                }
90            }
91        )*
92    }
93}
94
95transparent! {
96    Arc,
97    Box,
98    Cell,
99    Mutex,
100    // Hmm, is transparent the right thing to do here?
101    PhantomData,
102    Rc,
103    RefCell,
104    RwLock,
105    Wrapping,
106}
107
108impl<T: StructDoc> StructDoc for &T {
109    fn document() -> Documentation {
110        T::document()
111    }
112}
113
114impl<T: StructDoc> StructDoc for &mut T {
115    fn document() -> Documentation {
116        T::document()
117    }
118}
119
120impl<T: Clone + StructDoc> StructDoc for Cow<'_, T> {
121    fn document() -> Documentation {
122        T::document()
123    }
124}
125
126macro_rules! leaf {
127    ($($desc: expr => $($ty: ty),*;)*) => {
128        $(
129        $(
130            impl StructDoc for $ty {
131                fn document() -> Documentation {
132                    Documentation::leaf($desc)
133                }
134            }
135        )*
136        )*
137    }
138}
139
140leaf! {
141    "Integer" =>
142        u8, u16, u32, u64, u128, usize,
143        NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128,
144        i8, i16, i32, i64, i128, isize;
145    "Character" => char;
146    "String" => str, String, CString, CStr, OsStr, OsString;
147    "Boolean" => bool;
148    "Nil" => ();
149    "Float" => f32, f64;
150    "IPv4 address" => Ipv4Addr;
151    "IPv6 address" => Ipv6Addr;
152    "IP address" => IpAddr;
153    "Socket address (IPv4)" => SocketAddrV4;
154    "Socket address (IPv6)" => SocketAddrV6;
155    "Socket address" => SocketAddr;
156    "Filesystem path" => Path, PathBuf;
157    "Time duration" => Duration;
158    "Timestamp" => SystemTime, Instant;
159}