qualia_core_db/query/
rdf_star.rs1use crate::lexicon::{generate_embedded_triple_id, TAG_EMBEDDED};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
13pub enum RdfStarParseError {
14 InvalidSyntax,
16 MalformedEmbeddedTriple,
18 BufferOverflow,
20 UnsupportedFeature,
22 InvalidUtf8,
24 LexiconError,
26}
27
28#[derive(Debug, Clone, PartialEq, Eq)]
30pub enum RdfStarSerializeError {
31 VirtualIdNotFound,
33 ComponentNotFound,
35 BufferTooSmall,
37 UnsupportedFeature,
39}
40
41impl std::fmt::Display for RdfStarParseError {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 write!(f, "{:?}", self)
44 }
45}
46impl std::error::Error for RdfStarParseError {}
47
48impl std::fmt::Display for RdfStarSerializeError {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 write!(f, "{:?}", self)
51 }
52}
53impl std::error::Error for RdfStarSerializeError {}
54
55pub trait RdfStarParser {
60 fn parse_embedded_triple(&mut self, input: &[u8])
64 -> Result<(u64, [u64; 3]), RdfStarParseError>;
65
66 fn parse_triple(&mut self, input: &[u8]) -> Result<(u64, u64, u64), RdfStarParseError>;
68
69 fn parse_quad(&mut self, input: &[u8]) -> Result<(u64, u64, u64, u64), RdfStarParseError>;
73
74 fn supports_quads(&self) -> bool;
76
77 fn supports_named_graphs(&self) -> bool;
79
80 fn format_name(&self) -> &'static str;
82}
83
84pub trait RdfStarSerializer {
89 fn serialize_embedded_triple(
93 &self,
94 virtual_id: u64,
95 components: &[u64; 3],
96 ) -> Result<Vec<u8>, RdfStarSerializeError>;
97
98 fn serialize_triple(
100 &self,
101 subject: u64,
102 predicate: u64,
103 object: u64,
104 ) -> Result<Vec<u8>, RdfStarSerializeError>;
105
106 fn serialize_quad(
108 &self,
109 subject: u64,
110 predicate: u64,
111 object: u64,
112 graph: u64,
113 ) -> Result<Vec<u8>, RdfStarSerializeError>;
114
115 fn supports_quads(&self) -> bool;
117
118 fn format_name(&self) -> &'static str;
120}
121
122#[inline(always)]
127pub fn create_virtual_id(subject: u64, predicate: u64, object: u64) -> u64 {
128 let virtual_id = generate_embedded_triple_id(subject, predicate, object);
129 debug_assert_eq!(
130 virtual_id & TAG_EMBEDDED,
131 TAG_EMBEDDED,
132 "TAG_EMBEDDED bit should be set"
133 );
134 virtual_id
135}
136
137#[inline(always)]
139pub fn is_virtual_id(value: u64) -> bool {
140 (value & TAG_EMBEDDED) != 0
141}
142
143#[cfg(test)]
144mod tests {
145 use super::*;
146
147 #[test]
148 fn test_create_virtual_id_sets_tag() {
149 let vid = create_virtual_id(1, 2, 3);
150 assert_eq!(vid & TAG_EMBEDDED, TAG_EMBEDDED);
151 }
152
153 #[test]
154 fn test_is_virtual_id() {
155 let vid = create_virtual_id(1, 2, 3);
156 assert!(is_virtual_id(vid));
157
158 let regular_hash = 12345u64;
159 assert!(!is_virtual_id(regular_hash));
160 }
161
162 #[test]
163 fn test_create_virtual_id_deterministic() {
164 let vid1 = create_virtual_id(1, 2, 3);
165 let vid2 = create_virtual_id(1, 2, 3);
166 assert_eq!(vid1, vid2);
167 }
168}
169
170pub fn subject_of_virtual_id(
182 virtual_id: u64,
183 lex_data: &[u8],
184 _blob_base: usize,
185) -> Result<u64, RdfStarParseError> {
186 if !is_virtual_id(virtual_id) {
187 return Err(RdfStarParseError::MalformedEmbeddedTriple);
188 }
189 let lex = crate::q42_lex::Q42LexMmap::from_bytes(lex_data)
190 .map_err(|_| RdfStarParseError::LexiconError)?;
191 lex.lookup_embedded_triple(virtual_id)
192 .map(|t| t[0])
193 .ok_or(RdfStarParseError::LexiconError)
194}
195
196pub fn predicate_of_virtual_id(
198 virtual_id: u64,
199 lex_data: &[u8],
200 _blob_base: usize,
201) -> Result<u64, RdfStarParseError> {
202 if !is_virtual_id(virtual_id) {
203 return Err(RdfStarParseError::MalformedEmbeddedTriple);
204 }
205 let lex = crate::q42_lex::Q42LexMmap::from_bytes(lex_data)
206 .map_err(|_| RdfStarParseError::LexiconError)?;
207 lex.lookup_embedded_triple(virtual_id)
208 .map(|t| t[1])
209 .ok_or(RdfStarParseError::LexiconError)
210}
211
212pub fn object_of_virtual_id(
214 virtual_id: u64,
215 lex_data: &[u8],
216 _blob_base: usize,
217) -> Result<u64, RdfStarParseError> {
218 if !is_virtual_id(virtual_id) {
219 return Err(RdfStarParseError::MalformedEmbeddedTriple);
220 }
221 let lex = crate::q42_lex::Q42LexMmap::from_bytes(lex_data)
222 .map_err(|_| RdfStarParseError::LexiconError)?;
223 lex.lookup_embedded_triple(virtual_id)
224 .map(|t| t[2])
225 .ok_or(RdfStarParseError::LexiconError)
226}
227
228pub fn triple_from_components(subject: u64, predicate: u64, object: u64) -> u64 {
232 create_virtual_id(subject, predicate, object)
233}