Skip to content

New work item: crate r2c2_statement #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/CODEOWNER
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@
# Owners of the /dummy work-item
/dummy @pchampin @Tpt # ...

# Owners of the /statement work-item
/statement @pchampin # anyone else welcome, of course

# Owners of another work item
# ...
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

members = [
"dummy",
"statement",
]
resolver = "3"

Expand Down
22 changes: 22 additions & 0 deletions statement/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "r2c2_statement"
version.workspace = true
authors.workspace = true
edition.workspace = true
repository.workspace = true
readme.workspace = true
license-file.workspace = true
keywords.workspace = true

[dependencies]
regex = "1.11.1"

langtag = { version = "0.4.0", optional = true }
oxrdf = { version = "0.2.4", optional = true, features = ["rdf-star"] }
rdf-types = { version = "0.22.5", optional = true }

[lints]
workspace = true

[features]
poc_impl = ["dep:langtag", "dep:oxrdf", "dep:rdf-types"]
96 changes: 96 additions & 0 deletions statement/src/_graph_name.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
use std::borrow::Cow;

use crate::Iri;

/// A trait for [RDF terms] allowed as a [graph name] in an [RDF dataset].
///
/// [RDF terms]: https://www.w3.org/TR/rdf12-concepts/#dfn-rdf-term
/// [graph name]: https://www.w3.org/TR/rdf12-concepts/#dfn-graph-name
/// [RDF dataset]: https://www.w3.org/TR/rdf12-concepts/#dfn-rdf-dataset
pub trait GraphName {
/// Return a [`GraphNameProxy`] representing this graph name.
///
/// [RDF term]: https://www.w3.org/TR/rdf12-concepts/#dfn-rdf-term
fn as_graph_name_proxy(&self) -> GraphNameProxy<'_>;

/// Return the [kind](GraphNameKind) of this graph name.
///
/// # Implementers
/// A default implementation is provided for this method, based on [`GraphName::as_graph_name_proxy`].
/// It may be useful to override it, especially for types where the inner values of [`GraphNameProxy`]
/// are allocated as owned [`Cow<str>`](std::borrow::Cow) rather than borrowed.
fn graph_name_kind(&self) -> GraphNameKind {
match self.as_graph_name_proxy() {
GraphNameProxy::Iri(_) => GraphNameKind::Iri,
GraphNameProxy::BlankNode(_) => GraphNameKind::BlankNode,
}
}

/// Whether this graph_name is [ground](https://https://www.w3.org/TR/rdf12-concepts/#dfn-ground).
fn ground(&self) -> bool {
match self.graph_name_kind() {
GraphNameKind::Iri => true,
GraphNameKind::BlankNode => false,
}
}
}

/// An enum conveying the inner information of a value implementing [`GraphName`].
/// The return type of [`GraphName::as_graph_name_proxy`].
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum GraphNameProxy<'a> {
/// An [IRI](https://www.w3.org/TR/rdf12-concepts/#section-IRIs)
Iri(Iri<'a>),
/// A [blank node](https://www.w3.org/TR/rdf12-concepts/#dfn-blank-node)
///
/// The inner value is an internal [blank node identifier](https://www.w3.org/TR/rdf12-concepts/#dfn-blank-node-identifier).
/// This identifier is not part of RDF's abstract syntax, and only *locally* identifies the blank node.A
///
/// Note that this API does not impose any constraint on blank node identifiers,
/// but concrete syntax usually do, so serializer may alter these identifiers.
BlankNode(Cow<'a, str>),
}

/// An enum representing the different kinds of [RDF terms] that can be [graph name].
/// The return type of [`GraphName::graph_name_kind`].
///
/// [RDF terms]: https://www.w3.org/TR/rdf12-concepts/#dfn-rdf-term
/// [graph name]: https://www.w3.org/TR/rdf12-concepts/#dfn-graph_name
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum GraphNameKind {
/// An [IRI](https://www.w3.org/TR/rdf12-concepts/#section-IRIs)
Iri,
/// A [blank node](https://www.w3.org/TR/rdf12-concepts/#dfn-blank-node)
BlankNode,
}

/// Any reference to a [`GraphName`] also trivially implements [`GraphName`]
/// (as all methods of [`GraphName`] apply to `&self` anyway).
impl<T: GraphName> GraphName for &'_ T {
fn as_graph_name_proxy(&self) -> GraphNameProxy<'_> {
(*self).as_graph_name_proxy()
}

fn graph_name_kind(&self) -> GraphNameKind {
(*self).graph_name_kind()
}

fn ground(&self) -> bool {
(*self).ground()
}
}

/// [`GraphNameProxy`] implements the trait [`GraphName`].
/// This has not particular interest for [`GraphNameProxy`]s obtained from another [`GraphName`]-implementing type,
/// via the [`GraphName::as_graph_name_proxy`] method.
///
/// It can be useful, on the other hand, to provide a straightforward implementation of [`GraphName`]
/// (e.g. for testing or prototyping).
impl GraphName for GraphNameProxy<'_> {
fn as_graph_name_proxy(&self) -> GraphNameProxy<'_> {
match self {
GraphNameProxy::Iri(iri) => GraphNameProxy::Iri(iri.borrowed()),
GraphNameProxy::BlankNode(cow) => GraphNameProxy::BlankNode(Cow::from(cow.as_ref())),
}
}
}
Loading