File: docs.rs

package info (click to toggle)
firefox 149.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,767,760 kB
  • sloc: cpp: 7,416,064; javascript: 6,752,859; ansic: 3,774,850; python: 1,250,473; xml: 641,578; asm: 439,191; java: 186,617; sh: 56,634; makefile: 18,856; objc: 13,092; perl: 12,763; pascal: 5,960; yacc: 4,583; cs: 3,846; lex: 1,720; ruby: 1,002; php: 436; lisp: 258; awk: 105; sql: 66; sed: 53; csh: 10; exp: 6
file content (111 lines) | stat: -rw-r--r-- 3,590 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::collections::HashMap;
use std::fs;
use std::fs::File;
use std::io::Write;

use pulldown_cmark::Event::{End, Start, Text};
use pulldown_cmark::Tag::List;
use pulldown_cmark::TagEnd;
use pulldown_cmark_to_cmark::cmark;
use xshell::{cmd, Shell};

#[test]
fn reference_metrics_toc_is_sorted() {
    // Relative to `glean-core`
    let index_file = "../docs/user/reference/metrics/index.md";
    let src = fs::read_to_string(index_file).expect("unable to read file");
    let parser = pulldown_cmark::Parser::new(&src);
    let mut events = parser.into_offset_iter();

    let mut modified_events = Vec::new();

    let mut output = File::create(index_file).unwrap();

    // Everything before the list
    let mut list_start = 0;
    for (event, span) in events.by_ref() {
        if let Start(List(..)) = event {
            modified_events.push(event);
            list_start = span.start;
            break;
        }
    }

    // Output everything up to the list start unmodified.
    if list_start > 0 {
        writeln!(&mut output, "{}", &src[0..(list_start - 1)]).unwrap();
    }

    let mut items = HashMap::new();

    // The list itself.
    // We store a `title -> events` mapping to sort it later by `title`.
    let mut list_end = 0;
    while let Some((event, span)) = events.next() {
        if let End(TagEnd::List(..)) = event {
            list_end = span.end;
            break;
        }

        let mut elems = Vec::new();
        elems.push(event);

        let mut title: Option<String> = None;
        for (event, _) in events.by_ref() {
            match event {
                End(TagEnd::Item) => {
                    elems.push(End(TagEnd::Item));
                    break;
                }
                Text(s) if title.is_none() => {
                    title = Some(s.to_string());
                    elems.push(Text(s));
                }
                e => elems.push(e),
            }
        }
        items.insert(title.unwrap(), elems);
    }

    let mut item_keys: Vec<_> = items.keys().cloned().collect();
    item_keys.sort_by_key(|item| {
        // We need to handle a few special cases:
        //
        // * Dual-labeled and labeled metrics should be sorted right after their top-level metric type
        // * Normalizing plurals to be sorted correctly after the singular (quantity -> quantities)

        let mut k = item.to_ascii_lowercase();
        k = k.strip_prefix("dual-labeled ").unwrap_or(&k).to_string();
        k = k.strip_prefix("labeled ").unwrap_or(&k).to_string();

        match &*k {
            _ if item == "Dual-labeled counters" => String::from("counter3"),
            "counters" => String::from("counter2"),
            "quantities" => String::from("quantity2"),
            "strings" => String::from("string2"),
            "string list" => String::from("string3"),
            _ => k,
        }
    });

    for key in item_keys {
        let elems = items.remove(&key).unwrap();
        modified_events.extend(elems);
    }
    modified_events.push(End(TagEnd::List(false)));

    let mut output_markdown = String::new();
    cmark(modified_events.into_iter(), &mut output_markdown).unwrap();
    writeln!(&mut output, "{output_markdown}\n").unwrap();

    // The remaining document can be printed unmodified.
    if list_end > 0 {
        write!(&mut output, "{}", &src[list_end..]).unwrap();
    }

    // Last but not least check if we modified the document.
    let sh = Shell::new().unwrap();
    cmd!(sh, "git --no-pager diff --exit-code {index_file}")
        .run()
        .unwrap();
}