Skip to main content

Crate crdf

Crate crdf 

Source
Expand description

§crdf

Crates.io Docs.rs License GitHub

A CRDT-based RDF graph implementation in Rust, built on top of crdt-graph.

§Overview

crdf provides an RDF graph that can be replicated across multiple nodes using operation-based CRDTs. Each RDF term (IRI, blank node, or literal) maps to a vertex, and each triple becomes a directed edge in the underlying 2P2P-Graph CRDT.

Key properties:

  • Conflict-free — Concurrent additions on different replicas converge automatically.
  • Op-based replication — Operations returned by add_triple / remove_triple can be broadcast and applied on remote replicas via apply_downstream.
  • RDF 1.1 compliant — Literals always carry a datatype IRI; language-tagged literals use rdf:langString; language tags are normalized to lowercase.

§Features

  • RDF term typesRdfTerm::Iri, RdfTerm::BlankNode, RdfTerm::Literal with full accessor API.
  • Typed literalsFrom conversions for bool, i32, i64, f32, f64, &str, and String.
  • XSD constantsXSD_STRING, XSD_INTEGER, XSD_INT, XSD_DOUBLE, XSD_FLOAT, XSD_BOOLEAN.
  • Pattern matchingtriples_matching(subject?, predicate?, object?) with wildcard support.
  • Graph queriessubjects(), predicates(), objects(), triples_for_subject(), and more.
  • N-Triples displayDisplay implementations output valid N-Triples syntax.
  • oxrdf conversion — Convert terms, triples, and whole graphs into oxrdf types.
  • RDF file output — Export a graph to an RDF file (currently N-Triples).
  • Error handling — All fallible operations return Result<_, CrdfError> via thiserror.
  • UUID v7 identifiers — Time-ordered, globally unique IDs for vertices and edges.

§Quick Start

use crdf::{RdfGraph, RdfTerm, Literal};

let mut replica_a = RdfGraph::new();
let mut replica_b = RdfGraph::new();

let alice = RdfTerm::iri("http://example.org/alice");
let bob = RdfTerm::iri("http://example.org/bob");

// Replica A: add triples
let op1 = replica_a
    .add_triple(alice.clone(), "http://xmlns.com/foaf/0.1/name", RdfTerm::literal("Alice"))
    .unwrap();
let op2 = replica_a
    .add_triple(alice.clone(), "http://xmlns.com/foaf/0.1/knows", bob.clone())
    .unwrap();

// Broadcast to Replica B
replica_b.apply_downstream(op1).unwrap();
replica_b.apply_downstream(op2).unwrap();

// Both replicas have converged
assert_eq!(replica_a.len(), 2);
assert_eq!(replica_b.len(), 2);

// Query
let names = replica_b.objects_for_subject_predicate(
    &alice,
    "http://xmlns.com/foaf/0.1/name",
);
assert_eq!(names.len(), 1);

§Typed Literals

use crdf::Literal;

let integer_lit = Literal::new("42").with_datatype("http://www.w3.org/2001/XMLSchema#integer").unwrap();
let lang_lit = Literal::new("hello").with_language("en").unwrap();
let bool_lit = Literal::from(true);
let float_lit = Literal::from(3.14f64);

§Export to RDF File

use crdf::{RdfFileFormat, RdfGraph, RdfTerm};

let mut graph = RdfGraph::new();
graph
    .add_triple(
        RdfTerm::iri("http://example.org/alice"),
        "http://xmlns.com/foaf/0.1/name",
        RdfTerm::literal("Alice"),
    )
    .unwrap();

// Convert to oxrdf internally and write as N-Triples RDF file
graph
    .write_rdf_file("people.nt", RdfFileFormat::NTriples)
    .unwrap();

§API

MethodDescription
RdfGraph::new()Creates an empty RDF graph.
add_triple(s, p, o)Adds a triple (atSource). Returns the operation to broadcast.
remove_triple(s, p, o)Removes a triple (atSource). Returns the operation to broadcast.
apply_downstream(op)Applies an operation received from a remote replica.
contains_triple(s, p, o)Returns true if the triple exists.
triples()Returns all active triples.
triples_matching(s?, p?, o?)Pattern-based triple lookup.
subjects() / predicates() / objects()Unique terms in each position.
to_oxrdf()Converts the graph to oxrdf::Graph.
write_rdf_file(path, format)Writes an RDF file from the graph.
len() / is_empty()Triple count and emptiness check.

§Errors

All fallible operations return Result<_, CrdfError>:

VariantDescription
Graph(TwoPTwoPGraphError)Error from the underlying CRDT graph.
TripleNotFoundThe specified triple was not found.
LiteralSubjectLiterals cannot be used as subjects.
InvalidPredicatePredicates must be non-empty IRIs.
EmptyLanguageTagLanguage tags must be non-empty (BCP 47).
LangStringDatatyperdf:langString cannot be set directly; use with_language().

Modules§

flatbuffers

Structs§

AddEdge
An edge-add operation representing an RDF predicate connecting subject to object.
AddTripleOp
A compound operation representing an RDF triple addition.
AddVertex
A vertex-add operation representing an RDF term in the graph.
Literal
An RDF literal value with a datatype IRI and optional language tag.
RdfGraph
An RDF graph backed by a 2P2P-Graph CRDT.
RemoveEdge
An edge-remove operation. Only references the original add by ID.
RemoveTripleOp
A compound operation representing an RDF triple removal.
RemoveVertex
A vertex-remove operation. Only references the original add by ID.
Triple
An RDF triple (statement) consisting of subject, predicate, and object.
UndoManager
Tracks triple-level operations for undo/redo with CRDT-safe compensating operations.
Uuid
A Universally Unique Identifier (UUID).

Enums§

CrdfError
Errors that can occur when performing operations on an RdfGraph.
RdfFileFormat
RDF file serialization formats supported by RdfGraph::write_rdf_file.
RdfOperation
A high-level RDF operation that can be broadcast to other replicas.
RdfTerm
An RDF term that can appear as a subject or object in a triple.

Constants§

RDF_LANG_STRING
The IRI for rdf:langString, the datatype of language-tagged literals.
XSD_BOOLEAN
The IRI for xsd:boolean.
XSD_DOUBLE
The IRI for xsd:double.
XSD_FLOAT
The IRI for xsd:float.
XSD_INT
The IRI for xsd:int.
XSD_INTEGER
The IRI for xsd:integer.
XSD_STRING
The IRI for xsd:string, the default datatype for plain literals.