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
143
144
145
146
147
148
149
150
use crate::serde::Serialize;
use crate::RelLinkCollection;
use serde::de::DeserializeOwned;
use std::ops::{Deref, DerefMut};
#[skip_serializing_none]
#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct Content<T: Serialize> {
content: Option<T>,
rel: Option<RelLinkCollection>,
}
impl<T: Serialize> Content<T> {
/// Setting the content on the Content container
///
/// ```
/// use hateoas::Content;
/// let mut ctn_with_content = Content::new(());
///
/// assert_eq!(ctn_with_content.has_content(), true);
/// assert_eq!(ctn_with_content.content(), &Some(()));
/// ```
pub fn new(content: T) -> Self {
Content {
content: Some(content),
rel: None,
}
}
/// Checking if the content has any information in it, eg. is not none
///
/// ```
/// use hateoas::Content;
/// let ctn: Content<()> = Content::default();
/// let mut ctn_with_content = Content::new(Some(()));
///
/// assert_eq!(ctn.has_content(), false);
/// assert_eq!(ctn_with_content.has_content(), true);
/// ```
pub fn has_content(&self) -> bool {
self.content.is_some()
}
/// Getting a mut reference of the current spec content
/// This will get a Option<&mut T> of the current contents spec piece.
/// This will allow for modification of the internal content in the spec
/// ```
/// use hateoas::{Content};
/// let mut ctn: Content<String> = Content::default();
///
/// assert_eq!(ctn.content_mut(), &None);
///
/// let mut_ctn = ctn.content_mut();
/// *(mut_ctn) = Some("bar".to_string());
///
/// assert_eq!(ctn.content(), &Some("bar".to_string()));
/// ```
pub fn content_mut(&mut self) -> &mut Option<T> {
&mut self.content
}
/// Getting a reference of the current spec content
/// This will get a Option<T> of the current contents spec piece
/// ```
/// use hateoas::{Content, RelLinkCollection};
/// let mut ctn = Content::default();
///
/// assert_eq!(ctn.content(), &None);
///
/// *(ctn.content_mut()) = Some(());
///
/// assert_eq!(ctn.content(), &Some(()))
/// ```
pub fn content(&self) -> &Option<T> {
&self.content
}
/// Get the rel even if not set.
///
/// ```
/// use hateoas::{Content, RelLinkCollection};
///
/// let mut content: Content<()> = Content::default();
/// let rel = content.rel();
///
/// assert_eq!(rel, &mut RelLinkCollection::default())
/// ```
pub fn rel(&mut self) -> &mut RelLinkCollection {
if self.rel.is_none() {
self.rel = Some(RelLinkCollection::default());
}
self.rel.get_or_insert_with(RelLinkCollection::default)
}
}
impl<T: Serialize> Default for Content<T> {
fn default() -> Self {
Content {
content: None,
rel: None,
}
}
}
impl<T: Serialize> Deref for Content<T> {
type Target = Option<T>;
/// Dereferencing the Internal [T] from the Content object
/// This allows us to better operate on the content itself and use it without having to extract it.
/// ```
/// use std::ops::Deref;
/// use hateoas::Content;
/// let content: Content<()> = Content::default();
/// let content_opt: &Option<()> = content.deref();
///
/// assert_eq!(content_opt, &None);
/// ```
fn deref(&self) -> &Self::Target {
&self.content
}
}
impl<T: Serialize> DerefMut for Content<T> {
/// Dereferencing the Internal [T] from the Content object
/// This allows us to better operate on the content itself and use it without having to extract it.
/// ```
/// use std::ops::{Deref, DerefMut};
/// use hateoas::Content;
/// let mut content: Content<()> = Content::default();
/// let content_opt: &Option<()> = content.deref_mut();
///
/// assert_eq!(content_opt, &mut None);
/// ```
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.content
}
}
impl<T: Serialize> From<T> for Content<T> {
/// ## Convert from any type into a content<T> type.
/// This will simply wrap the `T` in a `Content` allowing for easier manipulation.
/// ```
/// use hateoas::Content;
/// let void: Content<()> = ().into();
///
/// assert_eq!(void, Content::new(()));
/// ```
fn from(t: T) -> Self {
Content::new(t)
}
}