From 6ba4e9dacc8dec5843dbe0b77fa52c23bd08879c Mon Sep 17 00:00:00 2001 From: TheRealMorgenfrue <33068980+TheRealMorgenfrue@users.noreply.github.com> Date: Thu, 19 Feb 2026 08:48:23 +0000 Subject: [PATCH 01/10] WIP on custom errors --- Cargo.lock | 1 - crates/parser/Cargo.toml | 1 - src/errors.rs | 6 ++++++ 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 src/errors.rs diff --git a/Cargo.lock b/Cargo.lock index dab2846..87d6d13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7575,7 +7575,6 @@ dependencies = [ "log", "rdf-fusion", "serde", - "strum 0.27.2", "tokio", "tokio-stream", "vowlr-util", diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index 5de79f0..be9a3d8 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -20,7 +20,6 @@ log.workspace=true rdf-fusion.workspace=true serde="1.0" - strum.workspace=true tokio.workspace=true tokio-stream="0.1.17" vowlr-util={path="../util"} diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..3ff0c58 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,6 @@ +use leptos::prelude::RwSignal; + +#[derive(Clone)] +pub struct ErrorLogContext { + pub errors: RwSignal>, +} From 8ecc5e99cd257e7d6cd9ef31caeb24c69a2a3bdb Mon Sep 17 00:00:00 2001 From: TheRealMorgenfrue <33068980+TheRealMorgenfrue@users.noreply.github.com> Date: Thu, 19 Feb 2026 13:26:43 +0000 Subject: [PATCH 02/10] WIP 2 on errors --- Cargo.lock | 1 + crates/parser/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 87d6d13..dab2846 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7575,6 +7575,7 @@ dependencies = [ "log", "rdf-fusion", "serde", + "strum 0.27.2", "tokio", "tokio-stream", "vowlr-util", diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index be9a3d8..5de79f0 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -20,6 +20,7 @@ log.workspace=true rdf-fusion.workspace=true serde="1.0" + strum.workspace=true tokio.workspace=true tokio-stream="0.1.17" vowlr-util={path="../util"} From 6d8dfac87994d30578ff3d9c0d87837f363484b3 Mon Sep 17 00:00:00 2001 From: TheRealMorgenfrue <33068980+TheRealMorgenfrue@users.noreply.github.com> Date: Thu, 26 Feb 2026 14:18:40 +0000 Subject: [PATCH 03/10] Add custom error types handling --- crates/util/src/error_handler.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/util/src/error_handler.rs b/crates/util/src/error_handler.rs index bea35bd..6af25a2 100644 --- a/crates/util/src/error_handler.rs +++ b/crates/util/src/error_handler.rs @@ -72,6 +72,8 @@ pub enum ErrorType { /// /// It stores the data of a single error event. /// +/// # Examples +/// /// # Note /// Every error type in use should implement [`From for ErrorRecord`]. pub struct ErrorRecord { From e4ef0c3a249392d02d850b254aa5268514d87b93 Mon Sep 17 00:00:00 2001 From: TheRealMorgenfrue <33068980+TheRealMorgenfrue@users.noreply.github.com> Date: Sat, 28 Feb 2026 01:57:20 +0100 Subject: [PATCH 04/10] Fix Leptos version and test Leptos table gen --- crates/util/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/util/Cargo.toml b/crates/util/Cargo.toml index 8a50aa5..7276ae8 100644 --- a/crates/util/Cargo.toml +++ b/crates/util/Cargo.toml @@ -14,6 +14,7 @@ [dependencies] leptos.workspace=true + # leptos-struct-table.workspace=true log.workspace=true rkyv.workspace=true serde={version="1.0", features=["derive"]} From 1bc854c1cdf006236f97df998c3aa534b7542f86 Mon Sep 17 00:00:00 2001 From: nikarnik Date: Wed, 11 Mar 2026 10:15:49 +0000 Subject: [PATCH 05/10] Distinguish deferred triples in error handling --- crates/database/src/serializers/frontend.rs | 307 +++++++++++++++----- 1 file changed, 230 insertions(+), 77 deletions(-) diff --git a/crates/database/src/serializers/frontend.rs b/crates/database/src/serializers/frontend.rs index 83c628a..dfd0e31 100644 --- a/crates/database/src/serializers/frontend.rs +++ b/crates/database/src/serializers/frontend.rs @@ -31,6 +31,11 @@ pub struct GraphDisplayDataSolutionSerializer { pub resolvable_iris: HashSet, } +pub enum SerializationStatus { + Serialized, + Deferred, +} + impl GraphDisplayDataSolutionSerializer { pub fn new() -> Self { Self { @@ -83,6 +88,16 @@ impl GraphDisplayDataSolutionSerializer { Ok::<(), VOWLRError>(()) })?; + // Catch permanently unresolved triples + for (term, triples) in data_buffer.unknown_buffer.drain() { + for triple in triples { + data_buffer.failed_buffer.push(( + Some(triple), + format!("Unresolved reference: could not map '{}'", term), + )); + } + } + let finish_time = Instant::now() .checked_duration_since(start_time) .unwrap_or(Duration::new(0, 0)) @@ -364,6 +379,10 @@ impl GraphDisplayDataSolutionSerializer { object: obj_iri.clone(), property, }; + data_buffer + .edge_element_buffer + .insert(triple.element_type.clone(), edge.element_type); + data_buffer.edge_buffer.insert(edge.clone()); trace!( "Inserting edge: {} -> {} -> {}", edge.subject, edge.element_type, edge.object @@ -570,22 +589,31 @@ impl GraphDisplayDataSolutionSerializer { )?; } for triple in triples { - self.write_node_triple(data_buffer, triple)?; + match self.write_node_triple(data_buffer, triple.clone()) { + Ok(SerializationStatus::Serialized) => (), + Ok(SerializationStatus::Deferred) => { + data_buffer.failed_buffer.push(( + Some(triple), + "Failed to resolve references during second pass".to_string(), + )); + } + Err(e) => { + data_buffer + .failed_buffer + .push((e.inner.triple().cloned(), e.to_string())); + } + } } } - Ok(()) } - #[expect( - clippy::result_large_err, - reason = "fixed when serializer is refactored to use pointers instead of values" - )] /// Serialize a triple to `data_buffer`. fn write_node_triple( &self, data_buffer: &mut SerializationDataBuffer, triple: Triple, - ) -> Result<(), SerializationError> { + ) -> Result { + // TODO: Collect errors and show to frontend debug!("{}", triple); match &triple.element_type { Term::BlankNode(bnode) => { @@ -625,12 +653,17 @@ impl GraphDisplayDataSolutionSerializer { // rdf::OBJECT => {} // rdf::PREDICATE => {} rdf::PROPERTY => { - self.insert_edge( + let edge = self.insert_edge( data_buffer, &triple, ElementType::Rdf(RdfType::Edge(RdfEdge::RdfProperty)), None, ); + if edge.is_some() { + return Ok(SerializationStatus::Serialized); + } else { + return Ok(SerializationStatus::Deferred); + } } // rdf::REST => {} // rdf::SEQ => {} @@ -641,11 +674,14 @@ impl GraphDisplayDataSolutionSerializer { // rdf::XML_LITERAL => {} // ----------- RDFS ----------- // - rdfs::CLASS => self.insert_node( - data_buffer, - &triple, - ElementType::Rdfs(RdfsType::Node(RdfsNode::Class)), - )?, + rdfs::CLASS => { + self.insert_node( + data_buffer, + &triple, + ElementType::Rdfs(RdfsType::Node(RdfsNode::Class)), + )?; + return Ok(SerializationStatus::Serialized); + } //TODO: OWL1 // rdfs::COMMENT => {} @@ -658,6 +694,7 @@ impl GraphDisplayDataSolutionSerializer { &triple, ElementType::Rdfs(RdfsType::Node(RdfsNode::Datatype)), )?; + return Ok(SerializationStatus::Serialized); } rdfs::DOMAIN => { return Err(SerializationErrorKind::SerializationFailed( @@ -676,6 +713,7 @@ impl GraphDisplayDataSolutionSerializer { &triple, ElementType::Rdfs(RdfsType::Node(RdfsNode::Literal)), )?; + return Ok(SerializationStatus::Serialized); } // rdfs::MEMBER => {} rdfs::RANGE => { @@ -691,17 +729,23 @@ impl GraphDisplayDataSolutionSerializer { &triple, ElementType::Rdfs(RdfsType::Node(RdfsNode::Resource)), )?; + return Ok(SerializationStatus::Serialized); } //TODO: OWL1 // rdfs::SEE_ALSO => {} rdfs::SUB_CLASS_OF => { - self.insert_edge( + let edge = self.insert_edge( data_buffer, &triple, ElementType::Rdfs(RdfsType::Edge(RdfsEdge::SubclassOf)), None, ); + if edge.is_some() { + return Ok(SerializationStatus::Serialized); + } else { + return Ok(SerializationStatus::Deferred); + } } //TODO: OWL1 //rdfs::SUB_PROPERTY_OF => {}, @@ -726,11 +770,13 @@ impl GraphDisplayDataSolutionSerializer { // owl::ANNOTATION_PROPERTY => {}, // owl::ASSERTION_PROPERTY => {}, - owl::ASYMMETRIC_PROPERTY => self.insert_characteristic( - data_buffer, - triple, - Characteristic::AsymmetricProperty.to_string(), - ), + owl::ASYMMETRIC_PROPERTY => { + return Ok(self.insert_characteristic( + data_buffer, + triple, + Characteristic::AsymmetricProperty.to_string(), + )); + } // owl::AXIOM => {}, // owl::BACKWARD_COMPATIBLE_WITH => {}, @@ -739,13 +785,17 @@ impl GraphDisplayDataSolutionSerializer { //TODO: OWL1 // owl::CARDINALITY => {} - owl::CLASS => self.insert_node( - data_buffer, - &triple, - ElementType::Owl(OwlType::Node(OwlNode::Class)), - )?, + owl::CLASS => { + self.insert_node( + data_buffer, + &triple, + ElementType::Owl(OwlType::Node(OwlNode::Class)), + )?; + return Ok(SerializationStatus::Serialized); + } owl::COMPLEMENT_OF => { - self.insert_edge(data_buffer, &triple, ElementType::NoDraw, None); + let edge = + self.insert_edge(data_buffer, &triple, ElementType::NoDraw, None); if triple.target.is_some() && let Some(index) = self.resolve(data_buffer, triple.id.clone()) { @@ -755,6 +805,11 @@ impl GraphDisplayDataSolutionSerializer { ElementType::Owl(OwlType::Node(OwlNode::Complement)), ); } + if edge.is_some() { + return Ok(SerializationStatus::Serialized); + } else { + return Ok(SerializationStatus::Deferred); + } } //TODO: OWL1 @@ -766,30 +821,41 @@ impl GraphDisplayDataSolutionSerializer { &triple, e, ); + self.check_unknown_buffer(data_buffer, &triple.id)?; + return Ok(SerializationStatus::Serialized); } //TODO: OWL1 (deprecated in OWL2, replaced by rdfs:datatype) // owl::DATA_RANGE => {} // owl::DEPRECATED => {} - owl::DEPRECATED_CLASS => self.insert_node( - data_buffer, - &triple, - ElementType::Owl(OwlType::Node(OwlNode::DeprecatedClass)), - )?, + owl::DEPRECATED_CLASS => { + self.insert_node( + data_buffer, + &triple, + ElementType::Owl(OwlType::Node(OwlNode::DeprecatedClass)), + )?; + return Ok(SerializationStatus::Serialized); + } owl::DEPRECATED_PROPERTY => { - self.insert_edge( + let edge = self.insert_edge( data_buffer, &triple, ElementType::Owl(OwlType::Edge(OwlEdge::DeprecatedProperty)), None, ); + if edge.is_some() { + return Ok(SerializationStatus::Serialized); + } else { + return Ok(SerializationStatus::Deferred); + } } //TODO: OWL1 // owl::DIFFERENT_FROM => {} owl::DISJOINT_UNION_OF => { - self.insert_edge(data_buffer, &triple, ElementType::NoDraw, None); + let edge = + self.insert_edge(data_buffer, &triple, ElementType::NoDraw, None); if triple.target.is_some() && let Some(index) = self.resolve(data_buffer, triple.id.clone()) { @@ -799,14 +865,24 @@ impl GraphDisplayDataSolutionSerializer { ElementType::Owl(OwlType::Node(OwlNode::DisjointUnion)), ); } + if edge.is_some() { + return Ok(SerializationStatus::Serialized); + } else { + return Ok(SerializationStatus::Deferred); + } } owl::DISJOINT_WITH => { - self.insert_edge( + let edge = self.insert_edge( data_buffer, &triple, ElementType::Owl(OwlType::Edge(OwlEdge::DisjointWith)), None, ); + if edge.is_some() { + return Ok(SerializationStatus::Serialized); + } else { + return Ok(SerializationStatus::Deferred); + } } //TODO: OWL1 @@ -845,7 +921,8 @@ impl GraphDisplayDataSolutionSerializer { } (Some(_), None) => match triple.target.clone() { Some(target) => { - self.add_to_unknown_buffer(data_buffer, target, triple.clone()) + self.add_to_unknown_buffer(data_buffer, target, triple.clone()); + return Ok(SerializationStatus::Deferred); } None => { let msg = "Failed to merge object of equivalence relation into subject: object not found".to_string(); @@ -856,6 +933,7 @@ impl GraphDisplayDataSolutionSerializer { }, (None, Some(index_o)) => { self.add_to_unknown_buffer(data_buffer, index_o, triple.clone()); + return Ok(SerializationStatus::Deferred); } (None, None) => { self.add_to_unknown_buffer( @@ -863,15 +941,18 @@ impl GraphDisplayDataSolutionSerializer { triple.id.clone(), triple.clone(), ); + return Ok(SerializationStatus::Deferred); } } } // owl::EQUIVALENT_PROPERTY => {} - owl::FUNCTIONAL_PROPERTY => self.insert_characteristic( - data_buffer, - triple, - Characteristic::FunctionalProperty.to_string(), - ), + owl::FUNCTIONAL_PROPERTY => { + return Ok(self.insert_characteristic( + data_buffer, + triple, + Characteristic::FunctionalProperty.to_string(), + )); + } // owl::HAS_KEY => {} // owl::HAS_SELF => {} @@ -890,22 +971,37 @@ impl GraphDisplayDataSolutionSerializer { &edge.subject, ElementType::Owl(OwlType::Node(OwlNode::IntersectionOf)), ); + return Ok(SerializationStatus::Serialized); } } owl::INVERSE_FUNCTIONAL_PROPERTY => { - self.insert_characteristic( + return Ok(self.insert_characteristic( data_buffer, triple, Characteristic::InverseFunctionalProperty.to_string(), - ); + )); } - // TODO owl::INVERSE_OF => {} - owl::IRREFLEXIVE_PROPERTY => self.insert_characteristic( - data_buffer, - triple, - Characteristic::IrreflexiveProperty.to_string(), - ), + owl::INVERSE_OF => { + let edge = self.insert_edge( + data_buffer, + &triple, + ElementType::Owl(OwlType::Edge(OwlEdge::InverseOf)), + None, + ); + if edge.is_some() { + return Ok(SerializationStatus::Serialized); + } else { + return Ok(SerializationStatus::Deferred); + } + } + owl::IRREFLEXIVE_PROPERTY => { + return Ok(self.insert_characteristic( + data_buffer, + triple, + Characteristic::IrreflexiveProperty.to_string(), + )); + } //TODO: OWL1 // owl::MAX_CARDINALITY => {} @@ -928,6 +1024,8 @@ impl GraphDisplayDataSolutionSerializer { &triple, e, ); + self.check_unknown_buffer(data_buffer, &triple.id)?; + return Ok(SerializationStatus::Serialized); } // owl::ONE_OF => {} owl::ONTOLOGY => { @@ -958,11 +1056,13 @@ impl GraphDisplayDataSolutionSerializer { // owl::PROPERTY_CHAIN_AXIOM => {} // owl::PROPERTY_DISJOINT_WITH => {} // owl::QUALIFIED_CARDINALITY => {} - owl::REFLEXIVE_PROPERTY => self.insert_characteristic( - data_buffer, - triple, - Characteristic::ReflexiveProperty.to_string(), - ), + owl::REFLEXIVE_PROPERTY => { + return Ok(self.insert_characteristic( + data_buffer, + triple, + Characteristic::ReflexiveProperty.to_string(), + )); + } //TODO: OWL1 // owl::RESTRICTION => {} @@ -973,25 +1073,32 @@ impl GraphDisplayDataSolutionSerializer { //TODO: OWL1 // owl::SOME_VALUES_FROM => {} // owl::SOURCE_INDIVIDUAL => {} - owl::SYMMETRIC_PROPERTY => self.insert_characteristic( - data_buffer, - triple, - Characteristic::SymmetricProperty.to_string(), - ), + owl::SYMMETRIC_PROPERTY => { + return Ok(self.insert_characteristic( + data_buffer, + triple, + Characteristic::SymmetricProperty.to_string(), + )); + } // owl::TARGET_INDIVIDUAL => {} // owl::TARGET_VALUE => {} - owl::THING => self.insert_node( - data_buffer, - &triple, - ElementType::Owl(OwlType::Node(OwlNode::Thing)), - )?, + owl::THING => { + self.insert_node( + data_buffer, + &triple, + ElementType::Owl(OwlType::Node(OwlNode::Thing)), + )?; + return Ok(SerializationStatus::Serialized); + } // owl::TOP_DATA_PROPERTY => {} // owl::TOP_OBJECT_PROPERTY => {} - owl::TRANSITIVE_PROPERTY => self.insert_characteristic( - data_buffer, - triple, - Characteristic::TransitiveProperty.to_string(), - ), + owl::TRANSITIVE_PROPERTY => { + return Ok(self.insert_characteristic( + data_buffer, + triple, + Characteristic::TransitiveProperty.to_string(), + )); + } owl::UNION_OF => { let edge = self.insert_edge(data_buffer, &triple, ElementType::NoDraw, None); @@ -1001,7 +1108,9 @@ impl GraphDisplayDataSolutionSerializer { &edge.subject, ElementType::Owl(OwlType::Node(OwlNode::UnionOf)), ); + return Ok(SerializationStatus::Serialized); } + return Ok(SerializationStatus::Serialized); } // owl::VERSION_INFO => {} // owl::VERSION_IRI => {} @@ -1059,16 +1168,46 @@ impl GraphDisplayDataSolutionSerializer { }), ), None => { - trace!( - "Adding unknown buffer: target: {}, triple: {}", - target, triple - ); + // Register the property itself as an element so it can be resolved by characteristics + if triple.element_type + == owl::OBJECT_PROPERTY.into() + { + self.add_to_element_buffer( + &mut data_buffer.edge_element_buffer, + &triple, + ElementType::Owl(OwlType::Edge( + OwlEdge::ObjectProperty, + )), + ); + self.check_unknown_buffer( + data_buffer, + &triple.id, + )?; + return Ok(SerializationStatus::Serialized); + } else if triple.element_type + == owl::DATATYPE_PROPERTY.into() + { + self.add_to_element_buffer( + &mut data_buffer.edge_element_buffer, + &triple, + ElementType::Owl(OwlType::Edge( + OwlEdge::DatatypeProperty, + )), + ); + self.check_unknown_buffer( + data_buffer, + &triple.id, + )?; + return Ok(SerializationStatus::Serialized); + } + + // Default: defer if it's not a known property type self.add_to_unknown_buffer( data_buffer, target, triple.clone(), ); - (None, None) + return Ok(SerializationStatus::Deferred); } } } @@ -1115,7 +1254,7 @@ impl GraphDisplayDataSolutionSerializer { target, triple.clone(), ); - (None, None) + return Ok(SerializationStatus::Deferred); } } } @@ -1178,6 +1317,10 @@ impl GraphDisplayDataSolutionSerializer { ) .into(), ); + debug!( + "Property triple ignored: Subject or Object not in display buffer." + ); + return Ok(SerializationStatus::Deferred); } } @@ -1191,7 +1334,7 @@ impl GraphDisplayDataSolutionSerializer { triple.element_type.clone(), triple.clone(), ); - (None, None) + return Ok(SerializationStatus::Deferred); } _ => { trace!("Adding unknown buffer: triple: {}", triple); @@ -1200,7 +1343,7 @@ impl GraphDisplayDataSolutionSerializer { triple.id.clone(), triple.clone(), ); - (None, None) + return Ok(SerializationStatus::Deferred); } }; match node_triple { @@ -1255,6 +1398,9 @@ impl GraphDisplayDataSolutionSerializer { .cloned(), ); if let Some(edge) = edge { + // Clone the property IRI before it gets consumed below + let prop_iri = edge_triple.element_type.clone(); + data_buffer.add_property_edge( edge_triple.element_type.clone(), edge, @@ -1272,6 +1418,9 @@ impl GraphDisplayDataSolutionSerializer { edge_triple.element_type, edge_triple.id, ); + + // Re-evaluate any characteristics waiting for this edge to exist + self.check_unknown_buffer(data_buffer, &prop_iri)?; } } None => { @@ -1295,7 +1444,7 @@ impl GraphDisplayDataSolutionSerializer { } } } - Ok(()) + Ok(SerializationStatus::Serialized) } fn insert_characteristic( @@ -1303,7 +1452,7 @@ impl GraphDisplayDataSolutionSerializer { data_buffer: &mut SerializationDataBuffer, triple: Triple, arg: String, - ) { + ) -> SerializationStatus { let resolved = self.resolve(data_buffer, triple.id.clone()); match resolved { Some(s) => match data_buffer.node_characteristics.get_mut(&s) { @@ -1313,6 +1462,7 @@ impl GraphDisplayDataSolutionSerializer { } debug!("Inserting characteristic: {} -> {}", s, arg); char.push(arg); + SerializationStatus::Serialized } None => { for (k, v) in data_buffer.property_edge_map.iter() { @@ -1325,9 +1475,11 @@ impl GraphDisplayDataSolutionSerializer { data_buffer .edge_characteristics .insert(e.clone(), vec![arg]); + SerializationStatus::Serialized } None => { self.add_to_unknown_buffer(data_buffer, s, triple); + SerializationStatus::Deferred } } } @@ -1335,6 +1487,7 @@ impl GraphDisplayDataSolutionSerializer { None => { debug!("Adding characteristic to unknown buffer: {}", triple); self.add_to_unknown_buffer(data_buffer, triple.id.clone(), triple); + SerializationStatus::Deferred } } } From 6ab6d1cc65c4e79d9a8f8b39c953376e3893f09d Mon Sep 17 00:00:00 2001 From: nikarnik Date: Thu, 12 Mar 2026 08:39:29 +0000 Subject: [PATCH 06/10] resolve unionOf for anonymous classes --- crates/database/src/serializers/frontend.rs | 51 +++++++++++---------- crates/sparql_queries/src/snippets/owl.rs | 2 + 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/crates/database/src/serializers/frontend.rs b/crates/database/src/serializers/frontend.rs index dfd0e31..7e94e22 100644 --- a/crates/database/src/serializers/frontend.rs +++ b/crates/database/src/serializers/frontend.rs @@ -25,7 +25,7 @@ use rdf_fusion::{ }, }; use vowlr_parser::errors::VOWLRStoreError; -use vowlr_util::prelude::VOWLRError; +use vowlr_util::prelude::{ErrorRecord, ErrorSeverity, ErrorType, VOWLRError}; pub struct GraphDisplayDataSolutionSerializer { pub resolvable_iris: HashSet, @@ -79,7 +79,7 @@ impl GraphDisplayDataSolutionSerializer { self.write_node_triple(&mut data_buffer, triple) .or_else(|e| { data_buffer.failed_buffer.push(e.into()); - Ok::<(), VOWLRError>(()) + Ok::(SerializationStatus::Serialized) })?; count += 1; } @@ -91,9 +91,12 @@ impl GraphDisplayDataSolutionSerializer { // Catch permanently unresolved triples for (term, triples) in data_buffer.unknown_buffer.drain() { for triple in triples { - data_buffer.failed_buffer.push(( - Some(triple), + data_buffer.failed_buffer.push(ErrorRecord::new( + ErrorSeverity::Error, + ErrorType::Serializer, format!("Unresolved reference: could not map '{}'", term), + #[cfg(debug_assertions)] + Some(format!("Triple: {:?}", triple)), )); } } @@ -482,7 +485,11 @@ impl GraphDisplayDataSolutionSerializer { let old_elem_opt = data_buffer.node_element_buffer.get(iri).cloned(); match old_elem_opt { Some(old_elem) => { - if old_elem == ElementType::Owl(OwlType::Node(OwlNode::Class)) { + if matches!( + old_elem, + ElementType::Owl(OwlType::Node(OwlNode::Class)) + | ElementType::Owl(OwlType::Node(OwlNode::AnonymousClass)) + ) { data_buffer .node_element_buffer .insert(iri.clone(), new_element); @@ -592,19 +599,27 @@ impl GraphDisplayDataSolutionSerializer { match self.write_node_triple(data_buffer, triple.clone()) { Ok(SerializationStatus::Serialized) => (), Ok(SerializationStatus::Deferred) => { - data_buffer.failed_buffer.push(( - Some(triple), + data_buffer.failed_buffer.push(ErrorRecord::new( + ErrorSeverity::Error, + ErrorType::Serializer, "Failed to resolve references during second pass".to_string(), + #[cfg(debug_assertions)] + Some(format!("Triple: {:?}", triple)), )); } Err(e) => { - data_buffer - .failed_buffer - .push((e.inner.triple().cloned(), e.to_string())); + data_buffer.failed_buffer.push(ErrorRecord::new( + ErrorSeverity::Error, + ErrorType::Serializer, + e.to_string(), + #[cfg(debug_assertions)] + Some(format!("Triple: {:?}", triple)), + )); } } } } + Ok(()) } /// Serialize a triple to `data_buffer`. @@ -1109,8 +1124,9 @@ impl GraphDisplayDataSolutionSerializer { ElementType::Owl(OwlType::Node(OwlNode::UnionOf)), ); return Ok(SerializationStatus::Serialized); + } else { + return Ok(SerializationStatus::Deferred); } - return Ok(SerializationStatus::Serialized); } // owl::VERSION_INFO => {} // owl::VERSION_IRI => {} @@ -1310,13 +1326,6 @@ impl GraphDisplayDataSolutionSerializer { }), ) } else { - return Err( - SerializationErrorKind::SerializationFailed( - triple, - "Illegal property triple".to_string(), - ) - .into(), - ); debug!( "Property triple ignored: Subject or Object not in display buffer." ); @@ -1369,11 +1378,7 @@ impl GraphDisplayDataSolutionSerializer { } } None => { - return Err(SerializationErrorKind::SerializationFailed( - triple.clone(), - "Error creating node".to_string(), - ) - .into()); + // When subject/property/object are already resolved, no synthetic node is needed } } diff --git a/crates/sparql_queries/src/snippets/owl.rs b/crates/sparql_queries/src/snippets/owl.rs index cf815ed..a288b70 100644 --- a/crates/sparql_queries/src/snippets/owl.rs +++ b/crates/sparql_queries/src/snippets/owl.rs @@ -63,6 +63,8 @@ impl SparqlSnippet for OwlNode { OwlNode::UnionOf => { r#"{ ?id owl:unionOf ?list . + ?list rdf:rest*/rdf:first ?target . + FILTER(?target != rdf:nil) BIND(owl:unionOf AS ?nodeType) }"# } From ce77dfc29dec1c99c07ed6a86e486aead3ee5903 Mon Sep 17 00:00:00 2001 From: nikarnik Date: Thu, 12 Mar 2026 10:43:37 +0000 Subject: [PATCH 07/10] merge structural class expressions --- crates/database/src/serializers/frontend.rs | 82 +++++++++++++++++-- crates/sparql_queries/src/assembly.rs | 2 +- crates/sparql_queries/src/snippets/general.rs | 5 +- crates/sparql_queries/src/snippets/owl.rs | 13 ++- crates/util/Cargo.toml | 1 - crates/util/src/error_handler.rs | 2 - src/errors.rs | 5 -- 7 files changed, 84 insertions(+), 26 deletions(-) diff --git a/crates/database/src/serializers/frontend.rs b/crates/database/src/serializers/frontend.rs index 7e94e22..28c1ce7 100644 --- a/crates/database/src/serializers/frontend.rs +++ b/crates/database/src/serializers/frontend.rs @@ -811,7 +811,16 @@ impl GraphDisplayDataSolutionSerializer { owl::COMPLEMENT_OF => { let edge = self.insert_edge(data_buffer, &triple, ElementType::NoDraw, None); - if triple.target.is_some() + + let target_is_structural_class_expression = + if let Some(target) = triple.target.as_ref() { + self.is_structural_class_expression(data_buffer, target) + } else { + false + }; + + if !target_is_structural_class_expression + && triple.target.is_some() && let Some(index) = self.resolve(data_buffer, triple.id.clone()) { self.upgrade_node_type( @@ -820,6 +829,7 @@ impl GraphDisplayDataSolutionSerializer { ElementType::Owl(OwlType::Node(OwlNode::Complement)), ); } + if edge.is_some() { return Ok(SerializationStatus::Serialized); } else { @@ -1147,7 +1157,38 @@ impl GraphDisplayDataSolutionSerializer { "Resolving object property: range: {}, property: {}, domain: {}", range, property, domain ); - (None, Some(triple.clone())) + + // If range is a structural class-expression node, collapse to a Thing node. + let normalized_range = if self + .is_structural_class_expression(data_buffer, &range) + { + let thing_iri = + trim_tag_circumfix(domain.to_string().as_str()) + .to_string() + + "_thing"; + let thing_triple = self.create_triple( + thing_iri, + owl::THING.into(), + None, + )?; + self.insert_node( + data_buffer, + &thing_triple, + ElementType::Owl(OwlType::Node(OwlNode::Thing)), + )?; + thing_triple.id + } else { + range + }; + + ( + None, + Some(Triple { + id: domain, + element_type: property, + target: Some(normalized_range), + }), + ) } (Some(domain), Some(property), None) => { trace!("Missing range: {}", triple); @@ -1386,11 +1427,12 @@ impl GraphDisplayDataSolutionSerializer { Some(edge_triple) => { // Dummy variable // TODO: Refactor clones away in all of serializer + let element_type = edge_triple.element_type.clone(); let dummy = || edge_triple.clone(); let property= data_buffer .edge_element_buffer - .get(&edge_triple.element_type).ok_or_else(|| { + .get(&element_type).ok_or_else(|| { let msg = "Edge triple not present in edge_element_buffer".to_string(); SerializationErrorKind::SerializationFailed(dummy(), msg)})?; let edge = self.insert_edge( @@ -1411,6 +1453,10 @@ impl GraphDisplayDataSolutionSerializer { edge, ); data_buffer.add_property_domain( + edge_triple.element_type.clone(), + edge_triple.id.clone(), + ); + data_buffer.add_property_range( edge_triple.element_type.clone(), edge_triple.target.clone().ok_or_else(|| { SerializationErrorKind::SerializationFailed( @@ -1419,10 +1465,6 @@ impl GraphDisplayDataSolutionSerializer { ) })?, ); - data_buffer.add_property_range( - edge_triple.element_type, - edge_triple.id, - ); // Re-evaluate any characteristics waiting for this edge to exist self.check_unknown_buffer(data_buffer, &prop_iri)?; @@ -1452,6 +1494,19 @@ impl GraphDisplayDataSolutionSerializer { Ok(SerializationStatus::Serialized) } + fn is_structural_class_expression( + &self, + data_buffer: &SerializationDataBuffer, + term: &Term, + ) -> bool { + matches!( + data_buffer.node_element_buffer.get(term), + Some(ElementType::Owl(OwlType::Node( + OwlNode::UnionOf | OwlNode::IntersectionOf | OwlNode::DisjointUnion + ))) + ) + } + fn insert_characteristic( &self, data_buffer: &mut SerializationDataBuffer, @@ -1483,8 +1538,17 @@ impl GraphDisplayDataSolutionSerializer { SerializationStatus::Serialized } None => { - self.add_to_unknown_buffer(data_buffer, s, triple); - SerializationStatus::Deferred + // Property exists as an edge type, but no concrete edge instance has been materialized yet + if data_buffer.edge_element_buffer.contains_key(&s) { + debug!( + "Characteristic '{}' for '{}' has no materialized property edge; marking as serialized", + arg, s + ); + SerializationStatus::Serialized + } else { + self.add_to_unknown_buffer(data_buffer, s, triple); + SerializationStatus::Deferred + } } } } diff --git a/crates/sparql_queries/src/assembly.rs b/crates/sparql_queries/src/assembly.rs index bac044e..f5d7faa 100644 --- a/crates/sparql_queries/src/assembly.rs +++ b/crates/sparql_queries/src/assembly.rs @@ -27,7 +27,7 @@ impl QueryAssembler { format!( r#" {} - SELECT ?id ?nodeType ?target ?label + SELECT DISTINCT ?id ?nodeType ?target ?label WHERE {{ {} BIND( diff --git a/crates/sparql_queries/src/snippets/general.rs b/crates/sparql_queries/src/snippets/general.rs index dc4e0dd..9451220 100644 --- a/crates/sparql_queries/src/snippets/general.rs +++ b/crates/sparql_queries/src/snippets/general.rs @@ -6,10 +6,7 @@ pub const COLLECTIONS: &str = r#"{ ?intermediate rdf:first ?firstItem . ?intermediate rdf:rest*/rdf:first ?target . FILTER(?nodeType IN ( - owl:intersectionOf, - owl:unionOf, - owl:oneOf, - owl:disjointUnionOf + owl:oneOf )) # 6. Safety: Remove nil to avoid phantom edges diff --git a/crates/sparql_queries/src/snippets/owl.rs b/crates/sparql_queries/src/snippets/owl.rs index a288b70..4a4115b 100644 --- a/crates/sparql_queries/src/snippets/owl.rs +++ b/crates/sparql_queries/src/snippets/owl.rs @@ -22,6 +22,9 @@ impl SparqlSnippet for OwlNode { OwlNode::Complement => { r#"{ ?id owl:complementOf ?target . + FILTER NOT EXISTS { ?target owl:unionOf ?u . } + FILTER NOT EXISTS { ?target owl:intersectionOf ?u . } + FILTER NOT EXISTS { ?target owl:disjointUnionOf ?u . } BIND(owl:complementOf AS ?nodeType) }"# } @@ -44,14 +47,16 @@ impl SparqlSnippet for OwlNode { } OwlNode::DisjointUnion => { r#"{ - ?id owl:disjointUnionOf ?target . + ?id owl:disjointUnionOf/rdf:rest*/rdf:first ?target . BIND(owl:disjointUnionOf AS ?nodeType) + FILTER NOT EXISTS { ?c owl:complementOf ?id . } }"# } OwlNode::IntersectionOf => { r#"{ - ?id owl:intersectionOf ?target . + ?id owl:intersectionOf/rdf:rest*/rdf:first ?target . BIND(owl:intersectionOf AS ?nodeType) + FILTER NOT EXISTS { ?c owl:complementOf ?id . } }"# } OwlNode::Thing => { @@ -62,9 +67,9 @@ impl SparqlSnippet for OwlNode { } OwlNode::UnionOf => { r#"{ - ?id owl:unionOf ?list . - ?list rdf:rest*/rdf:first ?target . + ?id owl:unionOf/rdf:rest*/rdf:first ?target . FILTER(?target != rdf:nil) + FILTER NOT EXISTS { ?c owl:complementOf ?id . } BIND(owl:unionOf AS ?nodeType) }"# } diff --git a/crates/util/Cargo.toml b/crates/util/Cargo.toml index 7276ae8..8a50aa5 100644 --- a/crates/util/Cargo.toml +++ b/crates/util/Cargo.toml @@ -14,7 +14,6 @@ [dependencies] leptos.workspace=true - # leptos-struct-table.workspace=true log.workspace=true rkyv.workspace=true serde={version="1.0", features=["derive"]} diff --git a/crates/util/src/error_handler.rs b/crates/util/src/error_handler.rs index 6af25a2..bea35bd 100644 --- a/crates/util/src/error_handler.rs +++ b/crates/util/src/error_handler.rs @@ -72,8 +72,6 @@ pub enum ErrorType { /// /// It stores the data of a single error event. /// -/// # Examples -/// /// # Note /// Every error type in use should implement [`From for ErrorRecord`]. pub struct ErrorRecord { diff --git a/src/errors.rs b/src/errors.rs index 3ff0c58..8b13789 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,6 +1 @@ -use leptos::prelude::RwSignal; -#[derive(Clone)] -pub struct ErrorLogContext { - pub errors: RwSignal>, -} From 4c6774248834ff669febcd29cec0ac8c53331428 Mon Sep 17 00:00:00 2001 From: nikarnik Date: Fri, 13 Mar 2026 09:32:41 +0000 Subject: [PATCH 08/10] collapse structural class expressions --- Cargo.lock | 461 +++++++++----------- crates/database/src/serializers.rs | 6 + crates/database/src/serializers/frontend.rs | 370 +++++++++++----- crates/sparql_queries/src/snippets/owl.rs | 6 - 4 files changed, 455 insertions(+), 388 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dab2846..2e515a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -103,7 +103,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -206,7 +206,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.6.2", + "socket2 0.6.3", "time", "tracing", "url", @@ -220,7 +220,7 @@ checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" dependencies = [ "actix-router", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -697,7 +697,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -732,7 +732,7 @@ dependencies = [ "derive-where", "manyhow", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -747,7 +747,7 @@ dependencies = [ "manyhow", "proc-macro-utils", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "quote-use", "syn 2.0.117", ] @@ -909,7 +909,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -935,7 +935,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -1213,7 +1213,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "unicode-xid 0.2.6", ] @@ -1244,15 +1244,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "convert_case" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "convert_case" version = "0.10.0" @@ -1518,7 +1509,7 @@ dependencies = [ "fnv", "ident_case", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "strsim", "syn 2.0.117", ] @@ -1530,7 +1521,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -2005,7 +1996,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec6f637bce95efac05cdfb9b6c19579ed4aa5f6b94d951cfa5bb054b7bb4f730" dependencies = [ "datafusion-expr", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -2199,7 +2190,7 @@ checksum = "e0df63c21a4383f94bd5388564829423f35c316aed85dc4f8427aded372c7c0d" dependencies = [ "darling", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -2219,7 +2210,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -2231,7 +2222,7 @@ checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" dependencies = [ "convert_case 0.4.0", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "rustc_version", "syn 2.0.117", ] @@ -2253,7 +2244,7 @@ checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ "convert_case 0.10.0", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "rustc_version", "syn 2.0.117", "unicode-xid 0.2.6", @@ -2283,7 +2274,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -2331,9 +2322,9 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "either_of" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216d23e0ec69759a17f05e1c553f3a6870e5ec73420fbb07807a6f34d5d1d5a4" +checksum = "14f7f86eef3a7e4b9c2107583dbbbe3d9535c4b800796faf1774b82ba22033da" dependencies = [ "paste", "pin-project-lite", @@ -2577,7 +2568,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -2657,7 +2648,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -2732,21 +2723,21 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", + "r-efi 6.0.0", "wasip2", "wasip3", "wasm-bindgen", @@ -2918,7 +2909,7 @@ dependencies = [ [[package]] name = "grapher" version = "0.5.3" -source = "git+https://github.com/WebVOWL/WasmGrapher#3b887b0af8ab04efef370d23ed15227737733bc0" +source = "git+https://github.com/WebVOWL/WasmGrapher#787447e3b3f4df9d926990568e38a794a5e01c93" dependencies = [ "anyhow", "bytemuck", @@ -3249,7 +3240,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.2", + "socket2 0.6.3", "system-configuration", "tokio", "tower-service", @@ -3511,9 +3502,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" @@ -3548,9 +3539,9 @@ checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jiff" -version = "0.2.21" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e3d65f018c6ae946ab16e80944b97096ed73c35b221d1c478a6c81d8f57940" +checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" dependencies = [ "jiff-static", "log", @@ -3561,12 +3552,12 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.21" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17c2b211d863c7fde02cbea8a3c1a439b98e109286554f2860bdded7ff83818" +checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -3655,16 +3646,16 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "leptos" -version = "0.8.16" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ad8042559850ee5253293b8460a75513f7d542021b9303083d5c236bcdd16f" +checksum = "4b540ac2868724738f0f5d00f00ec4640e587223774219c1baddc46bad46fb8e" dependencies = [ "any_spawner", "base64", "cfg-if", "either_of", "futures", - "getrandom 0.4.1", + "getrandom 0.4.2", "hydration_context", "leptos_config", "leptos_dom", @@ -3787,7 +3778,7 @@ dependencies = [ "indexmap 2.13.0", "or_poisoned", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "rstml", "serde", "syn 2.0.117", @@ -3825,7 +3816,7 @@ dependencies = [ "prettyplease", "proc-macro-error2", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "rstml", "rustc_version", "server_fn_macro", @@ -3881,7 +3872,7 @@ checksum = "409c0bd99f986c3cfa1a4db2443c835bc602ded1a12784e22ecb28c3ed5a2ae2" dependencies = [ "proc-macro-error2", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -3970,9 +3961,9 @@ checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" [[package]] name = "libc" -version = "0.2.182" +version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "libloading" @@ -3992,13 +3983,14 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" dependencies = [ "bitflags 2.11.0", "libc", - "redox_syscall 0.7.2", + "plain", + "redox_syscall 0.7.3", ] [[package]] @@ -4122,7 +4114,7 @@ checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587" dependencies = [ "manyhow-macros", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -4134,7 +4126,7 @@ checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495" dependencies = [ "proc-macro-utils", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", ] [[package]] @@ -4254,7 +4246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -4364,7 +4356,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c84f77a45e99a2f9b492695d99e1c23844619caa5f3e57647cffacad773ca257" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 1.0.109", ] @@ -4466,7 +4458,7 @@ checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ "proc-macro-crate", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -4727,9 +4719,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -4739,9 +4731,9 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openssl" -version = "0.10.75" +version = "0.10.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +checksum = "951c002c75e16ea2c65b8c7e4d3d51d5530d8dfa7d060b4776828c88cfb18ecf" dependencies = [ "bitflags 2.11.0", "cfg-if", @@ -4759,7 +4751,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -4771,9 +4763,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-sys" -version = "0.9.111" +version = "0.9.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +checksum = "57d55af3b3e226502be1526dfdba67ab0e9c96fc293004e79576b2b9edb0dbdb" dependencies = [ "cc", "libc", @@ -5019,7 +5011,7 @@ checksum = "6298ab04c202fa5b5d52ba03269fb7b74550b150323038878fe6c372d8280f71" dependencies = [ "peg-runtime", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", ] [[package]] @@ -5075,7 +5067,7 @@ dependencies = [ "pest", "pest_meta", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -5121,29 +5113,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] [[package]] name = "pin-project-lite" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pin-utils" @@ -5157,6 +5149,12 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + [[package]] name = "polling" version = "3.11.0" @@ -5245,9 +5243,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ "toml_edit", ] @@ -5259,7 +5257,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", ] [[package]] @@ -5270,7 +5268,7 @@ checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" dependencies = [ "proc-macro-error-attr2", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -5281,7 +5279,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "smallvec", ] @@ -5310,7 +5308,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", "version_check", "yansi", @@ -5348,7 +5346,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -5381,9 +5379,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.38.4" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" +checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d" dependencies = [ "memchr", ] @@ -5399,9 +5397,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2 1.0.106", ] @@ -5412,7 +5410,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9619db1197b497a36178cfc736dc96b271fe918875fbf1344c436a7e93d0321e" dependencies = [ - "quote 1.0.44", + "quote 1.0.45", "quote-use-macros", ] @@ -5424,7 +5422,7 @@ checksum = "82ebfb7faafadc06a7ab141a6f67bcfb24cb8beb158c6fe933f2f035afa99f35" dependencies = [ "proc-macro-utils", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -5434,6 +5432,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rancor" version = "0.1.1" @@ -5504,9 +5508,9 @@ dependencies = [ [[package]] name = "range-alloc" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde" +checksum = "ca45419789ae5a7899559e9512e58ca889e41f04f1f2445e9f4b290ceccd1d08" [[package]] name = "rangemap" @@ -5717,12 +5721,12 @@ dependencies = [ [[package]] name = "reactive_stores" -version = "0.3.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35372f05664a62a3dd389503371a15b8feb3396f99f6ec000de651fddb030942" +checksum = "3e114642d342893571ff40b4e1da8ccdea907be44c649041eb7d8413b3fd95e8" dependencies = [ - "dashmap", "guardian", + "indexmap 2.13.0", "itertools", "or_poisoned", "paste", @@ -5734,14 +5738,14 @@ dependencies = [ [[package]] name = "reactive_stores_macro" -version = "0.2.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa40919eb2975100283b2a70e68eafce1e8bcf81f0622ff168e4c2b3f8d46bb" +checksum = "5b024812c47a6867b6cb32767a46182203f94e59eb88c69b032fd9caffa304ce" dependencies = [ - "convert_case 0.8.0", + "convert_case 0.11.0", "proc-macro-error2", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -5771,7 +5775,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76009fbe0614077fc1a2ce255e3a1881a2e3a3527097d5dc6d8212c585e7e38b" dependencies = [ - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -5795,9 +5799,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d94dd2f7cd932d4dc02cc8b2b50dfd38bd079a4e5d79198b99743d7fcf9a4b4" +checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" dependencies = [ "bitflags 2.11.0", ] @@ -5818,7 +5822,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -5973,7 +5977,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -5992,7 +5996,7 @@ dependencies = [ "derive-where", "proc-macro2 1.0.106", "proc-macro2-diagnostics", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", "syn_derive", "thiserror 2.0.18", @@ -6126,9 +6130,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -6234,7 +6238,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -6285,9 +6289,9 @@ dependencies = [ [[package]] name = "server_fn" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fafe3a832a747ded8dc4827c538a2a064284f150c1c44c51ec56b58bd947dd7" +checksum = "7c799cec4e8e210dfb2f203aa97f0e82232c619e385ef4d011b17a58d6397c7b" dependencies = [ "actix-web", "actix-ws", @@ -6323,14 +6327,14 @@ dependencies = [ [[package]] name = "server_fn_macro" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14faf423aab09f8c3eb2d9785bb37f11a255cdf01857d3c6083eacc82269c191" +checksum = "1295b54815397d30d986b63f93cfd515fa86d5e528e0bb589ce9d530502f9e0f" dependencies = [ "const_format", "convert_case 0.11.0", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "rustc_version", "syn 2.0.117", "xxhash-rust", @@ -6394,7 +6398,7 @@ version = "0.7.0" source = "git+https://github.com/WebVOWL/shred#8d87d631c916f69b5876bce8814576b73adebd31" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 1.0.109", ] @@ -6515,12 +6519,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -6574,7 +6578,7 @@ version = "0.4.1" source = "git+https://github.com/WebVOWL/specs#05d1c43517e2a7d318cfc522e408a332e0210bb1" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 1.0.109", ] @@ -6614,7 +6618,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da5fc6819faabb412da764b99d3b713bb55083c11e7e0c00144d386cd6a1939c" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -6678,7 +6682,7 @@ checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ "heck", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "rustversion", "syn 2.0.117", ] @@ -6691,7 +6695,7 @@ checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ "heck", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -6736,7 +6740,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "unicode-ident", ] @@ -6747,7 +6751,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "unicode-ident", ] @@ -6759,7 +6763,7 @@ checksum = "cdb066a04799e45f5d582e8fc6ec8e6d6896040d00898eb4e6a835196815b219" dependencies = [ "proc-macro-error2", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -6779,7 +6783,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -6833,15 +6837,15 @@ dependencies = [ "heck", "proc-macro-error2", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] [[package]] name = "tachys" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14691ce610071757bd17bd8d572065192c9c93f9f169125390aaea345a4c56b9" +checksum = "f768750b0d5514f487772187d4b20c66f56faff4541b1faa5aad4975f5aee085" dependencies = [ "any_spawner", "async-trait", @@ -6871,12 +6875,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.26.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.1", + "getrandom 0.4.2", "once_cell", "rustix 1.1.4", "windows-sys 0.61.2", @@ -6937,7 +6941,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -6948,7 +6952,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -7065,9 +7069,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.49.0" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" dependencies = [ "bytes", "libc", @@ -7075,19 +7079,19 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.2", + "socket2 0.6.3", "tokio-macros", "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -7143,7 +7147,7 @@ checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ "serde_core", "serde_spanned", - "toml_datetime", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "winnow", ] @@ -7157,14 +7161,23 @@ dependencies = [ "serde_core", ] +[[package]] +name = "toml_datetime" +version = "1.0.0+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" -version = "0.23.10+spec-1.0.0" +version = "0.25.4+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2" dependencies = [ "indexmap 2.13.0", - "toml_datetime", + "toml_datetime 1.0.0+spec-1.1.0", "toml_parser", "winnow", ] @@ -7242,7 +7255,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -7316,7 +7329,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "076a02dc54dd46795c2e9c8282ed40bcfb1e22747e955de9389a1de28190fb26" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -7476,11 +7489,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.21.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" +checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" dependencies = [ - "getrandom 0.4.1", + "getrandom 0.4.2", "js-sys", "serde_core", "wasm-bindgen", @@ -7678,7 +7691,7 @@ version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55839b71ba921e4f75b674cb16f843f4b1f3b26ddfcb3454de1cf65cc021ec0f" dependencies = [ - "quote 1.0.44", + "quote 1.0.45", "wasm-bindgen-macro-support", ] @@ -7690,7 +7703,7 @@ checksum = "caf2e969c2d60ff52e7e98b7392ff1588bffdd1ccd4769eba27222fd3d621571" dependencies = [ "bumpalo", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", "wasm-bindgen-shared", ] @@ -7781,7 +7794,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56481f8ed1a9f9ae97ea7b08a5e2b12e8adf9a7818a6ba952b918e09c7be8bf0" dependencies = [ "base16", - "quote 1.0.44", + "quote 1.0.45", "sha2", "syn 2.0.117", ] @@ -7811,9 +7824,9 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.12" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee64194ccd96bf648f42a65a7e589547096dfa702f7cadef84347b66ad164f9" +checksum = "aa75f400b7f719bcd68b3f47cd939ba654cedeef690f486db71331eec4c6a406" dependencies = [ "cc", "downcast-rs", @@ -7825,9 +7838,9 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.12" +version = "0.31.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e6faa537fbb6c186cb9f1d41f2f811a4120d1b57ec61f50da451a0c5122bec" +checksum = "ab51d9f7c071abeee76007e2b742499e535148035bb835f97aaed1338cf516c3" dependencies = [ "bitflags 2.11.0", "rustix 1.1.4", @@ -7848,9 +7861,9 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.31.12" +version = "0.31.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5864c4b5b6064b06b1e8b74ead4a98a6c45a285fe7a0e784d24735f011fdb078" +checksum = "4b3298683470fbdc6ca40151dfc48c8f2fd4c41a26e13042f801f85002384091" dependencies = [ "rustix 1.1.4", "wayland-client", @@ -7859,9 +7872,9 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.10" +version = "0.32.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baeda9ffbcfc8cd6ddaade385eaf2393bd2115a69523c735f12242353c3df4f3" +checksum = "b23b5df31ceff1328f06ac607591d5ba360cf58f90c8fad4ac8d3a55a3c4aec7" dependencies = [ "bitflags 2.11.0", "wayland-backend", @@ -7871,9 +7884,9 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa98634619300a535a9a97f338aed9a5ff1e01a461943e8346ff4ae26007306b" +checksum = "d392fc283a87774afc9beefcd6f931582bb97fe0e6ced0b306a62cb1d026527c" dependencies = [ "bitflags 2.11.0", "wayland-backend", @@ -7884,9 +7897,9 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9597cdf02cf0c34cd5823786dce6b5ae8598f05c2daf5621b6e178d4f7345f3" +checksum = "78248e4cc0eff8163370ba5c158630dcae1f3497a586b826eca2ef5f348d6235" dependencies = [ "bitflags 2.11.0", "wayland-backend", @@ -7897,20 +7910,20 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.8" +version = "0.31.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5423e94b6a63e68e439803a3e153a9252d5ead12fd853334e2ad33997e3889e3" +checksum = "c86287151a309799b821ca709b7345a048a2956af05957c89cb824ab919fa4e3" dependencies = [ "proc-macro2 1.0.106", - "quick-xml 0.38.4", - "quote 1.0.44", + "quick-xml 0.39.2", + "quote 1.0.45", ] [[package]] name = "wayland-sys" -version = "0.31.8" +version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6dbfc3ac5ef974c92a2235805cc0114033018ae1290a72e474aa8b28cbbdfd" +checksum = "374f6b70e8e0d6bf9461a32988fd553b59ff630964924dad6e4a4eb6bd538d17" dependencies = [ "dlib", "log", @@ -8170,7 +8183,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -8181,7 +8194,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -8192,7 +8205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -8203,7 +8216,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -8288,15 +8301,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - [[package]] name = "windows-sys" version = "0.61.2" @@ -8330,30 +8334,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -8366,12 +8353,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -8384,12 +8365,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -8402,24 +8377,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -8432,12 +8395,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -8450,12 +8407,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -8468,12 +8419,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -8486,17 +8431,11 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winit" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" +checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d" dependencies = [ "ahash", "android-activity", @@ -8546,9 +8485,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" dependencies = [ "memchr", ] @@ -8598,7 +8537,7 @@ dependencies = [ "anyhow", "prettyplease", "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", @@ -8755,7 +8694,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", "synstructure", ] @@ -8768,21 +8707,21 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.39" +version = "0.8.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.39" +version = "0.8.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] @@ -8802,7 +8741,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", "synstructure", ] @@ -8843,15 +8782,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2 1.0.106", - "quote 1.0.44", + "quote 1.0.45", "syn 2.0.117", ] [[package]] name = "zlib-rs" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c745c48e1007337ed136dc99df34128b9faa6ed542d80a1c673cf55a6d7236c8" +checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513" [[package]] name = "zmij" diff --git a/crates/database/src/serializers.rs b/crates/database/src/serializers.rs index a2aee08..4318836 100644 --- a/crates/database/src/serializers.rs +++ b/crates/database/src/serializers.rs @@ -184,6 +184,11 @@ pub struct SerializationDataBuffer { /// Used in cases where multiple elements should refer to a particular instance. /// E.g. multiple properties referring to the same instance of owl:Thing. global_element_mappings: HashMap, + /// Canonical synthesized Thing node per resolved domain. + /// + /// This lets structurally-defined ranges like complement/union expressions + /// collapse to the same Thing node that direct owl:Thing ranges use. + anchor_thing_map: HashMap, /// Stores the edges of a property. /// @@ -237,6 +242,7 @@ impl SerializationDataBuffer { edge_redirection: HashMap::new(), edges_include_map: HashMap::new(), global_element_mappings: HashMap::new(), + anchor_thing_map: HashMap::new(), label_buffer: HashMap::new(), edge_label_buffer: HashMap::new(), edge_buffer: HashSet::new(), diff --git a/crates/database/src/serializers/frontend.rs b/crates/database/src/serializers/frontend.rs index 28c1ce7..a7228dc 100644 --- a/crates/database/src/serializers/frontend.rs +++ b/crates/database/src/serializers/frontend.rs @@ -623,6 +623,10 @@ impl GraphDisplayDataSolutionSerializer { } /// Serialize a triple to `data_buffer`. + #[expect( + clippy::result_large_err, + reason = "fixed when serializer is refactored to use pointers instead of values" + )] fn write_node_triple( &self, data_buffer: &mut SerializationDataBuffer, @@ -812,15 +816,7 @@ impl GraphDisplayDataSolutionSerializer { let edge = self.insert_edge(data_buffer, &triple, ElementType::NoDraw, None); - let target_is_structural_class_expression = - if let Some(target) = triple.target.as_ref() { - self.is_structural_class_expression(data_buffer, target) - } else { - false - }; - - if !target_is_structural_class_expression - && triple.target.is_some() + if triple.target.is_some() && let Some(index) = self.resolve(data_buffer, triple.id.clone()) { self.upgrade_node_type( @@ -1159,32 +1155,40 @@ impl GraphDisplayDataSolutionSerializer { ); // If range is a structural class-expression node, collapse to a Thing node. - let normalized_range = if self - .is_structural_class_expression(data_buffer, &range) + let (normalized_domain, normalized_range) = if self + .is_collapsible_range_expression(data_buffer, &range) { - let thing_iri = - trim_tag_circumfix(domain.to_string().as_str()) - .to_string() - + "_thing"; - let thing_triple = self.create_triple( - thing_iri, - owl::THING.into(), - None, + let thing_anchor = if domain == owl::THING.into() { + range.clone() + } else { + domain.clone() + }; + + let thing = self.get_or_create_anchor_thing( + data_buffer, + &thing_anchor, )?; - self.insert_node( + self.hide_collapsed_range_expression( data_buffer, - &thing_triple, - ElementType::Owl(OwlType::Node(OwlNode::Thing)), + &range, + &thing, )?; - thing_triple.id + + let normalized_domain = if domain == owl::THING.into() { + thing.clone() + } else { + domain.clone() + }; + + (normalized_domain, thing) } else { - range + (domain.clone(), range) }; ( None, Some(Triple { - id: domain, + id: normalized_domain, element_type: property, target: Some(normalized_range), }), @@ -1192,127 +1196,135 @@ impl GraphDisplayDataSolutionSerializer { } (Some(domain), Some(property), None) => { trace!("Missing range: {}", triple); - let node = if target == owl::THING.into() { - let target_iri = - trim_tag_circumfix(domain.to_string().as_str()) - + "_thing"; - info!("Creating thing node: {}", target_iri); - Some(self.create_triple( - target_iri.clone(), - owl::THING.into(), + + if target == owl::THING.into() { + let thing = self + .get_or_create_domain_thing(data_buffer, &domain)?; + + ( None, - )?) + Some(Triple { + id: triple.id.clone(), + element_type: triple.element_type.clone(), + target: Some(thing), + }), + ) } else if target == rdfs::LITERAL.into() { let target_iri = trim_tag_circumfix(property.to_string().as_str()) + "_literal"; info!("Creating literal node: {}", target_iri); - Some(self.create_triple( + let node = self.create_triple( target_iri.clone(), rdfs::LITERAL.into(), None, - )?) - } else { - None - }; - match node { - Some(node) => ( + )?; + + ( Some(vec![node.clone()]), Some(Triple { id: triple.id.clone(), element_type: triple.element_type.clone(), target: Some(node.id), }), - ), - None => { - // Register the property itself as an element so it can be resolved by characteristics - if triple.element_type - == owl::OBJECT_PROPERTY.into() - { - self.add_to_element_buffer( - &mut data_buffer.edge_element_buffer, - &triple, - ElementType::Owl(OwlType::Edge( - OwlEdge::ObjectProperty, - )), - ); - self.check_unknown_buffer( - data_buffer, - &triple.id, - )?; - return Ok(SerializationStatus::Serialized); - } else if triple.element_type - == owl::DATATYPE_PROPERTY.into() - { - self.add_to_element_buffer( - &mut data_buffer.edge_element_buffer, - &triple, - ElementType::Owl(OwlType::Edge( - OwlEdge::DatatypeProperty, - )), - ); - self.check_unknown_buffer( - data_buffer, - &triple.id, - )?; - return Ok(SerializationStatus::Serialized); - } - - // Default: defer if it's not a known property type - self.add_to_unknown_buffer( - data_buffer, - target, - triple.clone(), + ) + } else { + // Register the property itself as an element so it can be resolved by characteristics + if triple.element_type == owl::OBJECT_PROPERTY.into() { + self.add_to_element_buffer( + &mut data_buffer.edge_element_buffer, + &triple, + ElementType::Owl(OwlType::Edge( + OwlEdge::ObjectProperty, + )), + ); + self.check_unknown_buffer(data_buffer, &triple.id)?; + return Ok(SerializationStatus::Serialized); + } else if triple.element_type + == owl::DATATYPE_PROPERTY.into() + { + self.add_to_element_buffer( + &mut data_buffer.edge_element_buffer, + &triple, + ElementType::Owl(OwlType::Edge( + OwlEdge::DatatypeProperty, + )), ); - return Ok(SerializationStatus::Deferred); + self.check_unknown_buffer(data_buffer, &triple.id)?; + return Ok(SerializationStatus::Serialized); } + + self.add_to_unknown_buffer( + data_buffer, + target, + triple.clone(), + ); + return Ok(SerializationStatus::Deferred); } } - (None, Some(_), Some(range)) => { + (None, Some(property), Some(range)) => { trace!("Missing domain: {}", triple); - let node = if triple.id == owl::THING.into() { - let target_iri = - trim_tag_circumfix(range.to_string().as_str()) - + "_thing"; - info!("Creating thing node: {}", target_iri); - Some(self.create_triple( - target_iri.clone(), - owl::THING.into(), + + if triple.id == owl::THING.into() { + let thing_anchor = range.clone(); + + let thing = self.get_or_create_anchor_thing( + data_buffer, + &thing_anchor, + )?; + + let normalized_range = if self + .is_collapsible_range_expression( + data_buffer, + &range, + ) { + self.hide_collapsed_range_expression( + data_buffer, + &range, + &thing, + )?; + thing.clone() + } else { + range + }; + + ( None, - )?) + Some(Triple { + id: thing, + element_type: property, + target: Some(normalized_range), + }), + ) } else if triple.id == rdfs::LITERAL.into() { let target_iri = trim_tag_circumfix(range.to_string().as_str()) + "_literal"; - Some(self.create_triple( - target_iri.clone(), + let node = self.create_triple( + target_iri, rdfs::LITERAL.into(), None, - )?) - } else { - None - }; - match node { - Some(node) => ( + )?; + + ( Some(vec![node.clone()]), Some(Triple { id: node.id, - element_type: triple.element_type.clone(), + element_type: property, target: triple.target.clone(), }), - ), - None => { - trace!( - "Adding unknown buffer: target: {}, triple: {}", - target, triple - ); - self.add_to_unknown_buffer( - data_buffer, - target, - triple.clone(), - ); - return Ok(SerializationStatus::Deferred); - } + ) + } else { + trace!( + "Adding unknown buffer: target: {}, triple: {}", + target, triple + ); + self.add_to_unknown_buffer( + data_buffer, + target, + triple.clone(), + ); + return Ok(SerializationStatus::Deferred); } } (None, Some(property), None) => { @@ -1355,7 +1367,7 @@ impl GraphDisplayDataSolutionSerializer { let node = self.create_triple( global_thing.to_string(), - global_thing, + owl::THING.into(), None, )?; ( @@ -1494,17 +1506,133 @@ impl GraphDisplayDataSolutionSerializer { Ok(SerializationStatus::Serialized) } - fn is_structural_class_expression( + #[expect( + clippy::result_large_err, + reason = "fixed when serializer is refactored to use pointers instead of values" + )] + fn get_or_create_domain_thing( + &self, + data_buffer: &mut SerializationDataBuffer, + domain: &Term, + ) -> Result { + if let Some(existing) = data_buffer.anchor_thing_map.get(domain) { + return Ok(existing.clone()); + } + + let thing_iri = trim_tag_circumfix(domain.to_string().as_str()).to_string() + "_thing"; + let thing_triple = self.create_triple(thing_iri, owl::THING.into(), None)?; + let thing_id = thing_triple.id.clone(); + + self.insert_node( + data_buffer, + &thing_triple, + ElementType::Owl(OwlType::Node(OwlNode::Thing)), + )?; + + data_buffer + .anchor_thing_map + .insert(domain.clone(), thing_id.clone()); + + Ok(thing_id) + } + + fn no_draw_target(&self, data_buffer: &SerializationDataBuffer, term: &Term) -> Option { + data_buffer + .edge_buffer + .iter() + .find(|edge| edge.subject == *term && edge.element_type == ElementType::NoDraw) + .map(|edge| edge.object.clone()) + } + + fn is_collapsible_range_expression( &self, data_buffer: &SerializationDataBuffer, term: &Term, ) -> bool { - matches!( - data_buffer.node_element_buffer.get(term), + match data_buffer.node_element_buffer.get(term) { Some(ElementType::Owl(OwlType::Node( - OwlNode::UnionOf | OwlNode::IntersectionOf | OwlNode::DisjointUnion - ))) - ) + OwlNode::UnionOf | OwlNode::IntersectionOf | OwlNode::DisjointUnion, + ))) => true, + Some(ElementType::Owl(OwlType::Node(OwlNode::Complement))) => self + .no_draw_target(data_buffer, term) + .is_some_and(|target| { + matches!( + data_buffer.node_element_buffer.get(&target), + Some(ElementType::Owl(OwlType::Node( + OwlNode::UnionOf | OwlNode::IntersectionOf | OwlNode::DisjointUnion + ))) + ) + }), + _ => false, + } + } + + #[expect( + clippy::result_large_err, + reason = "fixed when serializer is refactored to use pointers instead of values" + )] + fn hide_collapsed_range_expression( + &self, + data_buffer: &mut SerializationDataBuffer, + range: &Term, + replacement: &Term, + ) -> Result<(), SerializationError> { + let nested_target = match data_buffer.node_element_buffer.get(range) { + Some(ElementType::Owl(OwlType::Node(OwlNode::Complement))) => { + self.no_draw_target(data_buffer, range) + } + _ => None, + }; + let nested_target_ref = nested_target.as_ref(); + + self.redirect_iri(data_buffer, range, replacement)?; + data_buffer.node_element_buffer.remove(range); + data_buffer.edges_include_map.remove(range); + + if let Some(target) = nested_target_ref { + self.redirect_iri(data_buffer, target, replacement)?; + data_buffer.node_element_buffer.remove(target); + data_buffer.edges_include_map.remove(target); + } + + data_buffer.edge_buffer.retain(|edge| { + edge.element_type != ElementType::NoDraw + || (edge.subject != *range && edge.object != *range && nested_target_ref.is_none() + || nested_target_ref + .is_none_or(|target| edge.subject != *target && edge.object != *target)) + }); + + Ok(()) + } + + #[expect( + clippy::result_large_err, + reason = "fixed when serializer is refactored to use pointers instead of values" + )] + fn get_or_create_anchor_thing( + &self, + data_buffer: &mut SerializationDataBuffer, + anchor: &Term, + ) -> Result { + if let Some(existing) = data_buffer.anchor_thing_map.get(anchor) { + return Ok(existing.clone()); + } + + let thing_iri = trim_tag_circumfix(anchor.to_string().as_str()).to_string() + "_thing"; + let thing_triple = self.create_triple(thing_iri, owl::THING.into(), None)?; + let thing_id = thing_triple.id.clone(); + + self.insert_node( + data_buffer, + &thing_triple, + ElementType::Owl(OwlType::Node(OwlNode::Thing)), + )?; + + data_buffer + .anchor_thing_map + .insert(anchor.clone(), thing_id.clone()); + + Ok(thing_id) } fn insert_characteristic( diff --git a/crates/sparql_queries/src/snippets/owl.rs b/crates/sparql_queries/src/snippets/owl.rs index 4a4115b..0cb8909 100644 --- a/crates/sparql_queries/src/snippets/owl.rs +++ b/crates/sparql_queries/src/snippets/owl.rs @@ -22,9 +22,6 @@ impl SparqlSnippet for OwlNode { OwlNode::Complement => { r#"{ ?id owl:complementOf ?target . - FILTER NOT EXISTS { ?target owl:unionOf ?u . } - FILTER NOT EXISTS { ?target owl:intersectionOf ?u . } - FILTER NOT EXISTS { ?target owl:disjointUnionOf ?u . } BIND(owl:complementOf AS ?nodeType) }"# } @@ -49,14 +46,12 @@ impl SparqlSnippet for OwlNode { r#"{ ?id owl:disjointUnionOf/rdf:rest*/rdf:first ?target . BIND(owl:disjointUnionOf AS ?nodeType) - FILTER NOT EXISTS { ?c owl:complementOf ?id . } }"# } OwlNode::IntersectionOf => { r#"{ ?id owl:intersectionOf/rdf:rest*/rdf:first ?target . BIND(owl:intersectionOf AS ?nodeType) - FILTER NOT EXISTS { ?c owl:complementOf ?id . } }"# } OwlNode::Thing => { @@ -69,7 +64,6 @@ impl SparqlSnippet for OwlNode { r#"{ ?id owl:unionOf/rdf:rest*/rdf:first ?target . FILTER(?target != rdf:nil) - FILTER NOT EXISTS { ?c owl:complementOf ?id . } BIND(owl:unionOf AS ?nodeType) }"# } From 9b8c0edca115d36d04f1020336c7ca3c784d75b6 Mon Sep 17 00:00:00 2001 From: nikarnik Date: Fri, 13 Mar 2026 10:09:34 +0000 Subject: [PATCH 09/10] prioritize owl:Class over rdfs:Class --- crates/sparql_queries/src/snippets/rdfs.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/sparql_queries/src/snippets/rdfs.rs b/crates/sparql_queries/src/snippets/rdfs.rs index 6160432..1ae1b70 100644 --- a/crates/sparql_queries/src/snippets/rdfs.rs +++ b/crates/sparql_queries/src/snippets/rdfs.rs @@ -9,6 +9,7 @@ impl SparqlSnippet for RdfsNode { r#"{ ?id a rdfs:Class . FILTER(?id != owl:Class) + FILTER NOT EXISTS { ?id a owl:Class } BIND(rdfs:Class AS ?nodeType) }"# } From c73e360c55b0d0e04953bd09e533efd2deea6fcd Mon Sep 17 00:00:00 2001 From: nikarnik Date: Fri, 13 Mar 2026 13:58:47 +0000 Subject: [PATCH 10/10] use edge_element_buffer over triple.element_type --- crates/database/src/serializers/frontend.rs | 124 +++++++++++--------- 1 file changed, 68 insertions(+), 56 deletions(-) diff --git a/crates/database/src/serializers/frontend.rs b/crates/database/src/serializers/frontend.rs index a7228dc..7d61fbe 100644 --- a/crates/database/src/serializers/frontend.rs +++ b/crates/database/src/serializers/frontend.rs @@ -1329,60 +1329,71 @@ impl GraphDisplayDataSolutionSerializer { } (None, Some(property), None) => { trace!("Missing domain and range: {}", triple); - if triple.element_type == owl::DATATYPE_PROPERTY.into() { - let local_literal = self.create_named_node( - property.to_string() + "_locallitral", - )?; - let literal_triple = self.create_triple( - local_literal.to_string(), - rdfs::LITERAL.into(), - None, - )?; - info!("Creating literal node: {}", local_literal); - let local_thing = self.create_named_node( - property.to_string() + "_localthing", - )?; - let thing_triple = self.create_triple( - local_thing.to_string(), - owl::THING.into(), - None, - )?; - info!("Creating thing node: {}", local_thing); - ( - Some(vec![ - literal_triple.clone(), - thing_triple.clone(), - ]), - Some(Triple { - id: thing_triple.id.clone(), - element_type: triple.element_type.clone(), - target: Some(literal_triple.id), - }), - ) - } else if triple.element_type == owl::OBJECT_PROPERTY.into() + + match data_buffer + .edge_element_buffer + .get(&property) + .copied() { - let global_thing = self.create_named_node( - owl::THING.to_string() + "_thing", - )?; + Some(ElementType::Owl(OwlType::Edge( + OwlEdge::DatatypeProperty, + ))) => { + let local_literal = self.create_named_node( + property.to_string() + "_locallitral", + )?; + let literal_triple = self.create_triple( + local_literal.to_string(), + rdfs::LITERAL.into(), + None, + )?; + info!("Creating literal node: {}", local_literal); - let node = self.create_triple( - global_thing.to_string(), - owl::THING.into(), - None, - )?; - ( - Some(vec![node.clone()]), - Some(Triple { - id: node.id.clone(), - element_type: triple.element_type.clone(), - target: Some(node.id), - }), - ) - } else { - debug!( - "Property triple ignored: Subject or Object not in display buffer." - ); - return Ok(SerializationStatus::Deferred); + let local_thing = self.create_named_node( + property.to_string() + "_localthing", + )?; + let thing_triple = self.create_triple( + local_thing.to_string(), + owl::THING.into(), + None, + )?; + info!("Creating thing node: {}", local_thing); + + ( + Some(vec![ + literal_triple.clone(), + thing_triple.clone(), + ]), + Some(Triple { + id: thing_triple.id.clone(), + element_type: property.clone(), + target: Some(literal_triple.id), + }), + ) + } + Some(ElementType::Owl(OwlType::Edge( + OwlEdge::ObjectProperty, + ))) => { + let thing_anchor: Term = owl::THING.into(); + let thing = self.get_or_create_anchor_thing( + data_buffer, + &thing_anchor, + )?; + + ( + None, + Some(Triple { + id: thing.clone(), + element_type: property.clone(), + target: Some(thing), + }), + ) + } + _ => { + debug!( + "Property triple ignored: Subject or Object not in display buffer." + ); + return Ok(SerializationStatus::Deferred); + } } } @@ -1669,14 +1680,15 @@ impl GraphDisplayDataSolutionSerializer { // Property exists as an edge type, but no concrete edge instance has been materialized yet if data_buffer.edge_element_buffer.contains_key(&s) { debug!( - "Characteristic '{}' for '{}' has no materialized property edge; marking as serialized", + "Characteristic '{}' for '{}' has no materialized property edge yet; deferring", arg, s ); - SerializationStatus::Serialized } else { - self.add_to_unknown_buffer(data_buffer, s, triple); - SerializationStatus::Deferred + debug!("Adding characteristic to unknown buffer: {}", triple); } + + self.add_to_unknown_buffer(data_buffer, s, triple); + SerializationStatus::Deferred } } }