1#[cfg(feature = "json")]
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3
4#[derive(Clone, Debug)]
8#[cfg_attr(feature = "json", derive(Serialize, Deserialize))]
9pub struct Error {
10 #[cfg_attr(feature = "json", serde(rename = "type"))]
12 #[cfg_attr(feature = "json", serde(serialize_with = "error_type_serialize"))]
13 #[cfg_attr(feature = "json", serde(deserialize_with = "error_type_deserialize"))]
14 pub type_: ErrorType,
15 pub detail: String,
17 #[cfg_attr(feature = "json", serde(skip_serializing_if = "Option::is_none"))]
19 #[cfg_attr(feature = "json", serde(rename = "subproblems"))]
20 pub sub_problems: Option<Vec<ProblemDocument>>,
21}
22
23#[cfg(feature = "json")]
24impl Error {
25 pub fn from_str(s: &str) -> Result<Error, serde_json::error::Error> {
27 serde_json::from_str(s)
28 }
29
30 pub fn to_string(&self) -> Result<String, serde_json::error::Error> {
32 serde_json::to_string(self)
33 }
34}
35
36#[derive(Clone, Debug)]
40#[cfg_attr(feature = "json", derive(Serialize, Deserialize))]
41pub struct ProblemDocument {
42 #[cfg_attr(feature = "json", serde(rename = "type"))]
44 #[cfg_attr(feature = "json", serde(serialize_with = "error_type_serialize"))]
45 #[cfg_attr(feature = "json", serde(deserialize_with = "error_type_deserialize"))]
46 pub type_: ErrorType,
47 pub detail: String,
49 #[cfg_attr(feature = "json", serde(skip_serializing_if = "Option::is_none"))]
51 pub identifier: Option<super::Identifier>,
52}
53
54#[derive(Clone, Debug)]
58pub enum ErrorType {
59 AccountDoesNotExist,
60 AlreadyRevoked,
61 BadCertificateSigningRequest,
62 BadNonce,
63 BadPublicKey,
64 BadRevocationReason,
65 BadSignatureAlgorithm,
66 CertificationAuthorityAuthorization,
67 Compound,
68 Connection,
69 Dns,
70 ExternalAccountRequired,
71 IncorrectResponse,
72 InvalidContact,
73 Malformed,
74 OrderNotReady,
75 RateLimited,
76 RejectedIdentifier,
77 ServerInternal,
78 Tls,
79 Unauthorized,
80 UnsupportedContact,
81 UnsupportedIdentifier,
82 UserActionRequired,
83 Other(String),
84}
85
86#[cfg(feature = "json")]
87fn error_type_deserialize<'de, D>(deserializer: D) -> Result<ErrorType, D::Error>
88where
89 D: Deserializer<'de>,
90{
91 use self::ErrorType::*;
92 let s = String::deserialize(deserializer)?;
93
94 match s.starts_with("urn:ietf:params:acme:error:") {
95 true => match s.strip_prefix("urn:ietf:params:acme:error:").unwrap() {
96 "accountDoesNotExist" => Ok(AccountDoesNotExist),
97 "alreadyRevoked" => Ok(AccountDoesNotExist),
98 "badCSR" => Ok(AccountDoesNotExist),
99 "badNonce" => Ok(AccountDoesNotExist),
100 "badPublicKey" => Ok(AccountDoesNotExist),
101 "badRevocationReason" => Ok(AccountDoesNotExist),
102 "badSignatureAlgorithm" => Ok(AccountDoesNotExist),
103 "caa" => Ok(AccountDoesNotExist),
104 "compound" => Ok(AccountDoesNotExist),
105 "connection" => Ok(AccountDoesNotExist),
106 "dns" => Ok(AccountDoesNotExist),
107 "externalAccountRequired" => Ok(AccountDoesNotExist),
108 "incorrectResponse" => Ok(AccountDoesNotExist),
109 "invalidContact" => Ok(AccountDoesNotExist),
110 "malformed" => Ok(AccountDoesNotExist),
111 "orderNotReady" => Ok(AccountDoesNotExist),
112 "rateLimited" => Ok(AccountDoesNotExist),
113 "rejectedIdentifier" => Ok(AccountDoesNotExist),
114 "serverInternal" => Ok(AccountDoesNotExist),
115 "tls" => Ok(AccountDoesNotExist),
116 "unauthorized" => Ok(AccountDoesNotExist),
117 "unsupportedContact" => Ok(AccountDoesNotExist),
118 "unsupportedIdentifier" => Ok(AccountDoesNotExist),
119 "userActionRequired" => Ok(AccountDoesNotExist),
120 _ => Ok(Other(s)),
121 },
122 false => Ok(Other(s)),
123 }
124}
125
126#[cfg(feature = "json")]
127fn error_type_serialize<S>(type_: &ErrorType, serializer: S) -> Result<S::Ok, S::Error>
128where
129 S: Serializer,
130{
131 use self::ErrorType::*;
132
133 serializer.serialize_str(&match type_ {
134 Other(s) => s.to_string(),
135 _ => {
136 format!(
137 "urn:ietf:params:acme:error:{}",
138 match type_ {
139 AccountDoesNotExist => "accountDoesNotExist",
140 AlreadyRevoked => "alreadyRevoked",
141 BadCertificateSigningRequest => "badCSR",
142 BadNonce => "badNonce",
143 BadPublicKey => "badPublicKey",
144 BadRevocationReason => "badRevocationReason",
145 BadSignatureAlgorithm => "badSignatureAlgorithm",
146 CertificationAuthorityAuthorization => "caa",
147 Compound => "compound",
148 Connection => "connection",
149 Dns => "dns",
150 ExternalAccountRequired => "externalAccountRequired",
151 IncorrectResponse => "incorrectResponse",
152 InvalidContact => "invalidContact",
153 Malformed => "malformed",
154 OrderNotReady => "orderNotReady",
155 RateLimited => "rateLimited",
156 RejectedIdentifier => "rejectedIdentifier",
157 ServerInternal => "serverInternal",
158 Tls => "tls",
159 Unauthorized => "unauthorized",
160 UnsupportedContact => "unsupportedContact",
161 UnsupportedIdentifier => "unsupportedIdentifier",
162 UserActionRequired => "userActionRequired",
163 _ => {
164 panic!("I've truly fucked up")
165 }
166 }
167 )
168 }
169 })
170}