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
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);
|