term_rustdoc/tree/stats/
mod.rs

1use super::DModule;
2
3mod impls;
4use impls::acc_sum;
5
6#[derive(Default, Clone)]
7pub struct ItemCount {
8    pub modules: u32,
9    pub structs: u32,
10    pub unions: u32,
11    pub enums: u32,
12    pub functions: u32,
13    pub traits: u32,
14    pub constants: u32,
15    pub statics: u32,
16    pub type_alias: u32,
17    pub macros_decl: u32,
18    pub macros_func: u32,
19    pub macros_attr: u32,
20    pub macros_derv: u32,
21}
22
23impl DModule {
24    /// Count the items under current module excluding the current module itself.
25    #[rustfmt::skip]
26    pub fn current_items_counts(&self) -> ItemCount {
27        macro_rules! len {
28            ($self:ident . $( $field:ident )+ ) => { $(
29                let $field = $self.$field.len().try_into()
30                    .expect("the count exceeds the maximum of u32");
31            )+ };
32        }
33        len!(self . modules structs unions enums functions traits constants statics type_alias macros_decl macros_func macros_attr macros_derv);
34        ItemCount {
35            modules, structs, unions, enums, functions, traits, constants, statics,
36            type_alias, macros_decl, macros_func, macros_attr, macros_derv,
37        }
38    }
39
40    /// Count all the items excluding the root itself.
41    pub fn recursive_items_counts(&self) -> ItemCount {
42        self.modules
43            .iter()
44            .map(Self::current_items_counts)
45            .fold(self.current_items_counts(), acc_sum)
46    }
47}
48
49/// This type implements `Add` and `AddAssign`, and it means
50/// when both operands are the same, the output is the same,
51/// if not, the output is `ImplKind::Both`.
52///
53/// This leads to before you add [`ImplCount`]s, if you care about
54/// the same impl kind, you should check it by yourself.
55#[derive(Clone, Copy, Debug)]
56pub enum ImplKind {
57    Inherent,
58    Trait,
59    Both,
60}
61
62#[derive(Clone, Copy)]
63pub struct ImplCount {
64    pub structs: u32,
65    pub enums: u32,
66    pub unions: u32,
67    pub kind: ImplKind,
68    pub total: u32,
69}
70
71/// Count the impl **blocks**.
72#[derive(Clone)]
73pub struct ImplCounts {
74    pub inherent: ImplCount,
75    pub trait_: ImplCount,
76    pub total: ImplCount,
77}
78
79impl ImplCounts {
80    pub const EMPTY: Self = ImplCounts {
81        inherent: ImplCount {
82            structs: 0,
83            enums: 0,
84            unions: 0,
85            kind: ImplKind::Inherent,
86            total: 0,
87        },
88        trait_: ImplCount {
89            structs: 0,
90            enums: 0,
91            unions: 0,
92            kind: ImplKind::Trait,
93            total: 0,
94        },
95        total: ImplCount {
96            structs: 0,
97            enums: 0,
98            unions: 0,
99            kind: ImplKind::Both,
100            total: 0,
101        },
102    };
103}
104
105impl DModule {
106    pub fn current_impls_counts(&self) -> ImplCounts {
107        let (s_in, s_tr) = {
108            let iter = self.structs.iter();
109            (
110                iter.clone().map(|s| s.impls.inherent.len()).sum::<usize>(),
111                iter.map(|s| s.impls.trait_.len()).sum::<usize>(),
112            )
113        };
114        let (e_in, e_tr) = {
115            let iter = self.enums.iter();
116            (
117                iter.clone().map(|s| s.impls.inherent.len()).sum::<usize>(),
118                iter.map(|s| s.impls.trait_.len()).sum::<usize>(),
119            )
120        };
121        let (u_in, u_tr) = {
122            let iter = self.unions.iter();
123            (
124                iter.clone().map(|s| s.impls.inherent.len()).sum::<usize>(),
125                iter.map(|s| s.impls.trait_.len()).sum::<usize>(),
126            )
127        };
128        let inherent = ImplCount {
129            structs: s_in as _,
130            enums: e_in as _,
131            unions: u_in as _,
132            kind: ImplKind::Inherent,
133            total: (s_in + e_in + u_in) as _,
134        };
135        let trait_ = ImplCount {
136            structs: s_tr as _,
137            enums: e_tr as _,
138            unions: u_tr as _,
139            kind: ImplKind::Trait,
140            total: (s_tr + e_tr + u_tr) as _,
141        };
142        ImplCounts {
143            total: inherent + trait_,
144            inherent,
145            trait_,
146        }
147    }
148
149    pub fn recursive_impls_counts(&self) -> ImplCounts {
150        self.modules
151            .iter()
152            .map(Self::current_impls_counts)
153            .fold(self.current_impls_counts(), acc_sum)
154    }
155}
156
157/* FIXME: to elaborate metrics on Impls
158
159/// Count impl blocks.
160#[derive(Clone, Debug)]
161pub struct ImplBlockCounts(pub ImplCounts);
162
163/// Count functions (including methods) in impl blocks w.r.t
164/// * the amount of items
165/// * the amount of arguments
166/// * the amount of generics (lifetime/type/constant)
167/// * the amount of trait bounds (lifetime/type/constant)
168/// * the occurence of identical fn name (using the Vec<Name> instead of digits)
169#[derive(Clone, Debug)]
170pub struct ImplFunctionCounts {
171    pub items: ImplCounts,
172}
173
174/// Count methods (the receiver is ) in impl blocks w.r.t
175/// * all the metrics on ImplFunctionCounts
176/// * and the amount of receiver types separately
177///   * Self/&Self/&mut Self/Box<Self>/Rc<Self>/Arc<Self>/Pin<P>
178///     see <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
179#[derive(Clone, Debug)]
180pub struct ImplMethodCounts(pub ImplCounts);
181*/