aboutsummaryrefslogtreecommitdiffstats
path: root/src/document/mod.rs
blob: 161214568b4a2ce0cf2da7c8de230b0cb1eb2b38 (plain)
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
//! The replicated document: the replica with its epoch, and the store semantics
//! (merged-view paths over JSON) the HTTP API and remakes work with.

/// The engine's types, under the names the rest of the crate uses: the document
/// (Automerge's `AutoCommit`), its changes and their hashes, and its writers (actors).
/// Only `document` and `remake` use Automerge itself (`architecture.md`, The document).
pub(crate) use automerge::{ActorId, AutoCommit as Document, Change, ChangeHash};

pub(crate) mod changes;
pub(crate) mod file;
pub(crate) mod lock;
pub(crate) mod meta;
pub(crate) mod replica;
pub(crate) mod store;

#[cfg(test)]
mod tests {
    use std::path::{Path, PathBuf};

    /// Every `.rs` file under `dir`.
    fn sources(dir: &Path, out: &mut Vec<PathBuf>) {
        for entry in std::fs::read_dir(dir).unwrap() {
            let path = entry.unwrap().path();
            if path.is_dir() {
                sources(&path, out);
            } else if path.extension().is_some_and(|extension| extension == "rs") {
                out.push(path);
            }
        }
    }

    /// Automerge is used only in `document`, `remake` and the sync session
    /// (`state/session.rs`); the rest of the node names its types as `document`
    /// re-exports them and works through `document` (`architecture.md`, The document).
    #[test]
    fn automerge_stays_behind_document() {
        let src = Path::new(env!("CARGO_MANIFEST_DIR")).join("src");
        let allowed = [
            src.join("document"),
            src.join("remake"),
            src.join("state").join("session.rs"),
        ];
        let mut files = Vec::new();
        sources(&src, &mut files);
        let mut found = Vec::new();
        for file in files
            .iter()
            .filter(|file| !allowed.iter().any(|allowed| file.starts_with(allowed)))
        {
            let text = std::fs::read_to_string(file).unwrap();
            for (number, line) in text.lines().enumerate() {
                if line.contains("automerge::") || line.trim_start().starts_with("use automerge") {
                    found.push(format!(
                        "{}:{}: {}",
                        file.display(),
                        number + 1,
                        line.trim()
                    ));
                }
            }
        }
        assert!(
            found.is_empty(),
            "Automerge used outside `document`:\n{}",
            found.join("\n")
        );
    }
}