morphir_core/metadata/
term.rs1use crate::node_address::NodeUri;
4use serde_json::Value;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum GraphName {
9 Default,
11 Named(NodeUri),
13}
14
15#[derive(Debug, Clone, PartialEq, Eq)]
20pub struct TypedValue {
21 value: Value,
22 datatype: Option<NodeUri>,
23}
24
25impl TypedValue {
26 pub fn new(value: Value) -> Self {
28 Self {
29 value,
30 datatype: None,
31 }
32 }
33
34 pub fn json(value: Value, datatype: NodeUri) -> Self {
37 Self {
38 value,
39 datatype: Some(datatype),
40 }
41 }
42
43 pub fn value(&self) -> &Value {
45 &self.value
46 }
47
48 pub fn datatype(&self) -> Option<&NodeUri> {
50 self.datatype.as_ref()
51 }
52
53 pub(crate) fn identity(&self) -> String {
54 serde_json::to_string(&(
55 self.datatype.as_ref().map(ToString::to_string),
56 canonical_value(&self.value),
57 ))
58 .expect("JSON values and strings serialize")
59 }
60}
61
62#[derive(Debug, Clone, PartialEq, Eq)]
64pub enum ObjectTerm {
65 Value(TypedValue),
67 NodeRef(NodeUri),
69}
70
71impl ObjectTerm {
72 pub fn value(value: Value) -> Self {
74 Self::Value(TypedValue::new(value))
75 }
76
77 pub fn typed_json(value: Value, datatype: NodeUri) -> Self {
79 Self::Value(TypedValue::json(value, datatype))
80 }
81
82 pub(crate) fn identity(&self) -> String {
83 match self {
84 Self::Value(value) => format!("value:{}", value.identity()),
85 Self::NodeRef(uri) => format!("node:{}", uri),
86 }
87 }
88}
89
90#[derive(Debug, Clone, PartialEq, Eq)]
95pub struct Fact {
96 subject: NodeUri,
97 predicate: NodeUri,
98 object: ObjectTerm,
99 graph: GraphName,
100}
101
102impl Fact {
103 pub fn new(subject: NodeUri, predicate: NodeUri, object: ObjectTerm, graph: GraphName) -> Self {
105 Self {
106 subject,
107 predicate,
108 object,
109 graph,
110 }
111 }
112
113 pub fn subject(&self) -> &NodeUri {
115 &self.subject
116 }
117
118 pub fn predicate(&self) -> &NodeUri {
120 &self.predicate
121 }
122
123 pub fn object(&self) -> &ObjectTerm {
125 &self.object
126 }
127
128 pub fn graph(&self) -> &GraphName {
130 &self.graph
131 }
132
133 pub(crate) fn identity(&self) -> String {
134 serde_json::to_string(&(
135 self.subject.to_string(),
136 self.predicate.to_string(),
137 self.object.identity(),
138 match &self.graph {
139 GraphName::Default => "default".to_owned(),
140 GraphName::Named(uri) => format!("named:{uri}"),
141 },
142 ))
143 .expect("fact identities serialize")
144 }
145}
146
147fn canonical_value(value: &Value) -> Value {
148 match value {
149 Value::Array(items) => Value::Array(items.iter().map(canonical_value).collect()),
150 Value::Object(members) => {
151 let mut keys = members.keys().collect::<Vec<_>>();
152 keys.sort_unstable();
153 let mut sorted = serde_json::Map::new();
154 for key in keys {
155 sorted.insert(key.clone(), canonical_value(&members[key]));
156 }
157 Value::Object(sorted)
158 }
159 _ => value.clone(),
160 }
161}