hdi/hash_path/
anchor.rs

1use crate::hash_path::path::Component;
2use crate::hash_path::path::Path;
3use holochain_wasmer_guest::*;
4
5/// This is the root of the [`Path`] tree.
6///
7/// Forms the entry point to all anchors so that agents can navigate down the tree from here.
8pub const ROOT: &[u8; 2] = &[0x00, 0x00];
9
10#[derive(PartialEq, SerializedBytes, serde::Serialize, serde::Deserialize, Debug, Clone)]
11/// An anchor can only be 1 or 2 levels deep as "type" and "text".
12///
13/// The second level is optional and the Strings use the standard [`TryInto`] for path [`Component`] internally.
14///
15/// __Anchors are required to be included in an application's [`entry_defs`](crate::prelude::entry_types)__ callback and so implement all the standard methods.
16/// Technically the [`Anchor`] entry definition is the [`Path`] definition.
17///
18/// e.g. `entry_defs![Anchor::entry_def()]`
19///
20/// The methods implemented on anchor follow the patterns that predate the Path module but `Path::from(&anchor)` is always possible to use the newer APIs.
21pub struct Anchor {
22    pub anchor_type: String,
23    pub anchor_text: Option<String>,
24}
25
26/// Anchors are just a special case of path, so we can move from anchor to path losslessly.
27/// We simply format the anchor structure into a string that works with the path string handling.
28impl From<&Anchor> for Path {
29    fn from(anchor: &Anchor) -> Self {
30        let mut components = vec![
31            Component::new(ROOT.to_vec()),
32            Component::from(anchor.anchor_type.as_bytes().to_vec()),
33        ];
34        if let Some(text) = anchor.anchor_text.as_ref() {
35            components.push(Component::from(text.as_bytes().to_vec()));
36        }
37        components.into()
38    }
39}
40
41#[cfg(test)]
42#[test]
43fn hash_path_root() {
44    assert_eq!(ROOT, &[0_u8, 0]);
45}
46
47#[cfg(test)]
48#[test]
49fn hash_path_anchor_path() {
50    let examples = [
51        (
52            "foo",
53            None,
54            Path::from(vec![
55                Component::from(vec![0, 0]),
56                Component::from(vec![102, 111, 111]),
57            ]),
58        ),
59        (
60            "foo",
61            Some("bar".to_string()),
62            Path::from(vec![
63                Component::from(vec![0, 0]),
64                Component::from(vec![102, 111, 111]),
65                Component::from(vec![98, 97, 114]),
66            ]),
67        ),
68    ];
69    for (atype, text, path) in examples {
70        assert_eq!(
71            path,
72            (&Anchor {
73                anchor_type: atype.to_string(),
74                anchor_text: text,
75            })
76                .into(),
77        );
78    }
79}