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
use params::JsonApiParams;
use params::JsonApiResource;
use to_json::ToJson;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct JsonApiData<T> {
pub id: Option<String>,
#[serde(rename = "type")]
pub lower_case_type: String,
pub attributes: T,
}
impl<T> JsonApiData<T> {
pub fn new<Id: Into<String>, Type: Into<String>>(id: Option<Id>,
lower_case_type: Type,
attrs: T)
-> JsonApiData<T> {
JsonApiData {
id: id.map(|i| i.into()),
lower_case_type: lower_case_type.into(),
attributes: attrs,
}
}
pub fn has_id(&self) -> bool {
self.id.is_some()
}
}
impl<'a, T> From<(T, &'a JsonApiParams<T::FilterField, T::SortField>)> for JsonApiData<T::Attrs>
where T: ToJson + JsonApiResource,
T::Attrs: From<(T, &'a JsonApiParams<T::FilterField, T::SortField>)>
{
fn from((model, params): (T, &'a JsonApiParams<T::FilterField, T::SortField>)) -> Self {
JsonApiData::new(Some(model.id()),
model.type_name(),
T::Attrs::from((model, params)))
}
}
pub trait IntoJson<T, F, S> {
fn into_json<'a>(self, params: &'a JsonApiParams<F, S>) -> T;
}
impl<T> IntoJson<JsonApiData<T::Attrs>, T::FilterField, T::SortField> for T
where T: ToJson + JsonApiResource,
T::Attrs: for<'b> From<(T, &'b JsonApiParams<T::FilterField, T::SortField>)>
{
fn into_json<'a>(self,
params: &'a JsonApiParams<T::FilterField, T::SortField>)
-> JsonApiData<T::Attrs> {
(self, params).into()
}
}
impl<T> IntoJson<Vec<JsonApiData<T::Attrs>>, T::FilterField, T::SortField> for Vec<T>
where T: ToJson + JsonApiResource,
T::Attrs: for<'b> From<(T, &'b JsonApiParams<T::FilterField, T::SortField>)>
{
fn into_json<'a>(self,
params: &'a JsonApiParams<T::FilterField, T::SortField>)
-> Vec<JsonApiData<T::Attrs>> {
self.into_iter().map(|i| (i, params).into()).collect()
}
}