astreams: Implement langString processing and Link.name

This commit is contained in:
Steffo 2024-12-30 01:37:25 +01:00
parent 71485b50af
commit 1ff33fcbdb
Signed by: steffo
GPG key ID: 5ADA3868646C3FC0
3 changed files with 95 additions and 11 deletions

View file

@ -2,13 +2,18 @@ use anyhow::{anyhow, Error};
use static_iref::iri; use static_iref::iri;
use anyhow::Result as AResult; use anyhow::Result as AResult;
use iref::Iri; use iref::Iri;
use json_ld::Direction;
use json_ld::object::Any; use json_ld::object::Any;
use json_ld::syntax::LangTagBuf;
use mediatype::MediaType; use mediatype::MediaType;
use crate::activitystreams::StreamsLink; use crate::activitystreams::StreamsLink;
pub type LangTriple = (String, Option<LangTagBuf>, Option<Direction>);
pub trait StreamsJsonLD { pub trait StreamsJsonLD {
fn jsonld_any_value_string(&self, id: &Iri) -> Option<AResult<String>>; fn jsonld_any_value_string(&self, id: &Iri) -> Option<AResult<String>>;
fn jsonld_iter_value_string(&self, id: &Iri) -> impl Iterator<Item = AResult<String>>; fn jsonld_iter_value_string(&self, id: &Iri) -> impl Iterator<Item = AResult<String>>;
fn jsonld_iter_value_langstring(&self, id: &Iri) -> impl Iterator<Item = AResult<LangTriple>>;
fn jsonld_any_value_mediatype(&self, id: &Iri) -> Option<AResult<MediaType>>; fn jsonld_any_value_mediatype(&self, id: &Iri) -> Option<AResult<MediaType>>;
fn jsonld_any_node_string(&self, id: &Iri) -> Option<AResult<String>>; fn jsonld_any_node_string(&self, id: &Iri) -> Option<AResult<String>>;
} }
@ -59,6 +64,43 @@ impl StreamsJsonLD for &json_ld::Node {
strings strings
} }
fn jsonld_iter_value_langstring(&self, id: &Iri) -> impl Iterator<Item = AResult<LangTriple>> {
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 values = values.flat_map(|v| v
.map(|v| {
let string = v
.as_str()
.ok_or(anyhow!("Expected property to be a langString, but no string was obtained"))?
.to_string();
let lang = v
.language()
.map(|l| l
.as_well_formed()
.ok_or(anyhow!("Expected property to have a valid language tag, but got an invalid one instead"))
);
let lang = match lang {
None => None,
Some(Ok(lang)) => Some(lang.to_owned()),
Some(Err(err)) => return Err(err),
};
let direction = v.direction();
Ok((string, lang, direction))
})
);
values
}
fn jsonld_any_value_mediatype(&self, id: &Iri) -> Option<AResult<MediaType>> { fn jsonld_any_value_mediatype(&self, id: &Iri) -> Option<AResult<MediaType>> {
let property = match self.properties.get_any(&id) { let property = match self.properties.get_any(&id) {
None => return None, None => return None,
@ -112,7 +154,7 @@ impl StreamsLink for &json_ld::Node {
) )
} }
fn activitystreams_rel_lenient(&self) -> impl Iterator<Item = AResult<String>> { fn activitystreams_rels_lenient(&self) -> impl Iterator<Item = AResult<String>> {
self.jsonld_iter_value_string( self.jsonld_iter_value_string(
iri!("https://www.w3.org/ns/activitystreams#rel") iri!("https://www.w3.org/ns/activitystreams#rel")
) )
@ -124,9 +166,9 @@ impl StreamsLink for &json_ld::Node {
) )
} }
/* fn activitystreams_names(&self) -> impl Iterator<Item = AResult<LangTriple>> {
fn activitystreams_name(&self) -> impl Iterator<Item=AResult<(Option<LanguageTag>, String)>> { self.jsonld_iter_value_langstring(
todo!() iri!("https://www.w3.org/ns/activitystreams#name")
)
} }
*/
} }

View file

@ -12,6 +12,8 @@
//! //!
use anyhow::Result as AResult; use anyhow::Result as AResult;
use json_ld::Direction;
use json_ld::syntax::LangTagBuf;
use mediatype::MediaType; use mediatype::MediaType;
pub mod jsonld; pub mod jsonld;
@ -26,11 +28,9 @@ pub trait StreamsLink {
fn activitystreams_href(&self) -> Option<AResult<String>>; fn activitystreams_href(&self) -> Option<AResult<String>>;
// FIXME: This accepts any kind of string, and does not filter to HTML link relations // FIXME: This accepts any kind of string, and does not filter to HTML link relations
fn activitystreams_rel_lenient(&self) -> impl Iterator<Item = AResult<String>>; fn activitystreams_rels_lenient(&self) -> impl Iterator<Item = AResult<String>>;
fn activitystreams_mediatype(&self) -> Option<AResult<MediaType>>; fn activitystreams_mediatype(&self) -> Option<AResult<MediaType>>;
/* fn activitystreams_names(&self) -> impl Iterator<Item = AResult<(String, Option<LangTagBuf>, Option<Direction>)>>;
fn streams_name(&self) -> impl Iterator<Item = AResult<(LanguageTag, String)>>;
*/
} }

View file

@ -1,4 +1,6 @@
use acrate_astreams::activitystreams::StreamsLink; use json_ld::Direction;
use json_ld::syntax::LangTagBuf;
use acrate_astreams::activitystreams::jsonld::LangTriple;
macro_rules! test_example { macro_rules! test_example {
($modname:ident, $filename:literal) => { ($modname:ident, $filename:literal) => {
@ -233,7 +235,7 @@ async fn test_link_rel() {
let mut rels = { let mut rels = {
use acrate_astreams::activitystreams::StreamsLink; use acrate_astreams::activitystreams::StreamsLink;
node.activitystreams_rel_lenient() node.activitystreams_rels_lenient()
.map(|v| v .map(|v| v
.expect("Property `rel` failed to process") .expect("Property `rel` failed to process")
) )
@ -267,3 +269,43 @@ async fn test_link_media_type() {
assert_eq!(href, mediatype::media_type!(TEXT/HTML)); assert_eq!(href, mediatype::media_type!(TEXT/HTML));
} }
#[tokio::test]
async fn test_link_name_value() {
let doc = e117::expand().await;
let node = doc.main_node()
.expect("Main node was not found");
let names: Vec<LangTriple> = {
use acrate_astreams::activitystreams::StreamsLink;
node.activitystreams_names()
.map(|v| v
.expect("Property `name` failed to process")
)
.collect()
};
println!("{names:#?}");
}
#[tokio::test]
async fn test_link_name_lang() {
let doc = e118::expand().await;
let node = doc.main_node()
.expect("Main node was not found");
let names: Vec<LangTriple> = {
use acrate_astreams::activitystreams::StreamsLink;
node.activitystreams_names()
.map(|v| v
.expect("Property `name` failed to process")
)
.collect()
};
println!("{names:#?}");
}