pub trait TTerm {
    fn kind(&self) -> TermKind;
fn value_raw(&self) -> RawValue<'_>;
fn as_dyn(&self) -> &dyn TTerm; fn value(&self) -> MownStr<'_> { ... }
fn datatype(&self) -> Option<SimpleIri<'_>> { ... }
fn language(&self) -> Option<&str> { ... }
fn is_absolute(&self) -> bool { ... } }
Expand description

Trait for all RDF terms.

Sophia supports 4 kinds of terms: IRI references (absolute or relative), literals, blank nodes and variables. Note that strict RDF does not support relative IRI references nor variables.

Types representing terms, of one or more of the kinds above, can implement this trait and be used with the rest of the Sophia API.

Design considerations

The design of this trait is not as “pure” as it could have been:

  • it merges into a single trait four “kinds” which could arguably be considered as four different abstract types;

  • it is rather opinionated on how implementation should store their data internally, and has a very constrained contract (see below);

  • it relies on the “semi-abstract” methods value_raw, which mostly makes sense for the default implementation of other methods.

These choices were made to allow for efficient implementations of the overall API.

Contract

In addition to the specific contract of each method, any type implementing this trait must uphold the following guarantees:

  • if it implements Hash, it must be consistent with (or, even better, based on) term_hash();

  • if it implements PartialEq, it must be consistent with (or, even better, based on) term_eq();

  • if it implements PartialCmp, it must be consistent with (or, even better, based on) term_cmp;

  • if it implements Borrow<dyn TTerm + 'a> it must have equivalent implementations to term_hash() and term_eq() so that the contract of Borrow upholds with the implementations on dyn TTerm.

[Borrow]<dyn TTerm + 'a>

Implementing Borrow<dyn TTerm + 'a> for a term increases the ergonomics when the type is used as key in a HashSet or similar. It allows to search for keys with any implementation of the TTerm trait, e.g.:

use sophia_term::Term;
use sophia_api::term::{SimpleIri, TTerm as _};

let t: Term<String> = Term::new_iri("http://example.com/test")?;
let mut map = HashSet::new();
map.insert(t);

let iri = SimpleIri::new("http://example.com/", Some("test"))?;
assert!(map.get(iri.as_dyn()).is_some());

Implementation

Besides the contract mentioned above, it should be noted that someone wants to implement Borrow<dyn TTerm + 'a> instead of Borrow<dyn TTerm> for a custom term. The reason is that Rust assumes that every dyn Trait object has a 'static lifetime which means that borrowing dyn TTerm requires borrowing of the value for the 'static lifetime. To remove this assumption implement Borrow<dyn TTerm + 'a> instead, e.g.:

use std::borrow::Borrow;

impl<'a> Borrow<dyn TTerm + 'a> for MyTerm {
    fn borrow(&self) -> &(dyn TTerm + 'a) {
        self
    }
}

Required methods

Returns the kind of this term (IRI, literal, blank node, variable).

Return the “value” of this term, possibly split in two substrings. The second part might only be non-empty if this term is an IRI reference.

See also value.

Note to implementors

The second part of the raw value is intended for some implementations of IRIs, storing both a “namespace” and a “suffix”. For other kinds of term, the second part must always be None.

This method ensures that all implementations of TTerm can be turned into a trait object.

Why is this required?

After all, in most cases, passing &t instead of t.as_dyn() will work just as well.

The reason is that most methods of the API will accept references to terms, as &T where T: TTerm + ?Sized, and such references can not be cast to dyn TTerm (see https://stackoverflow.com/a/57432042/1235487 for more details).

Provided methods

Return the “value” of this term, which depends on its kind:

  • for an IRI reference, its value;
  • for a literal, its lexical value;
  • for a blank node, its local identifier;
  • for a variable, its name.
Performance

The returned MownStr is always borrowed (equivalent to a &str), except for IRI references where this method may allocate a new string (depending on implementations). If this allocation is undesirable, use value_raw instead.

Note to implementors

Should not be overridden; must be consistent with value_raw.

Return the datatype IRI of this term if it is a literal.

NB: all literals have a datatype, even simple literals (whose implicit type is xsd:string) and language tagged strings (whose implicit type is rdf:langString).

Return the language tag of this term if it is a language-tagged literal.

Note to implementors

The default implementation always return None, so unless your type may represent a language-tagged literal, you do not need to override it.

All terms are absolute, except for:

  • relative IRI references,
  • literals whose datatype is a relative IRI reference.

Trait Implementations

Immutably borrows from an owned value. Read more

Formats the value using the given formatter. Read more

Feeds this value into the given Hasher. Read more

Feeds a slice of this type into the given Hasher. Read more

This method returns an Ordering between self and other. Read more

Compares and returns the maximum of two values. Read more

Compares and returns the minimum of two values. Read more

Restrict a value to a certain interval. Read more

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method returns an ordering between self and other values if one exists. Read more

This method tests less than (for self and other) and is used by the < operator. Read more

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more

This method tests greater than (for self and other) and is used by the > operator. Read more

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more

Implementations on Foreign Types

Implementors