1use std::fmt::Display;
7
8use crate::namespace::ErrorNamespaceUrl;
9
10#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
11#[serde(rename_all = "camelCase")]
12pub struct Error {
13 #[serde(rename = "type")]
14 pub namespace: ErrorNamespaceUrl,
15
16 pub message: String,
17
18 #[serde(default, skip_serializing_if = "Option::is_none")]
19 pub debug: Option<String>,
20}
21
22impl Display for Error {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 self.message.fmt(f)
25 }
26}
27
28#[cfg(test)]
29mod serde_tests {
30 use super::Error;
31 use crate::namespace::ErrorNamespaceUrl;
32
33 use pretty_assertions::assert_eq;
34 use serde_json::json;
35
36 fn example_error() -> Error {
37 Error {
38 namespace: ErrorNamespaceUrl::Identifier,
39 message: "Something went wrong".into(),
40 debug: Some("Could not connect to database".into()),
41 }
42 }
43
44 fn example_error_json() -> serde_json::Value {
45 json!( {
46 "type": "https://schema.oparl.org/1.1/Error",
47 "message": "Something went wrong",
48 "debug": "Could not connect to database",
49 })
50 }
51
52 #[test]
53 fn serialize() {
54 assert_eq!(json!(example_error()), example_error_json());
55 }
56
57 #[test]
58 fn deserialize_good() {
59 let deserialized: Error = serde_json::from_value(example_error_json())
60 .expect("value must be deserializable as Error");
61 assert_eq!(deserialized, example_error());
62 }
63
64 #[test]
65 fn deserialize_bad() {
66 assert!(serde_json::from_value::<Error>(json!("xyzabcd")).is_err());
67 assert!(serde_json::from_value::<Error>(json!(true)).is_err());
68 assert!(serde_json::from_value::<Error>(json!(123)).is_err());
69 }
70}