2026-08-20 20:43:18 -04:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
use std::fmt::Display;
|
2026-08-26 20:43:01 -04:00
|
|
|
use oxigraph::model::{Graph, Literal, NamedNode, NamedNodeRef, NamedOrBlankNode, Term, TermRef, Triple};
|
2026-08-20 20:43:18 -04:00
|
|
|
use oxilangtag::LanguageTag;
|
2026-08-26 19:44:18 -04:00
|
|
|
use url::Url;
|
2026-08-20 20:43:18 -04:00
|
|
|
use gl_search::Schema;
|
|
|
|
|
use crate::language::LanguageCondition;
|
2026-08-12 14:11:47 -04:00
|
|
|
use crate::vocab;
|
|
|
|
|
|
2026-08-20 20:43:18 -04:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2026-08-12 14:11:47 -04:00
|
|
|
pub enum Class {
|
|
|
|
|
RdfProperty = 0,
|
|
|
|
|
RdfsClass = 1,
|
|
|
|
|
SkosConcept = 2,
|
|
|
|
|
Work = 10001,
|
|
|
|
|
Person = 10004,
|
|
|
|
|
CorporateBody = 10005,
|
|
|
|
|
Expression = 10006,
|
|
|
|
|
Manifestation = 10007,
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-20 20:43:18 -04:00
|
|
|
impl Display for Class {
|
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
match self {
|
|
|
|
|
Class::RdfProperty => f.write_str("RDF Property"),
|
|
|
|
|
Class::RdfsClass => f.write_str("RDFS Class"),
|
|
|
|
|
Class::SkosConcept => f.write_str("SKOS Concept"),
|
|
|
|
|
Class::Work => f.write_str("Work"),
|
|
|
|
|
Class::Person => f.write_str("Person"),
|
|
|
|
|
Class::CorporateBody => f.write_str("Corporate Body"),
|
|
|
|
|
Class::Expression => f.write_str("Expression"),
|
|
|
|
|
Class::Manifestation => f.write_str("Manifestation"),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-12 14:11:47 -04:00
|
|
|
impl Class {
|
2026-08-20 20:43:18 -04:00
|
|
|
pub const ALL: &[Class] = &[
|
|
|
|
|
Class::RdfProperty,
|
|
|
|
|
Class::RdfsClass,
|
|
|
|
|
Class::SkosConcept,
|
|
|
|
|
Class::Work,
|
|
|
|
|
Class::Person,
|
|
|
|
|
Class::CorporateBody,
|
|
|
|
|
Class::Expression,
|
|
|
|
|
Class::Manifestation,
|
|
|
|
|
];
|
|
|
|
|
|
2026-08-26 19:44:18 -04:00
|
|
|
pub const CREATABLE: &[Class] = &[
|
|
|
|
|
Class::Work,
|
|
|
|
|
Class::Person,
|
|
|
|
|
Class::CorporateBody,
|
|
|
|
|
Class::Expression,
|
|
|
|
|
Class::Manifestation,
|
|
|
|
|
];
|
|
|
|
|
|
2026-08-12 14:11:47 -04:00
|
|
|
pub fn to_named_node(&self) -> NamedNodeRef<'_> {
|
|
|
|
|
match self {
|
|
|
|
|
Class::RdfProperty => vocab::rdf::PROPERTY,
|
|
|
|
|
Class::RdfsClass => vocab::rdfs::CLASS,
|
|
|
|
|
Class::SkosConcept => vocab::skos::CONCEPT,
|
|
|
|
|
Class::Work => vocab::rdac::WORK,
|
|
|
|
|
Class::Person => vocab::rdac::PERSON,
|
|
|
|
|
Class::CorporateBody => vocab::rdac::CORPORATE_BODY,
|
|
|
|
|
Class::Expression => vocab::rdac::EXPRESSION,
|
|
|
|
|
Class::Manifestation => vocab::rdac::MANIFESTATION,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn try_from_named_node<'a>(node: impl Into<NamedNodeRef<'a>>) -> Option<Self> {
|
|
|
|
|
let node = node.into();
|
|
|
|
|
match node {
|
|
|
|
|
vocab::rdf::PROPERTY => Some(Class::RdfProperty),
|
|
|
|
|
vocab::rdfs::CLASS => Some(Class::RdfsClass),
|
|
|
|
|
vocab::skos::CONCEPT => Some(Class::SkosConcept),
|
|
|
|
|
vocab::rdac::WORK => Some(Class::Work),
|
|
|
|
|
vocab::rdac::PERSON => Some(Class::Person),
|
|
|
|
|
vocab::rdac::CORPORATE_BODY => Some(Class::CorporateBody),
|
|
|
|
|
vocab::rdac::EXPRESSION => Some(Class::Expression),
|
|
|
|
|
vocab::rdac::MANIFESTATION => Some(Class::Manifestation),
|
|
|
|
|
_ => None,
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-20 20:43:18 -04:00
|
|
|
|
2026-08-24 21:44:23 -04:00
|
|
|
pub fn fields(&self, language: LanguageTag<String>) -> Vec<(gl_search::Field, String)> {
|
2026-08-20 20:43:18 -04:00
|
|
|
match self {
|
|
|
|
|
Class::RdfProperty => vec![
|
|
|
|
|
(Schema::field("label", Some(language.primary_language())), String::from("Label")),
|
|
|
|
|
(Schema::field("definition", Some(language.primary_language())), String::from("Definition")),
|
|
|
|
|
],
|
|
|
|
|
Class::RdfsClass => vec![
|
|
|
|
|
(Schema::field("label", Some(language.primary_language())), String::from("Label")),
|
|
|
|
|
(Schema::field("definition", Some(language.primary_language())), String::from("Definition")),
|
|
|
|
|
],
|
|
|
|
|
Class::SkosConcept => vec![
|
|
|
|
|
(Schema::field("label", Some(language.primary_language())), String::from("Label")),
|
|
|
|
|
(Schema::field("definition", Some(language.primary_language())), String::from("Definition")),
|
|
|
|
|
],
|
|
|
|
|
Class::Work => vec![
|
|
|
|
|
(Schema::field("title", Some(language.primary_language())), String::from("Title")),
|
|
|
|
|
],
|
|
|
|
|
Class::Person => vec![
|
|
|
|
|
(Schema::field("given_name", Some(language.primary_language())), String::from("Given Name")),
|
|
|
|
|
(Schema::field("surname", Some(language.primary_language())), String::from("Surname")),
|
|
|
|
|
],
|
|
|
|
|
Class::CorporateBody => vec![
|
|
|
|
|
(Schema::field("corporate_body", Some(language.primary_language())), String::from("Corporate Body")),
|
|
|
|
|
],
|
|
|
|
|
Class::Expression => vec![
|
|
|
|
|
(Schema::field("title", Some(language.primary_language())), String::from("Title")),
|
|
|
|
|
],
|
|
|
|
|
Class::Manifestation => vec![
|
|
|
|
|
(Schema::field("title", Some(language.primary_language())), String::from("Title")),
|
|
|
|
|
],
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-26 19:44:18 -04:00
|
|
|
|
|
|
|
|
pub fn next_url(&self) -> Option<Url> {
|
|
|
|
|
match self {
|
|
|
|
|
Class::Work => Some(Url::parse("http://fedora.quill.lan/rest/#Work").unwrap()),
|
2026-08-26 20:43:01 -04:00
|
|
|
Class::Person => Some(Url::parse("http://fedora.quill.lan/rest/#Agent").unwrap()),
|
|
|
|
|
Class::CorporateBody => Some(Url::parse("http://fedora.quill.lan/rest/#Agent").unwrap()),
|
|
|
|
|
Class::Expression => Some(Url::parse("http://fedora.quill.lan/rest/#Expression").unwrap()),
|
|
|
|
|
Class::Manifestation => Some(Url::parse("http://fedora.quill.lan/rest/#Manifestation").unwrap()),
|
2026-08-26 19:44:18 -04:00
|
|
|
_ => None,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn template(&self, subject: NamedNode) -> Graph {
|
2026-08-26 20:43:01 -04:00
|
|
|
let empty_english_string_term = Term::Literal(Literal::new_language_tagged_literal_unchecked("", "en"));
|
|
|
|
|
let empty_string_term = Term::Literal(Literal::new_simple_literal(""));
|
|
|
|
|
let empty_node = NamedNode::new_unchecked("");
|
|
|
|
|
let hash_node = NamedNode::new_unchecked("#");
|
2026-08-26 19:44:18 -04:00
|
|
|
|
|
|
|
|
match self {
|
|
|
|
|
Class::RdfProperty => Graph::new(),
|
|
|
|
|
Class::RdfsClass => Graph::new(),
|
|
|
|
|
Class::SkosConcept => Graph::new(),
|
|
|
|
|
Class::Work => Graph::from_iter([
|
2026-08-26 20:43:01 -04:00
|
|
|
Triple::new(NamedOrBlankNode::NamedNode(subject), vocab::rdawd::TITLE_OF_WORK, empty_english_string_term)
|
2026-08-26 19:44:18 -04:00
|
|
|
]),
|
|
|
|
|
Class::Person => Graph::from_iter([
|
2026-08-26 20:43:01 -04:00
|
|
|
Triple::new(NamedOrBlankNode::NamedNode(subject.clone()), vocab::rdaad::GIVEN_NAME, empty_english_string_term.clone()),
|
|
|
|
|
Triple::new(NamedOrBlankNode::NamedNode(subject.clone()), vocab::rdaad::SURNAME, empty_english_string_term),
|
|
|
|
|
Triple::new(NamedOrBlankNode::NamedNode(subject.clone()), vocab::rdaao::IDENTIFIER_FOR_PERSON, Term::NamedNode(hash_node.clone())),
|
|
|
|
|
Triple::new(NamedOrBlankNode::NamedNode(hash_node.clone()), vocab::rdano::SCHEME_OF_NOMEN, Term::NamedNode(empty_node)),
|
|
|
|
|
Triple::new(NamedOrBlankNode::NamedNode(subject.clone()), vocab::rdand::NOMEN_STRING, empty_string_term),
|
2026-08-26 19:44:18 -04:00
|
|
|
]),
|
|
|
|
|
Class::CorporateBody => Graph::new(),
|
|
|
|
|
Class::Expression => Graph::new(),
|
|
|
|
|
Class::Manifestation => Graph::new(),
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-12 14:11:47 -04:00
|
|
|
}
|