1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
use std::convert::{From, Into}; /// A Link object for linking HAL Resources. /// /// The link represents a related resource. /// If follows [the HAL Draft Spec](https://tools.ietf.org/html/draft-kelly-json-hal-08#section-5) /// /// # Examples /// /// ```rust /// use rustic_hal::HalLink; /// /// let link = HalLink::new("http://sowewhere.com"); /// ``` #[derive(Clone, Debug, Serialize, Deserialize)] pub struct HalLink { /// The "href" property is REQUIRED. /// /// Its value is either a URI [RFC3986] or a URI Template [RFC6570]. /// /// If the value is a URI Template then the Link Object SHOULD have a /// "templated" attribute whose value is true. pub href: String, /// The "templated" property is OPTIONAL. /// /// Its value is boolean and SHOULD be true when the Link Object's "href" /// property is a URI Template. /// /// Its value SHOULD be considered false if it is undefined or any other /// value than true. #[serde(skip_serializing_if = "is_not", default)] pub templated: bool, /// The "type" property is OPTIONAL. /// /// Its value is a string used as a hint to indicate the media type /// expected when dereferencing the target resource. #[serde(skip_serializing_if = "Option::is_none")] pub media_type: Option<String>, /// The "deprecation" property is OPTIONAL. /// /// Its presence indicates that the link is to be deprecated (i.e. /// removed) at a future date. Its value is a URL that SHOULD provide /// further information about the deprecation. /// /// A client SHOULD provide some notification (for example, by logging a /// warning message) whenever it traverses over a link that has this /// property. The notification SHOULD include the deprecation property's /// value so that a client manitainer can easily find information about /// the deprecation. #[serde(skip_serializing_if = "Option::is_none")] pub deprecation: Option<String>, /// The "name" property is OPTIONAL. /// /// Its value MAY be used as a secondary key for selecting Link Objects /// which share the same relation type. #[serde(skip_serializing_if = "Option::is_none")] pub name: Option<String>, /// The "profile" property is OPTIONAL. /// /// Its value is a string which is a URI that hints about the profile (as /// defined by [I-D.wilde-profile-link]) of the target resource. #[serde(skip_serializing_if = "Option::is_none")] pub profile: Option<String>, /// The "title" property is OPTIONAL. /// /// Its value is a string and is intended for labelling the link with a /// human-readable identifier (as defined by [RFC5988]). #[serde(skip_serializing_if = "Option::is_none")] pub title: Option<String>, /// The "hreflang" property is OPTIONAL. /// /// Its value is a string and is intended for indicating the language of /// the target resource (as defined by [RFC5988]). #[serde(skip_serializing_if = "Option::is_none")] pub hreflang: Option<String>, } fn is_not(b: &bool) -> bool { !*b } macro_rules! chainable_string { ($x: ident, $y: ident) => { pub fn $y(mut self, $x: &str) -> Self { self.$x = Some($x.to_string()); self } pub fn $x(&self) -> Option<String> { self.$x.clone() } } } impl HalLink { pub fn new<S>(href: S) -> HalLink where S: Into<String>, { HalLink { href: href.into(), templated: false, media_type: None, deprecation: None, name: None, profile: None, title: None, hreflang: None, } } pub fn templated(mut self, templated: bool) -> Self { self.templated = templated; self } chainable_string!(media_type, with_media_type); chainable_string!(deprecation, with_deprecation); chainable_string!(name, with_name); chainable_string!(profile, with_profile); chainable_string!(title, with_title); chainable_string!(hreflang, with_hreflang); } impl<T> From<T> for HalLink where T: Into<String>, { fn from(s: T) -> Self { HalLink::new(s) } } /// Two links are the same if their href is the same /// The rest is immaterial impl PartialEq for HalLink { fn eq(&self, other: &HalLink) -> bool { self.href == other.href } }