use oxrdf::{NamedNode, NamedOrBlankNode, Term, Triple};
use oxttl::{TurtleParser, TurtleSerializer};
pub const IK: &str = "https://ikigai-rs.dev/ns#";
pub const RDF_TYPE: &str = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
pub const RDFS_LABEL: &str = "http://www.w3.org/2000/01/rdf-schema#label";
pub const RDFS_SEE_ALSO: &str = "http://www.w3.org/2000/01/rdf-schema#seeAlso";
pub const PROV_ATTRIBUTED: &str = "http://www.w3.org/ns/prov#wasAttributedTo";
pub const DCT_CREATED: &str = "http://purl.org/dc/terms/created";
pub const DCT_SUBJECT: &str = "http://purl.org/dc/terms/subject";
pub const DCT_CONFORMS_TO: &str = "http://purl.org/dc/terms/conformsTo";
pub const DCT_HAS_PART: &str = "http://purl.org/dc/terms/hasPart";
pub const DCT_IS_PART_OF: &str = "http://purl.org/dc/terms/isPartOf";
pub const DCT_CONTRIBUTOR: &str = "http://purl.org/dc/terms/contributor";
pub const PROV_ACTIVITY: &str = "http://www.w3.org/ns/prov#Activity";
pub const PROV_USED: &str = "http://www.w3.org/ns/prov#used";
pub const PROV_ASSOCIATED: &str = "http://www.w3.org/ns/prov#wasAssociatedWith";
pub const PROV_ENDED: &str = "http://www.w3.org/ns/prov#endedAtTime";
pub const FOAF_PRIMARY_TOPIC: &str = "http://xmlns.com/foaf/0.1/primaryTopic";
pub const FOAF_PERSON: &str = "http://xmlns.com/foaf/0.1/Person";
pub const PROV_SOFTWARE_AGENT: &str = "http://www.w3.org/ns/prov#SoftwareAgent";
pub const PROV_ACTED_FOR: &str = "http://www.w3.org/ns/prov#actedOnBehalfOf";
pub const XSD_DATE_TIME: &str = "http://www.w3.org/2001/XMLSchema#dateTime";
pub const XSD_INTEGER: &str = "http://www.w3.org/2001/XMLSchema#integer";
pub const XSD_STRING: &str = "http://www.w3.org/2001/XMLSchema#string";
pub const SH_NODE_SHAPE: &str = "http://www.w3.org/ns/shacl#NodeShape";
pub const SH_CLOSED: &str = "http://www.w3.org/ns/shacl#closed";
pub const SH_TARGET_CLASS: &str = "http://www.w3.org/ns/shacl#targetClass";
pub fn ik_seq() -> String {
format!("{IK}seq")
}
pub fn ik_supersedes() -> String {
format!("{IK}supersedes")
}
pub fn ik_addressed_to() -> String {
format!("{IK}addressedTo")
}
pub fn ik_offer() -> String {
format!("{IK}offer")
}
pub fn ik_layer_class() -> String {
format!("{IK}Layer")
}
pub fn ik_layer_model() -> String {
format!("{IK}layerModel")
}
pub fn ik_machine() -> String {
format!("{IK}Machine")
}
pub fn ik_collaboration() -> String {
format!("{IK}Collaboration")
}
pub fn node(iri: &str) -> NamedNode {
NamedNode::new(iri).unwrap_or_else(|e| panic!("`{iri}` is not an IRI: {e}"))
}
pub fn parse_turtle(text: &str) -> Result<Vec<Triple>, String> {
TurtleParser::new()
.for_slice(text.as_bytes())
.collect::<Result<Vec<_>, _>>()
.map_err(|e| e.to_string())
}
pub fn to_turtle<'a>(triples: impl IntoIterator<Item = &'a Triple>) -> String {
to_turtle_with(triples, &[])
}
pub fn to_turtle_with<'a>(
triples: impl IntoIterator<Item = &'a Triple>,
extra: &[(&str, &str)],
) -> String {
let mut serializer = TurtleSerializer::new();
for (prefix, ns) in [
("ik", IK),
("prov", "http://www.w3.org/ns/prov#"),
("dcterms", "http://purl.org/dc/terms/"),
("rdfs", "http://www.w3.org/2000/01/rdf-schema#"),
("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"),
("xsd", "http://www.w3.org/2001/XMLSchema#"),
("foaf", "http://xmlns.com/foaf/0.1/"),
]
.into_iter()
.chain(extra.iter().copied())
{
serializer = serializer
.with_prefix(prefix, ns)
.expect("constant prefixes are valid");
}
let mut writer = serializer.for_writer(Vec::new());
for triple in triples {
writer
.serialize_triple(triple)
.expect("writing to a Vec cannot fail");
}
String::from_utf8(writer.finish().expect("writing to a Vec cannot fail"))
.expect("Turtle is UTF-8")
}
pub fn has_blank_node(triple: &Triple) -> bool {
matches!(triple.subject, NamedOrBlankNode::BlankNode(_))
|| matches!(triple.object, Term::BlankNode(_))
}
pub fn subject_iri(subject: &NamedOrBlankNode) -> Option<&str> {
match subject {
NamedOrBlankNode::NamedNode(n) => Some(n.as_str()),
_ => None,
}
}
pub fn object_iri(object: &Term) -> Option<&str> {
match object {
Term::NamedNode(n) => Some(n.as_str()),
_ => None,
}
}