Link docs

This commit is contained in:
asonix 2020-05-16 11:09:27 -05:00
parent 00bc74b1bf
commit 38c011be8b

View file

@ -1,3 +1,25 @@
//! Types and traits for dealing with Link attributes
//!
//! ```rust
//! # fn main() -> Result<(), anyhow::Error> {
//! use activitystreams_new::{
//! link::Mention,
//! object::Image,
//! prelude::*,
//! primitives::XsdAnyUri,
//! };
//!
//! let mut mention = Mention::default();
//!
//! mention
//! .set_href("https://example.com".parse()?)
//! .set_hreflang("en".into())
//! .set_rel("link".into())
//! .set_preview(Image::default().into_any_base()?);
//! #
//! # Ok(())
//! # }
//! ```
use crate::{ use crate::{
base::{AsBase, Base, Extends}, base::{AsBase, Base, Extends},
markers, markers,
@ -13,12 +35,33 @@ pub mod kind {
use self::kind::MentionType; use self::kind::MentionType;
/// Implementation trait for deriving Link methods for a type
///
/// Any type implementing AsLink will automatically gain methods provided by LinkExt
pub trait AsLink<Kind>: markers::Link { pub trait AsLink<Kind>: markers::Link {
/// Immutable borrow of Link<Kind>
fn link_ref(&self) -> &Link<Kind>; fn link_ref(&self) -> &Link<Kind>;
/// Mutable borrow of Link<Kind>
fn link_mut(&mut self) -> &mut Link<Kind>; fn link_mut(&mut self) -> &mut Link<Kind>;
} }
/// Helper methods for interacting with Link types
///
/// This trait represents methods valid for any ActivityStreams Link.
///
/// Documentation for the fields related to these methods can be found on the `Link` struct
pub trait LinkExt<Kind>: AsLink<Kind> { pub trait LinkExt<Kind>: AsLink<Kind> {
/// Fetch the href for the current object
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// let mention_href = mention.href();
/// ```
fn href<'a>(&'a self) -> Option<&'a XsdAnyUri> fn href<'a>(&'a self) -> Option<&'a XsdAnyUri>
where where
Kind: 'a, Kind: 'a,
@ -26,20 +69,73 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
self.link_ref().href.as_ref() self.link_ref().href.as_ref()
} }
/// Set the href for the current object
///
/// This overwrites the contents of href
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// mention.set_href("https://example.com".parse()?);
/// # Ok(())
/// # }
/// ```
fn set_href(&mut self, href: XsdAnyUri) -> &mut Self { fn set_href(&mut self, href: XsdAnyUri) -> &mut Self {
self.link_mut().href = Some(href); self.link_mut().href = Some(href);
self self
} }
/// Take the href from the current object, leaving nothing
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// if let Some(href) = mention.take_href() {
/// println!("{:?}", href);
/// }
/// ```
fn take_href(&mut self) -> Option<XsdAnyUri> { fn take_href(&mut self) -> Option<XsdAnyUri> {
self.link_mut().href.take() self.link_mut().href.take()
} }
/// Delete the href from the current object
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// # mention.set_href("https://example.com".parse()?);
/// #
/// use activitystreams_new::prelude::*;
///
/// assert!(mention.href().is_some());
/// mention.delete_href();
/// assert!(mention.href().is_none());
/// # Ok(())
/// # }
/// ```
fn delete_href(&mut self) -> &mut Self { fn delete_href(&mut self) -> &mut Self {
self.link_mut().href = None; self.link_mut().href = None;
self self
} }
/// Fetch the hreflang for the current object
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// let mention_hreflang = mention.hreflang();
/// ```
fn hreflang<'a>(&'a self) -> Option<&'a XsdString> fn hreflang<'a>(&'a self) -> Option<&'a XsdString>
where where
Kind: 'a, Kind: 'a,
@ -47,20 +143,70 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
self.link_ref().hreflang.as_ref() self.link_ref().hreflang.as_ref()
} }
/// Set the hreflang for the current object
///
/// This overwrites the contents of hreflang
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// mention.set_hreflang("en".into());
/// ```
fn set_hreflang(&mut self, hreflang: XsdString) -> &mut Self { fn set_hreflang(&mut self, hreflang: XsdString) -> &mut Self {
self.link_mut().hreflang = Some(hreflang); self.link_mut().hreflang = Some(hreflang);
self self
} }
/// Take the hreflang from the current object, leaving nothing
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// if let Some(hreflang) = mention.take_hreflang() {
/// println!("{:?}", hreflang);
/// }
/// ```
fn take_hreflang(&mut self) -> Option<XsdString> { fn take_hreflang(&mut self) -> Option<XsdString> {
self.link_mut().hreflang.take() self.link_mut().hreflang.take()
} }
/// Delete the hreflang from the current object
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// # mention.set_hreflang("https://example.com".parse()?);
/// #
/// use activitystreams_new::prelude::*;
///
/// assert!(mention.hreflang().is_some());
/// mention.delete_hreflang();
/// assert!(mention.hreflang().is_none());
/// # Ok(())
/// # }
/// ```
fn delete_hreflang(&mut self) -> &mut Self { fn delete_hreflang(&mut self) -> &mut Self {
self.link_mut().hreflang = None; self.link_mut().hreflang = None;
self self
} }
/// Fetch the rel for the current object
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// let mention_rel = mention.rel();
/// ```
fn rel<'a>(&'a self) -> Option<&'a OneOrMany<XsdString>> fn rel<'a>(&'a self) -> Option<&'a OneOrMany<XsdString>>
where where
Kind: 'a, Kind: 'a,
@ -68,11 +214,35 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
self.link_ref().rel.as_ref() self.link_ref().rel.as_ref()
} }
/// Set the rel for the current object
///
/// This overwrites the contents of rel
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// mention.set_rel("link".into());
/// ```
fn set_rel(&mut self, rel: XsdString) -> &mut Self { fn set_rel(&mut self, rel: XsdString) -> &mut Self {
self.link_mut().rel = Some(rel.into()); self.link_mut().rel = Some(rel.into());
self self
} }
/// Set many rels for the current object
///
/// This overwrites the contents of rel
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// mention.set_many_rels(vec!["link".into(), "stylesheet".into()]);
/// ```
fn set_many_rels<I>(&mut self, items: I) -> &mut Self fn set_many_rels<I>(&mut self, items: I) -> &mut Self
where where
I: IntoIterator<Item = XsdString>, I: IntoIterator<Item = XsdString>,
@ -82,6 +252,20 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
self self
} }
/// Add a rel to the current object
///
/// This does not overwrite the contents of rel, only appends an item
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// mention
/// .add_rel("link".into())
/// .add_rel("stylesheet".into());
/// ```
fn add_rel(&mut self, rel: XsdString) -> &mut Self { fn add_rel(&mut self, rel: XsdString) -> &mut Self {
let v = match self.link_mut().rel.take() { let v = match self.link_mut().rel.take() {
Some(mut v) => { Some(mut v) => {
@ -94,15 +278,52 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
self self
} }
/// Take the rel from the current object, leaving nothing
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// if let Some(rel) = mention.take_rel() {
/// println!("{:?}", rel);
/// }
/// ```
fn take_rel(&mut self) -> Option<OneOrMany<XsdString>> { fn take_rel(&mut self) -> Option<OneOrMany<XsdString>> {
self.link_mut().rel.take() self.link_mut().rel.take()
} }
/// Delete the rel from the current object
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// # mention.set_rel("link".into());
/// #
/// use activitystreams_new::prelude::*;
///
/// assert!(mention.rel().is_some());
/// mention.delete_rel();
/// assert!(mention.rel().is_none());
/// ```
fn delete_rel(&mut self) -> &mut Self { fn delete_rel(&mut self) -> &mut Self {
self.link_mut().rel = None; self.link_mut().rel = None;
self self
} }
/// Fetch the height of the current object
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// if let Some(height) = mention.height() {
/// println!("{:?}", height);
/// }
/// ```
fn height<'a>(&'a self) -> Option<&'a XsdNonNegativeInteger> fn height<'a>(&'a self) -> Option<&'a XsdNonNegativeInteger>
where where
Kind: 'a, Kind: 'a,
@ -110,6 +331,18 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
self.link_ref().height.as_ref() self.link_ref().height.as_ref()
} }
/// Set the height for the current object
///
/// This overwrites the contents of height
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// mention.set_height(5);
/// ```
fn set_height<T>(&mut self, height: T) -> &mut Self fn set_height<T>(&mut self, height: T) -> &mut Self
where where
T: Into<XsdNonNegativeInteger>, T: Into<XsdNonNegativeInteger>,
@ -118,15 +351,52 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
self self
} }
/// Take the height of the current object, leaving nothing
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// if let Some(height) = mention.height() {
/// println!("{:?}", height);
/// }
/// ```
fn take_height(&mut self) -> Option<XsdNonNegativeInteger> { fn take_height(&mut self) -> Option<XsdNonNegativeInteger> {
self.link_mut().height.take() self.link_mut().height.take()
} }
/// Delete the height from the current object
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// # mention.set_height(5);
/// #
/// use activitystreams_new::prelude::*;
///
/// assert!(mention.height().is_some());
/// mention.delete_height();
/// assert!(mention.height().is_none());
/// ```
fn delete_height(&mut self) -> &mut Self { fn delete_height(&mut self) -> &mut Self {
self.link_mut().height = None; self.link_mut().height = None;
self self
} }
/// Fetch the width of the current object
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// if let Some(width) = mention.width() {
/// println!("{:?}", width);
/// }
/// ```
fn width<'a>(&'a self) -> Option<&'a XsdNonNegativeInteger> fn width<'a>(&'a self) -> Option<&'a XsdNonNegativeInteger>
where where
Kind: 'a, Kind: 'a,
@ -134,6 +404,18 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
self.link_ref().width.as_ref() self.link_ref().width.as_ref()
} }
/// Set the width for the current object
///
/// This overwrites the contents of width
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// mention.set_width(5);
/// ```
fn set_width<T>(&mut self, width: T) -> &mut Self fn set_width<T>(&mut self, width: T) -> &mut Self
where where
T: Into<XsdNonNegativeInteger>, T: Into<XsdNonNegativeInteger>,
@ -142,10 +424,35 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
self self
} }
/// Take the width of the current object, leaving nothing
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// #
/// use activitystreams_new::prelude::*;
///
/// if let Some(width) = mention.take_width() {
/// println!("{:?}", width);
/// }
/// ```
fn take_width(&mut self) -> Option<XsdNonNegativeInteger> { fn take_width(&mut self) -> Option<XsdNonNegativeInteger> {
self.link_mut().width.take() self.link_mut().width.take()
} }
/// Delete the width from the current object
///
/// ```rust
/// # use activitystreams_new::link::Mention;
/// # let mut mention = Mention::default();
/// # mention.set_width(5);
/// #
/// use activitystreams_new::prelude::*;
///
/// assert!(mention.width().is_some());
/// mention.delete_width();
/// assert!(mention.width().is_none());
/// ```
fn delete_width(&mut self) -> &mut Self { fn delete_width(&mut self) -> &mut Self {
self.link_mut().width = None; self.link_mut().width = None;
self self
@ -154,32 +461,75 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
pub type Mention = Link<MentionType>; pub type Mention = Link<MentionType>;
/// Define all the properties of the Object base type as described by the Activity Streams
/// vocabulary.
///
/// The properties of the Link object are not the properties of the referenced resource, but are
/// provided as hints for rendering agents to understand how to make use of the resource. For
/// example, height and width might represent the desired rendered size of a referenced image,
/// rather than the actual pixel dimensions of the referenced image.
///
/// The target URI of the Link is expressed using the required href property.
///
/// For example, all Objects can contain an image property whose value describes a graphical
/// representation of the containing object. This property will typically be used to provide the
/// URL to an image (e.g. JPEG, GIF or PNG) resource that can be displayed to the user. Any given
/// object might have multiple such visual representations -- multiple screenshots, for instance,
/// or the same image at different resolutions. In Activity Streams 2.0, there are essentially
/// three ways of describing such references.
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize, TypedBuilder)] #[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize, TypedBuilder)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[builder(doc)] #[builder(doc)]
pub struct Link<Kind> { pub struct Link<Kind> {
/// The target resource pointed to by a Link.
///
/// - Range: xsd:anyUri
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(strip_option))] #[builder(default, setter(strip_option))]
href: Option<XsdAnyUri>, pub href: Option<XsdAnyUri>,
/// Hints as to the language used by the target resource.
///
/// Value MUST be a [BCP47] Language-Tag.
///
/// - Range: [BCP47] Language Tag
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(strip_option))] #[builder(default, setter(strip_option))]
hreflang: Option<XsdString>, pub hreflang: Option<XsdString>,
/// A link relation associated with a Link.
///
/// The value MUST conform to both the [HTML5] and [RFC5988] "link relation" definitions.
///
/// In the [HTML5], any string not containing the "space" U+0020, "tab" (U+0009), "LF" (U+000A), "FF" (U+000C), "CR" (U+000D) or "," (U+002C) characters can be used as a valid link relation.
///
/// - Range: [RFC5988] or [HTML5] Link Relation
/// - Functional: false
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(strip_option, into))] #[builder(default, setter(strip_option, into))]
rel: Option<OneOrMany<XsdString>>, pub rel: Option<OneOrMany<XsdString>>,
/// On a Link, specifies a hint as to the rendering height in device-independent pixels of the linked resource.
///
/// - Range: xsd:nonNegativeInteger
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(strip_option, into))] #[builder(default, setter(strip_option, into))]
height: Option<XsdNonNegativeInteger>, pub height: Option<XsdNonNegativeInteger>,
/// On a Link, specifies a hint as to the rendering width in device-independent pixels of the linked resource.
///
/// Range: xsd:nonNegativeInteger
/// Functional: true
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(strip_option, into))] #[builder(default, setter(strip_option, into))]
width: Option<XsdNonNegativeInteger>, pub width: Option<XsdNonNegativeInteger>,
/// Base fields and unparsed json ends up here
#[serde(flatten)] #[serde(flatten)]
inner: Base<Kind>, pub inner: Base<Kind>,
} }
impl<Kind> Link<Kind> { impl<Kind> Link<Kind> {