pr4xis_runtime/
archive.rs1use serde::{Deserialize, Serialize};
18
19use crate::address::ContentAddress;
20use crate::codec::{self, CodecError};
21use crate::connection::Connection;
22use crate::definition::Definition;
23
24#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
26pub struct Archive {
27 pub nodes: Vec<Definition>,
29 pub connections: Vec<Connection>,
31}
32
33impl Archive {
34 pub fn new() -> Self {
36 Self::default()
37 }
38
39 pub fn root(&self) -> Result<ContentAddress, CodecError> {
42 let mut addrs: Vec<[u8; 32]> =
43 Vec::with_capacity(self.nodes.len() + self.connections.len());
44 for n in &self.nodes {
45 addrs.push(*n.address()?.as_bytes());
46 }
47 for c in &self.connections {
48 addrs.push(*c.address()?.as_bytes());
49 }
50 addrs.sort_unstable();
51 addrs.dedup();
52 codec::address_of(&addrs)
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59 use crate::connection::GeneratorAction;
60
61 fn node(name: &str) -> Definition {
62 Definition {
63 kind: "Concept".into(),
64 name: name.into(),
65 edges: vec![],
66 axioms: vec![],
67 lexical: None,
68 }
69 }
70
71 fn conn() -> Connection {
72 Connection {
73 kind: "Faithful".into(),
74 source: "A".into(),
75 target: "B".into(),
76 action: GeneratorAction::Functor {
77 map_object: vec![("A".into(), "B".into())],
78 map_morphism: vec![],
79 },
80 laws: vec![],
81 }
82 }
83
84 #[test]
85 fn empty_archive_has_a_stable_root() {
86 assert_eq!(
87 Archive::new().root().unwrap(),
88 Archive::new().root().unwrap()
89 );
90 }
91
92 #[test]
93 fn adding_a_node_changes_the_root() {
94 let mut a = Archive::new();
95 a.nodes.push(node("X"));
96 assert_ne!(Archive::new().root().unwrap(), a.root().unwrap());
97 }
98
99 #[test]
100 fn root_is_node_order_independent() {
101 let a = Archive {
102 nodes: vec![node("X"), node("Y")],
103 connections: vec![],
104 };
105 let b = Archive {
106 nodes: vec![node("Y"), node("X")],
107 connections: vec![],
108 };
109 assert_eq!(a.root().unwrap(), b.root().unwrap());
110 }
111
112 #[test]
113 fn duplicate_node_does_not_change_the_root() {
114 let a = Archive {
115 nodes: vec![node("X")],
116 connections: vec![],
117 };
118 let b = Archive {
119 nodes: vec![node("X"), node("X")],
120 connections: vec![],
121 };
122 assert_eq!(a.root().unwrap(), b.root().unwrap());
123 }
124
125 #[test]
126 fn a_connection_contributes_to_the_root() {
127 let a = Archive {
128 nodes: vec![node("A"), node("B")],
129 connections: vec![],
130 };
131 let mut b = a.clone();
132 b.connections.push(conn());
133 assert_ne!(a.root().unwrap(), b.root().unwrap());
134 }
135}