From 816798d00652bc2cac0673f8b753856ed472a34d Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Champin Date: Thu, 2 Apr 2020 09:40:58 +0200 Subject: [PATCH 1/2] open blank_node inners This is required by libraries binding Oxigraph to other languages or other APIs. --- lib/src/model/blank_node.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/src/model/blank_node.rs b/lib/src/model/blank_node.rs index e485fe24..df806bc1 100644 --- a/lib/src/model/blank_node.rs +++ b/lib/src/model/blank_node.rs @@ -22,7 +22,13 @@ pub struct BlankNode { impl BlankNode { /// Creates a blank node from a unique id - pub(crate) fn new_from_unique_id(id: u128) -> Self { + /// + /// In most cases, you **should not*** create a blank node this way, + /// but should use `Default::default` instead. + /// + /// This method is only exposed for low-level library, + /// in particular bindings to other languages or APIs. + pub fn new_from_unique_id(id: u128) -> Self { let mut str = [0; 32]; write!(&mut str[..], "{:x}", id).unwrap(); Self { id, str } @@ -33,8 +39,8 @@ impl BlankNode { str::from_utf8(&self.str).unwrap() } - /// Returns the underlying ID of this blank node - pub(crate) const fn id(&self) -> u128 { + /// Returns the internal ID of this blank node + pub const fn id(&self) -> u128 { self.id } } From 053335b4313790a5fa0ff5f986e4406256261ed5 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Champin Date: Thu, 2 Apr 2020 12:32:15 +0200 Subject: [PATCH 2/2] open API for creating unchecked NamedNode Again, this will be useful for bindings to other languages and APIs, where IRIs have been checked elsewhere, and hence do not need another parsing. Renamed new_from_string to new_unchecked, to make explicit the unchecked nature of this method (now that it is public). --- lib/src/model/named_node.rs | 10 ++- lib/src/model/vocab.rs | 124 +++++++++++++++---------------- lib/src/store/numeric_encoder.rs | 12 +-- 3 files changed, 76 insertions(+), 70 deletions(-) diff --git a/lib/src/model/named_node.rs b/lib/src/model/named_node.rs index 4cd43b76..3e8df04a 100644 --- a/lib/src/model/named_node.rs +++ b/lib/src/model/named_node.rs @@ -27,10 +27,16 @@ impl NamedNode { } pub(crate) fn new_from_iri(iri: Iri) -> Self { - Self::new_from_string(iri.into_inner()) + Self::new_unchecked(iri.into_inner()) } - pub(crate) fn new_from_string(iri: impl Into) -> Self { + /// Builds a RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) from a string. + /// + /// Note that it is the caller's responsibility to ensure that `iri` + /// is a valid IRI. + /// + /// See also [`parse`](#method.parse). + pub fn new_unchecked(iri: impl Into) -> Self { Self { iri: iri.into() } } diff --git a/lib/src/model/vocab.rs b/lib/src/model/vocab.rs index 30b64051..022cddc5 100644 --- a/lib/src/model/vocab.rs +++ b/lib/src/model/vocab.rs @@ -8,54 +8,54 @@ pub mod rdf { lazy_static! { /// The class of containers of alternatives. pub static ref ALT: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#Alt"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Alt"); /// The class of unordered containers. pub static ref BAG: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag"); /// The first item in the subject RDF list. pub static ref FIRST: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#first"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#first"); /// The class of HTML literal values. pub static ref HTML: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#HTML"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#HTML"); /// The class of language-tagged string literal values. pub static ref LANG_STRING: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"); /// The class of RDF Lists. pub static ref LIST: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#List"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#List"); pub static ref NIL: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"); /// The object of the subject RDF statement. pub static ref OBJECT: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#object"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#object"); /// The predicate of the subject RDF statement. pub static ref PREDICATE: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#predicate"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#predicate"); /// The class of RDF properties. pub static ref PROPERTY: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"); /// The rest of the subject RDF list after the first item. pub static ref REST: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest"); /// The class of ordered containers. pub static ref SEQ: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq"); /// The class of RDF statements. pub static ref STATEMENT: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#Statement"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#Statement"); /// The subject of the subject RDF statement. pub static ref SUBJECT: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#subject"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#subject"); /// The subject is an instance of a class. pub static ref TYPE: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); /// Idiomatic property used for structured values. pub static ref VALUE: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#value"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#value"); /// The class of XML literal values. pub static ref XML_LITERAL: NamedNode = - NamedNode::new_from_string("http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"); + NamedNode::new_unchecked("http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"); } } @@ -67,49 +67,49 @@ pub mod rdfs { lazy_static! { /// The class of classes. pub static ref CLASS: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#Class"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Class"); /// A description of the subject resource. pub static ref COMMENT: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#comment"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#comment"); /// The class of RDF containers. pub static ref CONTAINER: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#Container"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Container"); /// The class of container membership properties, rdf:_1, rdf:_2, ..., all of which are sub-properties of 'member'. pub static ref CONTAINER_MEMBERSHIP_PROPERTY: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#ContainerMembershipProperty"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#ContainerMembershipProperty"); /// The class of RDF datatypes. pub static ref DATATYPE: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#Datatype"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Datatype"); /// A domain of the subject property. pub static ref DOMAIN: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#domain"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#domain"); /// The definition of the subject resource. pub static ref IS_DEFINED_BY: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#isDefinedBy"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#isDefinedBy"); /// A human-readable name for the subject. pub static ref LABEL: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#label"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#label"); /// The class of literal values, e.g. textual strings and integers. pub static ref LITERAL: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#Literal"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Literal"); /// A member of the subject resource. pub static ref MEMBER: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#member"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#member"); /// A range of the subject property. pub static ref RANGE: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#range"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#range"); /// The class resource, everything. pub static ref RESOURCE: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#Resource"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#Resource"); /// Further information about the subject resource. pub static ref SEE_ALSO: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#seeAlso"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#seeAlso"); /// The subject is a subclass of a class. pub static ref SUB_CLASS_OF: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#subClassOf"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#subClassOf"); /// The subject is a subproperty of a property. pub static ref SUB_PROPERTY_OF: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2000/01/rdf-schema#subPropertyOf"); + NamedNode::new_unchecked("http://www.w3.org/2000/01/rdf-schema#subPropertyOf"); } } @@ -121,93 +121,93 @@ pub mod xsd { lazy_static! { /// true, false pub static ref BOOLEAN: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#boolean"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#boolean"); /// 128…+127 (8 bit) pub static ref BYTE: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#byte"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#byte"); /// Dates (yyyy-mm-dd) with or without timezone pub static ref DATE: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#date"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#date"); /// Duration of time (days, hours, minutes, seconds only) pub static ref DAY_TIME_DURATION: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#dayTimeDuration"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#dayTimeDuration"); /// Date and time with or without timezone pub static ref DATE_TIME: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#dateTime"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#dateTime"); /// Date and time with required timezone pub static ref DATE_TIME_STAMP: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#dateTimeStamp"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#dateTimeStamp"); /// Arbitrary-precision decimal numbers pub static ref DECIMAL: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#decimal"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#decimal"); /// 64-bit floating point numbers incl. ±Inf, ±0, NaN pub static ref DOUBLE: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#double"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#double"); /// Duration of time pub static ref DURATION: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#duration"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#duration"); /// 32-bit floating point numbers incl. ±Inf, ±0, NaN pub static ref FLOAT: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#float"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#float"); /// Gregorian calendar day of the month pub static ref G_DAY: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#gDay"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#gDay"); /// Gregorian calendar month pub static ref G_MONTH: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#gMonth"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#gMonth"); /// Gregorian calendar month and day pub static ref G_MONTH_DAY: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#gMonthDay"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#gMonthDay"); /// Gregorian calendar year pub static ref G_YEAR: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#gYear"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#gYear"); /// Gregorian calendar year and month pub static ref G_YEAR_MONTH: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#gYearMonth"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#gYearMonth"); /// -2147483648…+2147483647 (32 bit) pub static ref INT: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#int"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#int"); /// Arbitrary-size integer numbers pub static ref INTEGER: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#integer"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#integer"); /// -9223372036854775808…+9223372036854775807 (64 bit) pub static ref LONG: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#long"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#long"); /// Integer numbers <0 pub static ref NEGATIVE_INTEGER: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#negativeInteger"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#negativeInteger"); /// Integer numbers ≥0 pub static ref NON_NEGATIVE_INTEGER: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#nonNegativeInteger"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#nonNegativeInteger"); /// Integer numbers ≤0 pub static ref NON_POSITIVE_INTEGER: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#nonPositiveInteger"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#nonPositiveInteger"); /// Integer numbers >0 pub static ref POSITIVE_INTEGER: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#positiveInteger"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#positiveInteger"); /// Times (hh:mm:ss.sss…) with or without timezone pub static ref TIME: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#time"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#time"); /// -32768…+32767 (16 bit) pub static ref SHORT: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#short"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#short"); /// Character strings (but not all Unicode character strings) pub static ref STRING: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#string"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#string"); /// 0…255 (8 bit) pub static ref UNSIGNED_BYTE: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#unsignedByte"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#unsignedByte"); /// 0…4294967295 (32 bit) pub static ref UNSIGNED_INT: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#unsignedInt"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#unsignedInt"); /// 0…18446744073709551615 (64 bit) pub static ref UNSIGNED_LONG: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#unsignedLong"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#unsignedLong"); /// 0…65535 (16 bit) pub static ref UNSIGNED_SHORT: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#unsignedShort"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#unsignedShort"); /// Duration of time (months and years only) pub static ref YEAR_MONTH_DURATION: NamedNode = - NamedNode::new_from_string("http://www.w3.org/2001/XMLSchema#yearMonthDuration"); + NamedNode::new_unchecked("http://www.w3.org/2001/XMLSchema#yearMonthDuration"); } } diff --git a/lib/src/store/numeric_encoder.rs b/lib/src/store/numeric_encoder.rs index cf5ea1ce..cea44f2f 100644 --- a/lib/src/store/numeric_encoder.rs +++ b/lib/src/store/numeric_encoder.rs @@ -1152,7 +1152,7 @@ impl Decoder for S { Err(format_err!("The default graph tag is not a valid term")) } EncodedTerm::NamedNode { iri_id } => { - Ok(NamedNode::new_from_string(get_required_str(self, iri_id)?).into()) + Ok(NamedNode::new_unchecked(get_required_str(self, iri_id)?).into()) } EncodedTerm::BlankNode { id } => Ok(BlankNode::new_from_unique_id(id).into()), EncodedTerm::StringLiteral { value_id } => { @@ -1171,7 +1171,7 @@ impl Decoder for S { datatype_id, } => Ok(Literal::new_typed_literal( get_required_str(self, value_id)?, - NamedNode::new_from_string(get_required_str(self, datatype_id)?), + NamedNode::new_unchecked(get_required_str(self, datatype_id)?), ) .into()), EncodedTerm::BooleanLiteral(value) => Ok(Literal::from(value).into()), @@ -1200,9 +1200,9 @@ fn get_required_str(lookup: &impl StrLookup, id: u128) -> Result { fn test_encoding() { let mut store = MemoryStrStore::default(); let terms: Vec = vec![ - NamedNode::new_from_string("http://foo.com").into(), - NamedNode::new_from_string("http://bar.com").into(), - NamedNode::new_from_string("http://foo.com").into(), + NamedNode::new_unchecked("http://foo.com").into(), + NamedNode::new_unchecked("http://bar.com").into(), + NamedNode::new_unchecked("http://foo.com").into(), BlankNode::default().into(), Literal::new_simple_literal("foo").into(), Literal::from(true).into(), @@ -1216,7 +1216,7 @@ fn test_encoding() { Literal::new_typed_literal("2020-01-01", xsd::DATE.clone()).into(), Literal::new_typed_literal("01:01:01Z", xsd::TIME.clone()).into(), Literal::new_typed_literal("PT1S", xsd::DURATION.clone()).into(), - Literal::new_typed_literal("-foo", NamedNode::new_from_string("http://foo.com")).into(), + Literal::new_typed_literal("-foo", NamedNode::new_unchecked("http://foo.com")).into(), ]; for term in terms { let encoded = store.encode_term(&term).unwrap();