tl_build/generator/
grouper.rs

1//! Several functions to group definitions by a certain criteria.
2
3use crate::tl::{Category, Definition, Type};
4use std::collections::HashMap;
5
6/// Group the input vector by namespace, filtering by a certain category.
7pub(crate) fn group_by_ns(
8    definitions: &[Definition],
9    category: Category,
10) -> HashMap<String, Vec<&Definition>> {
11    let mut result = HashMap::new();
12    definitions
13        .iter()
14        .filter(|d| d.category == category)
15        .for_each(|d| {
16            // We currently only handle zero or one namespace.
17            assert!(d.namespace.len() <= 1);
18            let ns = d.namespace.get(0).map(|x| &x[..]).unwrap_or("");
19            result.entry(ns.into()).or_insert_with(Vec::new).push(d);
20        });
21
22    for (_, vec) in result.iter_mut() {
23        vec.sort_by_key(|d| &d.name);
24    }
25    result
26}
27
28/// Similar to `group_by_ns`, but for the definition types.
29pub(crate) fn group_types_by_ns(definitions: &[Definition]) -> HashMap<Option<String>, Vec<&Type>> {
30    let mut result = HashMap::new();
31    definitions
32        .iter()
33        .filter(|d| d.category == Category::Types && !d.ty.generic_ref)
34        .for_each(|d| {
35            // We currently only handle zero or one namespace.
36            assert!(d.namespace.len() <= 1);
37            result
38                .entry(d.namespace.get(0).map(Clone::clone))
39                .or_insert_with(Vec::new)
40                .push(&d.ty);
41        });
42
43    for (_, vec) in result.iter_mut() {
44        vec.sort_by_key(|t| &t.name);
45        vec.dedup();
46    }
47    result
48}