astreams: Implement entity processing and Entity.preview

This commit is contained in:
Steffo 2024-12-30 02:50:04 +01:00
parent 678daac2eb
commit 70053021a5
Signed by: steffo
GPG key ID: 5ADA3868646C3FC0
3 changed files with 63 additions and 7 deletions

View file

@ -6,11 +6,11 @@ use json_ld::Direction;
use json_ld::object::Any; use json_ld::object::Any;
use json_ld::syntax::LangTagBuf; use json_ld::syntax::LangTagBuf;
use mediatype::MediaType; use mediatype::MediaType;
use crate::activitystreams::StreamsLink; use crate::activitystreams::{StreamsEntity, StreamsLink};
pub type LangTriple = (String, Option<LangTagBuf>, Option<Direction>); pub type LangTriple = (String, Option<LangTagBuf>, Option<Direction>);
pub trait StreamsJsonLD { pub trait StreamsJsonLD<Entity> {
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_iter_value_langstring(&self, id: &Iri) -> impl Iterator<Item = AResult<LangTriple>>;
@ -19,9 +19,10 @@ pub trait StreamsJsonLD {
fn jsonld_any_value_langtag(&self, id: &Iri) -> Option<AResult<LangTagBuf>>; fn jsonld_any_value_langtag(&self, id: &Iri) -> Option<AResult<LangTagBuf>>;
fn jsonld_any_value_u32(&self, id: &Iri) -> Option<AResult<u32>>; fn jsonld_any_value_u32(&self, id: &Iri) -> Option<AResult<u32>>;
fn jsonld_any_value_u64(&self, id: &Iri) -> Option<AResult<u64>>; fn jsonld_any_value_u64(&self, id: &Iri) -> Option<AResult<u64>>;
fn jsonld_iter_node_entity(&self, id: &Iri) -> impl Iterator<Item = AResult<Entity>>;
} }
impl StreamsJsonLD for &json_ld::Node { impl StreamsJsonLD<json_ld::Node> for json_ld::Node {
fn jsonld_any_value_string(&self, id: &Iri) -> Option<AResult<String>> { fn jsonld_any_value_string(&self, id: &Iri) -> Option<AResult<String>> {
let property = match self.properties.get_any(&id) { let property = match self.properties.get_any(&id) {
None => return None, None => return None,
@ -222,9 +223,31 @@ impl StreamsJsonLD for &json_ld::Node {
Some(Ok(r#u64)) Some(Ok(r#u64))
} }
fn jsonld_iter_node_entity(&self, id: &Iri) -> impl Iterator<Item = AResult<json_ld::Node>> {
let properties = self.properties.get(&id);
let nodes = properties.map(|v| v
.as_node()
.ok_or(anyhow!("Couldn't process property as JSON-LD node"))
.map(|v| v
.clone()
)
);
nodes
}
} }
impl StreamsLink for &json_ld::Node { impl StreamsEntity<json_ld::Node> for json_ld::Node {
fn activitystreams_previews(&self) -> impl Iterator<Item = AResult<json_ld::Node>> {
self.jsonld_iter_node_entity(
iri!("https://www.w3.org/ns/activitystreams#preview")
)
}
}
impl StreamsLink<json_ld::Node> for json_ld::Node {
fn activitystreams_href(&self) -> Option<AResult<String>> { fn activitystreams_href(&self) -> Option<AResult<String>> {
self.jsonld_any_node_string( self.jsonld_any_node_string(
iri!("https://www.w3.org/ns/activitystreams#href") iri!("https://www.w3.org/ns/activitystreams#href")

View file

@ -18,13 +18,23 @@ use mediatype::MediaType;
pub mod jsonld; pub mod jsonld;
/// Something that is either a [`StreamsObject`] or a [`StreamsLink`].
pub trait StreamsEntity<Preview> {
fn activitystreams_previews(&self) -> impl Iterator<Item = AResult<Preview>>;
}
/// Something that can be considered a `https://www.w3.org/ns/activitystreams#Object`. /// Something that can be considered a `https://www.w3.org/ns/activitystreams#Object`.
pub trait StreamsObject { pub trait StreamsObject<Preview> where
Self: StreamsEntity<Preview>,
{
} }
/// Something that can be considered a `https://www.w3.org/ns/activitystreams#Link`. /// Something that can be considered a `https://www.w3.org/ns/activitystreams#Link`.
pub trait StreamsLink { pub trait StreamsLink<Preview> where
Self: StreamsEntity<Preview>,
Preview: StreamsEntity<Preview>,
{
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

View file

@ -1,6 +1,5 @@
use json_ld::syntax::LangTagBuf; use json_ld::syntax::LangTagBuf;
use acrate_astreams::activitystreams::jsonld::LangTriple; use acrate_astreams::activitystreams::jsonld::LangTriple;
use acrate_astreams::activitystreams::StreamsLink;
macro_rules! test_example { macro_rules! test_example {
($modname:ident, $filename:literal) => { ($modname:ident, $filename:literal) => {
@ -383,3 +382,27 @@ async fn test_link_width() {
assert_eq!(width, 100u64) assert_eq!(width, 100u64)
} }
#[tokio::test]
async fn test_link_preview() {
let doc = e102::expand().await;
let node = doc.main_node()
.expect("Main node was not found");
let previews: Vec<json_ld::Node> = {
use acrate_astreams::activitystreams::StreamsEntity;
node.activitystreams_previews()
.map(|v| v
.expect("Property `preview` failed to process")
)
.collect()
};
let mut previews = previews.into_iter();
let _preview = previews.next().expect("Expected `preview` [0] to be present");
// TODO: More tests when StreamsObject is implemented
}