astreams: Yet another attempt at reasonable mapping

This commit is contained in:
Steffo 2024-12-24 17:26:49 +01:00
parent f756e10557
commit 829396846e
Signed by: steffo
GPG key ID: 5ADA3868646C3FC0
4 changed files with 151 additions and 7 deletions

View file

@ -13,12 +13,18 @@ categories = ["web-programming"]
iref = "3.2.2" iref = "3.2.2"
json-ld = { version = "0.21.1", features = ["serde", "reqwest"] } json-ld = { version = "0.21.1", features = ["serde", "reqwest"] }
log = "0.4.22" log = "0.4.22"
anyhow = "1.0.95"
serde = { version = "1.0.214", features = ["derive"] } serde = { version = "1.0.214", features = ["derive"] }
serde_json = "1.0.132" serde_json = "1.0.132"
static-iref = "3.0.0" static-iref = "3.0.0"
thiserror = "2.0.3" thiserror = "2.0.3"
mediatype = { version = "0.19.18", features = ["serde"] }
language-tags = { version = "0.3.2", features = ["serde"] }
[dev-dependencies] [dev-dependencies]
tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread"] }
tokio-test = "0.4.4" tokio-test = "0.4.4"
[lints.clippy]
tabs-in-doc-comments = "allow"
let-and-return = "allow"

View file

@ -1,6 +0,0 @@
//! Struct definitions for ActivityStreams Core and Extended Types.
//!
//! # Specification
//!
//! - <https://www.w3.org/TR/activitystreams-vocabulary/>
//!

View file

@ -0,0 +1,109 @@
use anyhow::{anyhow, Error};
use static_iref::iri;
use anyhow::Result as AResult;
use iref::Iri;
use mediatype::MediaType;
use crate::activitystreams::StreamsLink;
pub trait StreamsJsonLD {
fn get_one_str(&self, id: &Iri) -> Option<AResult<String>>;
fn get_multiple_str(&self, id: &Iri) -> impl Iterator<Item = AResult<String>>;
fn get_one_mediatype(&self, id: &Iri) -> Option<AResult<MediaType>>;
}
impl StreamsJsonLD for &json_ld::Node {
fn get_one_str(&self, id: &Iri) -> Option<AResult<String>> {
let property = match self.properties.get_any(&id) {
None => return None,
Some(property) => property,
};
let value = match property.as_value() {
None => return Some(Err(anyhow!("Couldn't process property as JSON-LD value"))),
Some(value) => value,
};
let r#str = match value.as_str() {
None => return Some(Err(anyhow!("Couldn't process property as JSON-LD string"))),
Some(string) => string
};
let string = r#str.to_string();
Some(Ok(string))
}
fn get_multiple_str(&self, id: &Iri) -> impl Iterator<Item = AResult<String>> {
let properties = self.properties.get(&id);
let values = properties.map(|v| v
.as_value()
.ok_or(anyhow!("Couldn't process property as JSON-LD value"))
);
let strs = values.flat_map(|v| v
.map(|v| v
.as_str()
.ok_or(anyhow!("Couldn't process property as JSON-LD string"))
)
);
let strings = strs.map(|v| v
.map(|v| v
.to_string()
)
);
strings
}
fn get_one_mediatype(&self, id: &Iri) -> Option<AResult<MediaType>> {
let property = match self.properties.get_any(&id) {
None => return None,
Some(property) => property,
};
let value = match property.as_value() {
None => return Some(Err(anyhow!("Couldn't process property as JSON-LD value"))),
Some(value) => value,
};
let string = match value.as_str() {
None => return Some(Err(anyhow!("Couldn't process property as JSON-LD string"))),
Some(string) => string
};
let mediatype = match MediaType::parse(string) {
Err(e) => return Some(Err(Error::from(e).context("Couldn't parse property as MIME media type"))),
Ok(mediatype) => mediatype,
};
Some(Ok(mediatype))
}
}
impl StreamsLink for &json_ld::Node {
fn streams_href(&self) -> Option<AResult<String>> {
self.get_one_str(
iri!("https://www.w3.org/ns/activitystreams#href")
)
}
fn streams_rel(&self) -> impl Iterator<Item = AResult<String>> {
self.get_multiple_str(
iri!("https://www.w3.org/ns/activitystreams#rel")
)
}
fn streams_media_type(&self) -> Option<AResult<MediaType>> {
self.get_one_mediatype(
iri!("https://www.w3.org/ns/activitystreams#mediaType")
)
}
/*
fn streams_name(&self) -> impl Iterator<Item=AResult<(Option<LanguageTag>, String)>> {
todo!()
}
*/
}

View file

@ -0,0 +1,35 @@
//! Struct definitions for ActivityStreams Core and Extended Types.
//!
//! # Functional
//!
//! > Properties marked as being "Functional" can have only one value.
//! >
//! > Items not marked as "Functional" can have multiple values.
//!
//! # Specification
//!
//! - <https://www.w3.org/TR/activitystreams-vocabulary/>
//!
use anyhow::Result as AResult;
use mediatype::MediaType;
pub mod jsonld;
/// Something that can be considered a `https://www.w3.org/ns/activitystreams#Object`.
pub trait StreamsObject {
}
/// Something that can be considered a `https://www.w3.org/ns/activitystreams#Link`.
pub trait StreamsLink {
fn streams_href(&self) -> Option<AResult<String>>;
fn streams_rel(&self) -> impl Iterator<Item = AResult<String>>;
fn streams_media_type(&self) -> Option<AResult<MediaType>>;
/*
fn streams_name(&self) -> impl Iterator<Item = AResult<(LanguageTag, String)>>;
*/
}