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
15macro_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 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 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}