j_api/error/
mod.rs

1use crate::link::{Link, Links};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Default, Clone, Deserialize, Serialize)]
5#[serde(rename_all = "camelCase")]
6pub struct JsonApiError {
7    #[serde(skip_serializing_if = "Option::is_none")]
8    id: Option<String>,
9    #[serde(skip_serializing_if = "Option::is_none")]
10    links: Option<Links>,
11    #[serde(skip_serializing_if = "Option::is_none")]
12    status: Option<String>,
13    #[serde(skip_serializing_if = "Option::is_none")]
14    code: Option<String>,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    title: Option<String>,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    detail: Option<String>,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    source: Option<Source>,
21    // TODO: Meta
22}
23
24impl JsonApiError {
25    pub fn new() -> Self {
26        JsonApiError {
27            id: None,
28            links: None,
29            status: None,
30            code: None,
31            title: None,
32            detail: None,
33            source: None,
34        }
35    }
36
37    pub fn finish(&self) -> Self {
38        self.clone()
39    }
40
41    pub fn id(&mut self, id: String) -> &mut Self {
42        self.id = Some(id);
43        self
44    }
45
46    pub fn links(&mut self, links: Vec<Link>) -> &mut Self {
47        let mut error = "";
48        let (mut has_about, mut has_pagination) = (false, false);
49        links.iter().for_each(|link| match link {
50            Link::About(_) | Link::AboutObject(_) => {
51                error = "When returning an error you need to have an about link.";
52                has_about = true
53            }
54            Link::First(_) | Link::Last(_) | Link::Previous(_) | Link::Next(_) => {
55                error = "Errors should not have pagination links.";
56                has_pagination = true
57            }
58            _ => (),
59        });
60        if !has_about || has_pagination {
61            panic!(error)
62        }
63        self.links = Some(Links::new(links));
64        self
65    }
66
67    pub fn status(&mut self, status: u32) -> &mut Self {
68        self.status = Some(status.to_string());
69        self
70    }
71
72    pub fn code(&mut self, code: isize) -> &mut Self {
73        self.code = Some(code.to_string());
74        self
75    }
76
77    pub fn title(&mut self, title: &str) -> &mut Self {
78        self.title = Some(title.to_string());
79        self
80    }
81
82    pub fn detail(&mut self, detail: &str) -> &mut Self {
83        self.detail = Some(detail.to_string());
84        self
85    }
86
87    pub fn source(&mut self, source: Source) -> &mut Self {
88        self.source = Some(source);
89        self
90    }
91}
92
93#[derive(Debug, Clone, Deserialize, Serialize)]
94#[serde(rename_all = "camelCase")]
95pub enum Source {
96    Pointer(String),
97    Parameter(String),
98}