hdi/hash_path/anchor.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 69 70 71 72 73 74 75 76 77 78 79
use crate::hash_path::path::Component;
use crate::hash_path::path::Path;
use holochain_wasmer_guest::*;
/// This is the root of the [`Path`] tree.
///
/// Forms the entry point to all anchors so that agents can navigate down the tree from here.
pub const ROOT: &[u8; 2] = &[0x00, 0x00];
#[derive(PartialEq, SerializedBytes, serde::Serialize, serde::Deserialize, Debug, Clone)]
/// An anchor can only be 1 or 2 levels deep as "type" and "text".
///
/// The second level is optional and the Strings use the standard [`TryInto`] for path [`Component`] internally.
///
/// __Anchors are required to be included in an application's [`entry_defs`](crate::prelude::entry_types)__ callback and so implement all the standard methods.
/// Technically the [`Anchor`] entry definition is the [`Path`] definition.
///
/// e.g. `entry_defs![Anchor::entry_def()]`
///
/// 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.
pub struct Anchor {
pub anchor_type: String,
pub anchor_text: Option<String>,
}
/// Anchors are just a special case of path, so we can move from anchor to path losslessly.
/// We simply format the anchor structure into a string that works with the path string handling.
impl From<&Anchor> for Path {
fn from(anchor: &Anchor) -> Self {
let mut components = vec![
Component::new(ROOT.to_vec()),
Component::from(anchor.anchor_type.as_bytes().to_vec()),
];
if let Some(text) = anchor.anchor_text.as_ref() {
components.push(Component::from(text.as_bytes().to_vec()));
}
components.into()
}
}
#[cfg(test)]
#[test]
fn hash_path_root() {
assert_eq!(ROOT, &[0_u8, 0]);
}
#[cfg(test)]
#[test]
fn hash_path_anchor_path() {
let examples = [
(
"foo",
None,
Path::from(vec![
Component::from(vec![0, 0]),
Component::from(vec![102, 111, 111]),
]),
),
(
"foo",
Some("bar".to_string()),
Path::from(vec![
Component::from(vec![0, 0]),
Component::from(vec![102, 111, 111]),
Component::from(vec![98, 97, 114]),
]),
),
];
for (atype, text, path) in examples {
assert_eq!(
path,
(&Anchor {
anchor_type: atype.to_string(),
anchor_text: text,
})
.into(),
);
}
}