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:
parent
71c0795222
commit
b315de3381
4 changed files with 162 additions and 11 deletions
|
@ -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();
|
||||||
|
|
|
@ -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()),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
|
}),
|
||||||
|
]),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue