Skip to main content

Link

Struct Link 

Source
pub struct Link {
    pub rel: Rel,
    pub type: Option<String>,
    pub href: Option<JrdUri>,
    pub template: Option<String>,
    pub titles: Option<BTreeMap<String, String>>,
    pub properties: Option<BTreeMap<JrdUri, Option<String>>>,
}
Expand description

A link in the WebFinger response.

Link objects describe related resources for the JRD subject. RFC 7033 gives each link a required rel member and optional type, href, titles, and properties members. Some WebFinger profiles also use the JRD template member from RFC 6415 link templates.

The Rust fields mirror the JRD JSON shape:

  • rel is a Rel so the required relation string is validated as one relation type.
  • href is a JrdUri because RFC 7033 defines it as a URI string.
  • template is a URI template string.
  • titles is a language-keyed object, matching the RFC JSON form.
  • properties uses JrdUri keys and Option<String> values so JSON null is representable.

Use Link::builder for ordinary construction from string literals or application values. Use Link::new when you already have a validated Rel.

See RFC 7033 section 4.4.4.

§Examples

use webfinger_rs::Link;

let link = Link::builder("http://webfinger.net/rel/profile-page")
    .href("https://example.com/profile/carol")
    .r#type("text/html")
    .title("en-us", "Carol's profile")
    .property("https://example.com/ns/verified", "true")
    .null_property("https://example.com/ns/old-profile")
    .build();

assert_eq!(link.rel.as_ref(), "http://webfinger.net/rel/profile-page");

Fields§

§rel: Rel

The relation type of the link.

This member is required by RFC 7033 section 4.4.4.1. It uses Rel instead of String so deserialization and builder construction both reject empty or malformed relation values.

§type: Option<String>

The media type of the link.

RFC 7033 leaves this as a media type string. The crate stores it as String because it is advisory metadata for the linked representation, not one of the WebFinger URI-valued fields.

See RFC 7033 section 4.4.4.2.

§href: Option<JrdUri>

The target URI of the link.

RFC 7033 defines href as a URI string. The field uses JrdUri rather than String so relative references are rejected when links are deserialized or built through the builder.

See RFC 7033 section 4.4.4.3.

§template: Option<String>

A URI template for the link.

RFC 6415 defines template as an optional JRD link member for link templates. The crate stores it as a string because WebFinger servers do not need to parse or expand the template expression before serializing it.

See RFC 6415 appendix A.

§titles: Option<BTreeMap<String, String>>

The titles of the link.

RFC 7033 models titles as a JSON object whose keys are language tags and whose values are title strings. The crate uses a BTreeMap so direct struct construction preserves that JSON object shape and gets deterministic ordering for comparisons, hashing, and rendered output.

Use LinkBuilder::title for one title at a time or LinkBuilder::titles to set a full language map.

See RFC 7033 section 4.4.4.4.

§properties: Option<BTreeMap<JrdUri, Option<String>>>

The properties of the link.

Link properties are a JSON object whose property identifiers are URI strings. Values may be strings or JSON null, so the Rust value type is Option<String>. None serializes as a property value of null; it does not omit the property from the map.

Use LinkBuilder::property for string-valued properties and LinkBuilder::null_property for JSON null values.

See RFC 7033 section 4.4.4.5.

Implementations§

Source

pub fn new(rel: Rel) -> Self

Creates a link from an already validated relation type.

The returned link has no optional members set. This is useful when relation validation happens separately, for example when reusing a Rel from a request filter. Use Link::builder when constructing a link directly from strings.

Source

pub fn builder<R: AsRef<str>>(rel: R) -> LinkBuilder

Creates a LinkBuilder with the given relation type.

The builder accepts a string-like value for the common case and validates it into Rel. Invalid values panic through Rel::new; use Rel::try_new and Link::new when the relation comes from untrusted input.

Examples found in repository?
examples/actix.rs (line 80)
68async fn webfinger(request: WebFingerRequest) -> actix_web::Result<WebFingerResponse> {
69    info!("fetching webfinger resource: {:?}", request);
70    let subject = request.resource.to_string();
71    if subject != SUBJECT {
72        let message = format!("{subject} does not exist");
73        return Err(actix_web::error::ErrorNotFound(message))?;
74    }
75    let mut links = Vec::new();
76
77    let profile_rel = Rel::new(PROFILE_PAGE_REL);
78    if request.rels.is_empty() || request.rels.contains(&profile_rel) {
79        links.push(
80            Link::builder(profile_rel)
81                .href(PROFILE_HREF)
82                .title("en", "Carol's profile")
83                .build(),
84        );
85    }
86
87    let avatar_rel = Rel::new(AVATAR_REL);
88    if request.rels.is_empty() || request.rels.contains(&avatar_rel) {
89        links.push(
90            Link::builder(avatar_rel)
91                .href(AVATAR_HREF)
92                .r#type("image/png")
93                .build(),
94        );
95    }
96
97    let response = WebFingerResponse::builder(subject)
98        .alias(PROFILE_HREF)
99        .property(ROLE_PROPERTY, "maintainer")
100        .links(links)
101        .build();
102    Ok(response)
103}
More examples
Hide additional examples
examples/axum.rs (line 83)
71async fn webfinger(request: WebFingerRequest) -> axum::response::Result<WebFingerResponse> {
72    info!("fetching webfinger resource: {:?}", request);
73    let subject = request.resource.to_string();
74    if subject != SUBJECT {
75        let message = format!("{subject} does not exist");
76        return Err((StatusCode::NOT_FOUND, message).into());
77    }
78    let mut links = Vec::new();
79
80    let profile_rel = Rel::new(PROFILE_PAGE_REL);
81    if request.rels.is_empty() || request.rels.contains(&profile_rel) {
82        links.push(
83            Link::builder(profile_rel)
84                .href(PROFILE_HREF)
85                .title("en", "Carol's profile")
86                .build(),
87        );
88    }
89
90    let avatar_rel = Rel::new(AVATAR_REL);
91    if request.rels.is_empty() || request.rels.contains(&avatar_rel) {
92        links.push(
93            Link::builder(avatar_rel)
94                .href(AVATAR_HREF)
95                .r#type("image/png")
96                .build(),
97        );
98    }
99
100    let response = WebFingerResponse::builder(subject)
101        .alias(PROFILE_HREF)
102        .property(ROLE_PROPERTY, "maintainer")
103        .links(links)
104        .build();
105    Ok(response)
106}

Trait Implementations§

Source§

fn clone(&self) -> Link

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

fn from(builder: LinkBuilder) -> Self

Converts to this type from the input type.
Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

fn cmp(&self, other: &Link) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 (const: unstable) · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 (const: unstable) · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 (const: unstable) · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

fn eq(&self, other: &Link) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

fn partial_cmp(&self, other: &Link) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 (const: unstable) · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Comparable<K> for Q
where Q: Ord + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into<'async_trait>( self, ) -> Pin<Box<dyn Future<Output = Result<U, <U as TryFrom<T>>::Error>> + 'async_trait>>
where T: 'async_trait,

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more