nmd_core/utility/
nmd_unique_identifier.rs

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
use std::collections::HashMap;
use ahash::RandomState;
use crate::dossier::document::Document;
use super::file_utility;


/// `NmdUniqueIdentifier` is a unique identifier in a NMD compilation.
pub type NmdUniqueIdentifier = String;

const HASHER_SEED: usize = 42;

pub fn assign_nuid_to_document_paragraphs(document: &mut Document) {

    let hasher = RandomState::with_seed(HASHER_SEED);
    let mut nuid_map: HashMap<u64, usize> = HashMap::new();

    let prefix = file_utility::build_output_file_name(document.name(), None);

    let mut calc_nuid = |s: &String| {

        let h = hasher.hash_one(s);

        let mut n = *nuid_map.get(&h).unwrap_or(&0);

        n += 1;

        nuid_map.insert(h, n);

        let nuid = format!("{}-{}-{}", prefix, h, n);

        nuid
    };
    
    document.content_mut().preamble_mut().iter_mut().for_each(|p| {
        p.set_nuid(Some(calc_nuid(p.raw_content())));
    });

    document.content_mut().chapters_mut().iter_mut().for_each(|chapter| {
        chapter.paragraphs_mut().iter_mut().for_each(|p| {
            p.set_nuid(Some(calc_nuid(p.raw_content())));
        });

        let title = chapter.header().heading().title().clone();
        chapter.header_mut().heading_mut().set_nuid(Some(calc_nuid(&title)));
    });
}


#[cfg(test)]
mod test {
    use ahash::RandomState;

    use super::HASHER_SEED;

    #[test]
    fn deterministic_hashing() {

        let test_string = "this is a test string";

        let hasher = RandomState::with_seed(HASHER_SEED);
        let h1 = hasher.hash_one(test_string);

        let hasher = RandomState::with_seed(HASHER_SEED);
        let h2 = hasher.hash_one(test_string);

        assert_eq!(h1, h2);
    }
}