You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
3.4 KiB
Rust

use iref::IriBuf;
use mime::Mime;
use rdf_types::vocabulary::IriIndex;
use rdf_types::Vocabulary;
use std::fmt;
use crate::ap::trans::{matches_type, ApDocument, DebugApub, ParseApub, PropHelper, RawObject};
use crate::ap::vocab::Ids;
pub enum Link {
Link(BaseLink),
Mention(Mention),
}
impl<V: Vocabulary<Iri = IriIndex>> ParseApub<V> for Link {
fn parse_apub(obj: &RawObject, vocab: &V, ids: &Ids) -> Option<Self> {
BaseLink::parse_apub(obj, vocab, ids)
.map(Self::Link)
.or_else(|| Mention::parse_apub(obj, vocab, ids).map(Self::Mention))
}
}
impl DebugApub for Link {
fn apub_class_name(&self) -> &str {
match self {
Link::Link(link) => link.apub_class_name(),
Link::Mention(mention) => mention.apub_class_name(),
}
}
fn debug_apub(&self, f: &mut fmt::Formatter, depth: usize) -> fmt::Result {
match self {
Link::Link(link) => link.debug_apub(f, depth),
Link::Mention(mention) => mention.debug_apub(f, depth),
}
}
fn debug_apub_members(&self, f: &mut fmt::Formatter, depth: usize) -> fmt::Result {
match self {
Link::Link(link) => link.debug_apub_members(f, depth),
Link::Mention(mention) => mention.debug_apub_members(f, depth),
}
}
}
pub struct BaseLink {
pub id: Option<IriBuf>,
pub href: Option<String>,
pub rel: Option<String>,
pub media_type: Option<Mime>,
pub name: Option<String>, // TODO: this could be a langString
pub hreflang: Option<String>,
pub height: Option<u32>,
pub width: Option<u32>,
pub preview: Option<Box<ApDocument>>,
}
impl<V: Vocabulary<Iri = IriIndex>> ParseApub<V> for BaseLink {
fn parse_apub(obj: &RawObject, vocab: &V, ids: &Ids) -> Option<Self> {
matches_type(obj, &ids.apub.link.link)?;
unsafe { Self::_parse_apub_unchecked(obj, vocab, ids) }
}
unsafe fn _parse_apub_unchecked(obj: &RawObject, vocab: &V, ids: &Ids) -> Option<Self> {
let ph = PropHelper::new(obj, vocab, ids)?;
let prop_ids = &ids.apub.property;
Some(Self {
id: obj
.id()
.and_then(|id| id.as_iri())
.and_then(|idx| vocab.iri(idx))
.map(|iri| iri.to_owned()),
href: ph.parse_prop(&prop_ids.href),
rel: ph.parse_prop(&prop_ids.rel),
media_type: ph.parse_prop(&prop_ids.media_type),
name: ph.parse_prop(&prop_ids.name),
hreflang: ph.parse_prop(&prop_ids.hreflang),
height: ph.parse_prop(&prop_ids.height),
width: ph.parse_prop(&prop_ids.width),
preview: ph.parse_prop_box(&prop_ids.preview),
})
}
}
impl DebugApub for BaseLink {
fn apub_class_name(&self) -> &str {
"Link"
}
fn debug_apub_members(&self, f: &mut fmt::Formatter, depth: usize) -> fmt::Result {
ap_display_prop!(self, f, href, depth)?;
ap_display_prop!(self, f, rel, depth)?;
ap_display_prop!(self, f, media_type, depth)?;
ap_display_prop!(self, f, name, depth)?;
ap_display_prop!(self, f, hreflang, depth)?;
ap_display_prop!(self, f, height, depth)?;
ap_display_prop!(self, f, width, depth)?;
ap_display_prop_box!(self, f, preview, depth)
}
}
ap_empty_child_impl!(Mention, BaseLink, apub, link, mention);