1
0
Fork 0
mirror of https://github.com/kotovalexarian/jsonapis.rs.git synced 2024-10-30 11:53:58 -04:00

Add struct field Document.errors

This commit is contained in:
Alex Kotov 2022-08-03 01:09:53 +04:00
parent 71c0795222
commit b315de3381
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
4 changed files with 162 additions and 11 deletions

View file

@ -142,6 +142,7 @@ fn main() {
}), }),
}), }),
]), ]),
"errors": json!(null),
}); });
let actual_json = serde_json::to_string(&document).unwrap(); let actual_json = serde_json::to_string(&document).unwrap();

View file

@ -6,12 +6,26 @@ pub struct DocumentBuilder {
meta: Option<MetaOrAttrsBuilder>, meta: Option<MetaOrAttrsBuilder>,
links: Option<LinksBuilder>, links: Option<LinksBuilder>,
data: Option<DataBuilder>, data: Option<DataBuilder>,
errors: Option<Vec<ErrorBuilder>>,
} }
impl Builder<'_> for DocumentBuilder { impl Builder<'_> for DocumentBuilder {
type Entity = Document; type Entity = Document;
fn finish(self) -> Result<Self::Entity, BuildErrors> { fn finish(self) -> Result<Self::Entity, BuildErrors> {
let errors = match self.errors {
None => None,
Some(errors) => {
let mut new_errors = Vec::new();
for error in errors {
new_errors.push(error.finish()?);
}
Some(new_errors)
}
};
Ok(Self::Entity { Ok(Self::Entity {
jsonapi: match self.jsonapi { jsonapi: match self.jsonapi {
None => None, None => None,
@ -29,6 +43,7 @@ impl Builder<'_> for DocumentBuilder {
None => None, None => None,
Some(data) => Some(data.finish()?), Some(data) => Some(data.finish()?),
}, },
errors,
}) })
} }
} }
@ -62,6 +77,19 @@ impl DocumentBuilder {
} }
} }
pub fn errors<E: Into<ErrorBuilder>>(self, errors: Vec<E>) -> Self {
let mut new_errors = Vec::new();
for error in errors {
new_errors.push(error.into());
}
Self {
errors: Some(new_errors),
..self
}
}
pub fn meta1<N: ToString, V: Into<Value>>(self, name: N, meta1: V) -> Self { pub fn meta1<N: ToString, V: Into<Value>>(self, name: N, meta1: V) -> Self {
let meta = self.meta.unwrap_or_default().item(name, meta1); let meta = self.meta.unwrap_or_default().item(name, meta1);
@ -83,15 +111,39 @@ impl DocumentBuilder {
..self ..self
} }
} }
pub fn error<E: Into<ErrorBuilder>>(self, error: E) -> Self {
let mut errors = self.errors.unwrap_or_default();
errors.push(error.into());
Self {
errors: Some(errors),
..self
}
}
} }
impl From<Document> for DocumentBuilder { impl From<Document> for DocumentBuilder {
fn from(document: Document) -> Self { fn from(document: Document) -> Self {
let errors = match document.errors {
None => None,
Some(errors) => {
let mut new_errors = Vec::new();
for error in errors {
new_errors.push(error.into());
}
Some(new_errors)
}
};
Self { Self {
jsonapi: document.jsonapi.map(|jsonapi| jsonapi.into()), jsonapi: document.jsonapi.map(|jsonapi| jsonapi.into()),
meta: document.meta.map(|meta| meta.into()), meta: document.meta.map(|meta| meta.into()),
links: document.links.map(|links| links.into()), links: document.links.map(|links| links.into()),
data: document.data.map(|data| data.into()), data: document.data.map(|data| data.into()),
errors,
} }
} }
} }
@ -127,6 +179,19 @@ mod tests {
} }
} }
fn errors() -> Vec<Error> {
vec![Error {
id: Some("789".into()),
links: None,
status: None,
code: None,
title: None,
detail: None,
source: None,
meta: None,
}]
}
#[test] #[test]
fn empty() { fn empty() {
assert_eq!( assert_eq!(
@ -136,6 +201,7 @@ mod tests {
meta: None, meta: None,
links: None, links: None,
data: None, data: None,
errors: None,
}, },
); );
} }
@ -156,6 +222,7 @@ mod tests {
.link("qwe", LinkBuilder::new("http://qwe.com")), .link("qwe", LinkBuilder::new("http://qwe.com")),
) )
.data(DataBuilder::Single(ResourceBuilder::new("qwerties"))) .data(DataBuilder::Single(ResourceBuilder::new("qwerties")))
.errors(vec![ErrorBuilder::default().id("789")])
.unwrap(), .unwrap(),
Document { Document {
jsonapi: Some(JsonApi { jsonapi: Some(JsonApi {
@ -172,6 +239,7 @@ mod tests {
attributes: None, attributes: None,
relationships: None, relationships: None,
})), })),
errors: Some(errors()),
}, },
); );
} }
@ -186,6 +254,7 @@ mod tests {
.link("self", LinkBuilder::new("http://self.com")) .link("self", LinkBuilder::new("http://self.com"))
.link("qwe", LinkBuilder::new("http://qwe.com")) .link("qwe", LinkBuilder::new("http://qwe.com"))
.data(DataBuilder::Single(ResourceBuilder::new("qwerties"))) .data(DataBuilder::Single(ResourceBuilder::new("qwerties")))
.error(ErrorBuilder::default().id("789"))
.unwrap(), .unwrap(),
Document { Document {
jsonapi: Some(JsonApi { jsonapi: Some(JsonApi {
@ -202,6 +271,7 @@ mod tests {
attributes: None, attributes: None,
relationships: None, relationships: None,
})), })),
errors: Some(errors()),
}, },
); );
} }
@ -220,6 +290,7 @@ mod tests {
meta: None, meta: None,
links: None, links: None,
data: None, data: None,
errors: None,
}, },
); );
} }
@ -238,6 +309,7 @@ mod tests {
meta: None, meta: None,
links: None, links: None,
data: None, data: None,
errors: None,
}, },
); );
} }
@ -257,6 +329,7 @@ mod tests {
meta: Some(meta()), meta: Some(meta()),
links: None, links: None,
data: None, data: None,
errors: None,
}, },
); );
} }
@ -294,6 +367,7 @@ mod tests {
about: None, about: None,
}), }),
data: None, data: None,
errors: None,
}, },
); );
} }
@ -318,6 +392,7 @@ mod tests {
attributes: None, attributes: None,
relationships: None, relationships: None,
}])), }])),
errors: None,
}, },
); );
} }
@ -340,6 +415,7 @@ mod tests {
attributes: None, attributes: None,
relationships: None, relationships: None,
})), })),
errors: None,
}, },
); );
} }
@ -362,6 +438,23 @@ mod tests {
attributes: None, attributes: None,
relationships: None, relationships: None,
}])), }])),
errors: None,
},
);
}
#[test]
fn with_errors() {
assert_eq!(
DocumentBuilder::default()
.errors(vec![ErrorBuilder::default().id("789")])
.unwrap(),
Document {
jsonapi: None,
meta: None,
links: None,
data: None,
errors: Some(errors()),
}, },
); );
} }
@ -383,6 +476,7 @@ mod tests {
}), }),
links: None, links: None,
data: None, data: None,
errors: None,
}, },
); );
} }
@ -415,6 +509,7 @@ mod tests {
about: None, about: None,
}), }),
data: None, data: None,
errors: None,
}, },
); );
} }
@ -427,16 +522,7 @@ mod tests {
meta: Some(meta()), meta: Some(meta()),
}), }),
meta: Some(meta()), meta: Some(meta()),
links: Some(Links { links: Some(links()),
other: HashMap::new(),
self_: Some(Link::String("http://self.com".into())),
related: Some(Link::String("http://related.com".into())),
first: None,
last: None,
prev: None,
next: None,
about: None,
}),
data: Some(Data::Single(Resource { data: Some(Data::Single(Resource {
type_: "qwerties".into(), type_: "qwerties".into(),
id: Some("123".into()), id: Some("123".into()),
@ -445,6 +531,7 @@ mod tests {
attributes: None, attributes: None,
relationships: None, relationships: None,
})), })),
errors: Some(errors()),
}; };
let builder: DocumentBuilder = document.clone().into(); let builder: DocumentBuilder = document.clone().into();
@ -461,6 +548,7 @@ mod tests {
meta: Some(meta()), meta: Some(meta()),
links: None, links: None,
data: None, data: None,
errors: None,
}, },
); );
} }
@ -474,6 +562,21 @@ mod tests {
meta: None, meta: None,
links: Some(links()), links: Some(links()),
data: None, data: None,
errors: None,
},
);
}
#[test]
fn with_errors_implicit_from_entity() {
assert_eq!(
DocumentBuilder::default().errors(errors()).unwrap(),
Document {
jsonapi: None,
meta: None,
links: None,
data: None,
errors: Some(errors()),
}, },
); );
} }

View file

@ -8,6 +8,7 @@ pub struct Document {
pub meta: Option<MetaOrAttrs>, pub meta: Option<MetaOrAttrs>,
pub links: Option<Links>, pub links: Option<Links>,
pub data: Option<Data>, pub data: Option<Data>,
pub errors: Option<Vec<Error>>,
} }
#[cfg(test)] #[cfg(test)]
@ -24,13 +25,15 @@ mod tests {
meta: None, meta: None,
links: None, links: None,
data: None, data: None,
errors: None,
}, },
), ),
"Document { \ "Document { \
jsonapi: None, \ jsonapi: None, \
meta: None, \ meta: None, \
links: None, \ links: None, \
data: None \ data: None, \
errors: None \
}", }",
); );
} }
@ -43,12 +46,14 @@ mod tests {
meta: None, meta: None,
links: None, links: None,
data: None, data: None,
errors: None,
}, },
Document { Document {
jsonapi: None, jsonapi: None,
meta: None, meta: None,
links: None, links: None,
data: None, data: None,
errors: None,
}, },
); );
@ -58,6 +63,7 @@ mod tests {
meta: None, meta: None,
links: None, links: None,
data: None, data: None,
errors: None,
}, },
Document { Document {
jsonapi: Some(JsonApi { jsonapi: Some(JsonApi {
@ -67,6 +73,7 @@ mod tests {
meta: None, meta: None,
links: None, links: None,
data: None, data: None,
errors: None,
}, },
); );
} }

View file

@ -165,6 +165,22 @@ mod tests {
}) })
} }
fn expected_errors() -> Vec<Error> {
vec![Error {
id: Some("789".into()),
links: Some(expected_links()),
status: Some(HttpStatus(http::StatusCode::OK)),
code: Some("some code".into()),
title: Some("some title".into()),
detail: Some("some detail".into()),
source: Some(ErrorSource {
pointer: Some("/foo/0/bar/1".into()),
parameter: Some("car".into()),
}),
meta: Some(expected_meta_or_attrs()),
}]
}
#[test] #[test]
fn serialize_and_deserialize() { fn serialize_and_deserialize() {
let document = Document { let document = Document {
@ -182,6 +198,7 @@ mod tests {
attributes: Some(expected_meta_or_attrs()), attributes: Some(expected_meta_or_attrs()),
relationships: Some(expected_relationships()), relationships: Some(expected_relationships()),
}])), }])),
errors: Some(expected_errors()),
}; };
let serialized = serde_json::to_string(&document).unwrap(); let serialized = serde_json::to_string(&document).unwrap();
@ -204,6 +221,7 @@ mod tests {
meta: Some(expected_meta_or_attrs()), meta: Some(expected_meta_or_attrs()),
links: Some(expected_links()), links: Some(expected_links()),
data: None, data: None,
errors: None,
}; };
let value = json!({ let value = json!({
@ -229,6 +247,7 @@ mod tests {
meta: None, meta: None,
links: None, links: None,
data: None, data: None,
errors: None,
}; };
let json = "{\"data\": null}"; let json = "{\"data\": null}";
@ -245,6 +264,7 @@ mod tests {
meta: None, meta: None,
links: None, links: None,
data: Some(Data::Multiple(vec![])), data: Some(Data::Multiple(vec![])),
errors: None,
}; };
let json = "{\"data\": []}"; let json = "{\"data\": []}";
@ -268,6 +288,7 @@ mod tests {
attributes: Some(expected_meta_or_attrs()), attributes: Some(expected_meta_or_attrs()),
relationships: Some(expected_relationships()), relationships: Some(expected_relationships()),
})), })),
errors: None,
}; };
let value = json!({ let value = json!({
@ -302,6 +323,7 @@ mod tests {
attributes: Some(expected_meta_or_attrs()), attributes: Some(expected_meta_or_attrs()),
relationships: Some(expected_relationships()), relationships: Some(expected_relationships()),
}])), }])),
errors: None,
}; };
let value = json!({ let value = json!({
@ -335,6 +357,7 @@ mod tests {
meta: None, meta: None,
links: None, links: None,
data: None, data: None,
errors: None,
}; };
let json = serde_json::to_string(&document).unwrap(); let json = serde_json::to_string(&document).unwrap();
@ -348,6 +371,7 @@ mod tests {
"meta": json!(null), "meta": json!(null),
"links": json!(null), "links": json!(null),
"data": json!(null), "data": json!(null),
"errors": json!(null),
}) })
); );
} }
@ -369,6 +393,7 @@ mod tests {
attributes: Some(expected_meta_or_attrs()), attributes: Some(expected_meta_or_attrs()),
relationships: Some(expected_relationships()), relationships: Some(expected_relationships()),
}])), }])),
errors: Some(expected_errors()),
}; };
let json = serde_json::to_string(&document).unwrap(); let json = serde_json::to_string(&document).unwrap();
@ -394,6 +419,21 @@ mod tests {
"relationships": expected_relationships_value(), "relationships": expected_relationships_value(),
}), }),
]), ]),
"errors": json!([
json!({
"id": json!("789"),
"links": expected_links_value(),
"status": Some(HttpStatus(http::StatusCode::OK)),
"code": json!("some code"),
"title": json!("some title"),
"detail": json!("some detail"),
"source": json!({
"pointer": json!("/foo/0/bar/1"),
"parameter": json!("car"),
}),
"meta": expected_meta_or_attrs_value(),
}),
]),
}) })
); );
} }