Link docs

This commit is contained in:
asonix 2020-05-16 11:09:27 -05:00
parent 00bc74b1bf
commit 38c011be8b
1 changed files with 356 additions and 6 deletions

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::{
base::{AsBase, Base, Extends},
markers,
@ -13,12 +35,33 @@ pub mod kind {
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 {
/// Immutable borrow of Link<Kind>
fn link_ref(&self) -> &Link<Kind>;
/// Mutable borrow of 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> {
/// 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>
where
Kind: 'a,
@ -26,20 +69,73 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
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 {
self.link_mut().href = Some(href);
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> {
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 {
self.link_mut().href = None;
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>
where
Kind: 'a,
@ -47,20 +143,70 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
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 {
self.link_mut().hreflang = Some(hreflang);
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> {
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 {
self.link_mut().hreflang = None;
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>>
where
Kind: 'a,
@ -68,11 +214,35 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
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 {
self.link_mut().rel = Some(rel.into());
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
where
I: IntoIterator<Item = XsdString>,
@ -82,6 +252,20 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
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 {
let v = match self.link_mut().rel.take() {
Some(mut v) => {
@ -94,15 +278,52 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
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>> {
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 {
self.link_mut().rel = None;
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>
where
Kind: 'a,
@ -110,6 +331,18 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
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
where
T: Into<XsdNonNegativeInteger>,
@ -118,15 +351,52 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
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> {
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 {
self.link_mut().height = None;
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>
where
Kind: 'a,
@ -134,6 +404,18 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
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
where
T: Into<XsdNonNegativeInteger>,
@ -142,10 +424,35 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
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> {
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 {
self.link_mut().width = None;
self
@ -154,32 +461,75 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
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)]
#[serde(rename_all = "camelCase")]
#[builder(doc)]
pub struct Link<Kind> {
/// The target resource pointed to by a Link.
///
/// - Range: xsd:anyUri
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[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")]
#[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")]
#[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")]
#[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")]
#[builder(default, setter(strip_option, into))]
width: Option<XsdNonNegativeInteger>,
pub width: Option<XsdNonNegativeInteger>,
/// Base fields and unparsed json ends up here
#[serde(flatten)]
inner: Base<Kind>,
pub inner: Base<Kind>,
}
impl<Kind> Link<Kind> {