ogcapi_types/common/
exception.rs1use std::{error::Error, fmt::Display};
2
3use serde::{Deserialize, Serialize};
4use serde_json::{Map, Value};
5
6#[serde_with::skip_serializing_none]
8#[derive(Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone)]
9pub struct Exception {
10 pub r#type: String,
12 pub title: Option<String>,
14 pub status: Option<u16>,
17 pub detail: Option<String>,
19 pub instance: Option<String>,
22 #[serde(flatten, default, skip_serializing_if = "Map::is_empty")]
23 pub additional_properties: Map<String, Value>,
24}
25
26impl Exception {
27 pub fn new(r#type: impl ToString) -> Self {
28 Exception {
29 r#type: r#type.to_string(),
30 ..Default::default()
31 }
32 }
33
34 pub fn new_from_status(status: u16) -> Self {
35 let exception = Exception::new(format!(
36 "https://httpwg.org/specs/rfc7231.html#status.{}",
37 status
38 ));
39 exception.status(status)
40 }
41
42 pub fn title(mut self, title: impl ToString) -> Self {
43 self.title = Some(title.to_string());
44 self
45 }
46
47 pub fn status(mut self, status: u16) -> Self {
48 self.status = Some(status);
49 self
50 }
51
52 pub fn detail(mut self, detail: impl ToString) -> Self {
53 self.detail = Some(detail.to_string());
54 self
55 }
56
57 pub fn instance(mut self, instance: impl ToString) -> Self {
58 self.instance = Some(instance.to_string());
59 self
60 }
61}
62
63impl Display for Exception {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 write!(f, "{}", serde_json::to_string_pretty(self).unwrap())
66 }
67}
68
69impl Error for Exception {}
70
71#[cfg(test)]
72mod tests {
73 use super::Exception;
74
75 #[test]
76 fn exception() {
77 let e = Exception::new_from_status(500);
78 println!("{:#?}", e);
79 println!("{}", serde_json::to_string_pretty(&e).unwrap());
80 }
81}