code_docs/
documented_consts.rs1#[derive(Clone, Copy)]
2pub struct DocumentedConstants {
3 names: &'static [&'static str],
4 types: &'static [&'static str],
5 values: &'static [&'static str],
6 docs: &'static [&'static [&'static str]],
7}
8
9impl DocumentedConstants {
10 pub fn constant_names(&self) -> &[&'static str] {
12 self.names
13 }
14
15 pub fn constant_types(&self) -> &[&'static str] {
17 self.types
18 }
19
20 pub fn constant_values(&self) -> &[&'static str] {
22 self.values
23 }
24
25 pub fn constant_docs_raw(&self) -> &[&[&'static str]] {
26 self.docs
27 }
28
29 pub fn constant_docs(&self) -> Vec<Vec<&'static str>> {
31 self.constant_docs_raw()
32 .iter().map(|x| {
33 x.into_iter()
34 .filter_map(|x| super::filter_docs(*x))
35 .collect::<Vec<_>>()
36 })
37 .collect::<Vec<_>>()
38 }
39
40 pub fn commented_constants(&self) -> String {
42 use std::fmt::Write;
43
44 let mut output = String::new();
47 assert_eq!(self.names.len(), self.types.len(), "Constant names and types length are not equal");
49 assert_eq!(self.names.len(), self.values.len(), "Constant names and values length are not equal");
50 assert_eq!(self.names.len(), self.docs.len(), "Constant names and docs length are not equal");
51
52 for (i, field) in self.names.iter().enumerate() {
54 if i != 0 {
56 write!(output, "\n").unwrap();
57 }
58
59 for comment in self.docs.get(i).unwrap().iter() {
61 if let Some(comment) = super::filter_docs(comment) {
62 write!(output, "///{}\n", comment).unwrap();
63 }
64 }
65
66 write!(output, "{}: {}\n", field, self.types.get(i).unwrap()).unwrap();
67 }
68
69 output
70 }
71}
72
73#[macro_export]
75macro_rules! code_docs_constants {
76 (
77 $t_vis:vis $t_name:ident;
78
79 $(
80 $(#[$meta:meta])*
81 $vis:vis const $name:ident : $t:ty = $expr:expr ;
82 )*
83 ) => {
84 $t_vis const $t_name: $crate::DocumentedConstants = $crate::DocumentedConstants {
85 names: &[
86 $(
87 stringify!($name),
88 )*
89 ],
90 types: &[
91 $(
92 stringify!($t),
93 )*
94 ],
95 values: &[
96 $(
97 stringify!($expr),
98 )*
99 ],
100 docs: &[
101 $(
102 &[
103 $(stringify!($meta),)*
104 ],
105 )*
106 ],
107 };
108
109 $(
110 $(#[$meta])*
111 $vis const $name : $t = $expr ;
112 )*
113 }
114}
115
116#[cfg(test)]
117#[allow(unused)]
118mod tests {
119 code_docs_constants! {
120 pub DOCS;
121
122 const ENV_FEATURE1: &str = "something";
123
124 #[allow(unused)]
128 const ENV_FEATURE2: usize = 666;
129 }
130
131 #[test]
132 fn test_constants() {
133 assert_eq!(DOCS.constant_names(), &["ENV_FEATURE1", "ENV_FEATURE2"]);
134 assert_eq!(DOCS.constant_types(), &["&str", "usize"]);
135 assert_eq!(DOCS.constant_values(), &["\"something\"", "666"]);
136
137 assert_eq!(DOCS.constant_docs_raw(), vec![
138 vec![],
139 vec![
140 "doc = r\" Does the thing with feature2\"",
141 "doc = r\"\"",
142 "doc = r\" Yes very important\"",
143 "allow(unused)"
144 ],
145 ]);
146
147 assert_eq!(DOCS.constant_docs(), vec![
148 vec![],
149 vec![
150 " Does the thing with feature2",
151 "",
152 " Yes very important",
153 ]]);
154 }
155}
156