nmd_core/utility/
nmd_unique_identifier.rs

1use std::collections::HashMap;
2use ahash::RandomState;
3use crate::dossier::document::Document;
4use super::file_utility;
5
6
7/// `NmdUniqueIdentifier` is a unique identifier in a NMD compilation.
8pub type NmdUniqueIdentifier = String;
9
10const HASHER_SEED: usize = 42;
11
12pub fn assign_nuid_to_document_paragraphs(document: &mut Document) {
13
14    let hasher = RandomState::with_seed(HASHER_SEED);
15    let mut nuid_map: HashMap<u64, usize> = HashMap::new();
16
17    let prefix = file_utility::build_output_file_name(document.name(), None);
18
19    let mut calc_nuid = |s: &String| {
20
21        let h = hasher.hash_one(s);
22
23        let mut n = *nuid_map.get(&h).unwrap_or(&0);
24
25        n += 1;
26
27        nuid_map.insert(h, n);
28
29        let nuid = format!("{}-{}-{}", prefix, h, n);
30
31        nuid
32    };
33    
34    document.content_mut().preamble_mut().iter_mut().for_each(|p| {
35        p.set_nuid(Some(calc_nuid(p.raw_content())));
36    });
37
38    document.content_mut().chapters_mut().iter_mut().for_each(|chapter| {
39        chapter.paragraphs_mut().iter_mut().for_each(|p| {
40            p.set_nuid(Some(calc_nuid(p.raw_content())));
41        });
42
43        let title = chapter.header().heading().title().clone();
44        chapter.header_mut().heading_mut().set_nuid(Some(calc_nuid(&title)));
45    });
46}
47
48
49#[cfg(test)]
50mod test {
51    use ahash::RandomState;
52
53    use super::HASHER_SEED;
54
55    #[test]
56    fn deterministic_hashing() {
57
58        let test_string = "this is a test string";
59
60        let hasher = RandomState::with_seed(HASHER_SEED);
61        let h1 = hasher.hash_one(test_string);
62
63        let hasher = RandomState::with_seed(HASHER_SEED);
64        let h2 = hasher.hash_one(test_string);
65
66        assert_eq!(h1, h2);
67    }
68}