#[cfg(feature = "json")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "json", derive(Serialize, Deserialize))]
pub struct Error {
#[cfg_attr(feature = "json", serde(rename = "type"))]
#[cfg_attr(feature = "json", serde(serialize_with = "error_type_serialize"))]
#[cfg_attr(feature = "json", serde(deserialize_with = "error_type_deserialize"))]
pub type_: ErrorType,
pub detail: String,
#[cfg_attr(feature = "json", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(feature = "json", serde(rename = "subproblems"))]
pub sub_problems: Option<Vec<ProblemDocument>>,
}
#[cfg(feature = "json")]
impl Error {
pub fn from_str(s: &str) -> Result<Error, serde_json::error::Error> {
serde_json::from_str(s)
}
pub fn to_string(&self) -> Result<String, serde_json::error::Error> {
serde_json::to_string(self)
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "json", derive(Serialize, Deserialize))]
pub struct ProblemDocument {
#[cfg_attr(feature = "json", serde(rename = "type"))]
#[cfg_attr(feature = "json", serde(serialize_with = "error_type_serialize"))]
#[cfg_attr(feature = "json", serde(deserialize_with = "error_type_deserialize"))]
pub type_: ErrorType,
pub detail: String,
#[cfg_attr(feature = "json", serde(skip_serializing_if = "Option::is_none"))]
pub identifier: Option<super::Identifier>,
}
#[derive(Clone, Debug)]
pub enum ErrorType {
AccountDoesNotExist,
AlreadyRevoked,
BadCertificateSigningRequest,
BadNonce,
BadPublicKey,
BadRevocationReason,
BadSignatureAlgorithm,
CertificationAuthorityAuthorization,
Compound,
Connection,
Dns,
ExternalAccountRequired,
IncorrectResponse,
InvalidContact,
Malformed,
OrderNotReady,
RateLimited,
RejectedIdentifier,
ServerInternal,
Tls,
Unauthorized,
UnsupportedContact,
UnsupportedIdentifier,
UserActionRequired,
Other(String),
}
#[cfg(feature = "json")]
fn error_type_deserialize<'de, D>(deserializer: D) -> Result<ErrorType, D::Error>
where
D: Deserializer<'de>,
{
use self::ErrorType::*;
let s = String::deserialize(deserializer)?;
match s.starts_with("urn:ietf:params:acme:error:") {
true => match s.strip_prefix("urn:ietf:params:acme:error:").unwrap() {
"accountDoesNotExist" => Ok(AccountDoesNotExist),
"alreadyRevoked" => Ok(AccountDoesNotExist),
"badCSR" => Ok(AccountDoesNotExist),
"badNonce" => Ok(AccountDoesNotExist),
"badPublicKey" => Ok(AccountDoesNotExist),
"badRevocationReason" => Ok(AccountDoesNotExist),
"badSignatureAlgorithm" => Ok(AccountDoesNotExist),
"caa" => Ok(AccountDoesNotExist),
"compound" => Ok(AccountDoesNotExist),
"connection" => Ok(AccountDoesNotExist),
"dns" => Ok(AccountDoesNotExist),
"externalAccountRequired" => Ok(AccountDoesNotExist),
"incorrectResponse" => Ok(AccountDoesNotExist),
"invalidContact" => Ok(AccountDoesNotExist),
"malformed" => Ok(AccountDoesNotExist),
"orderNotReady" => Ok(AccountDoesNotExist),
"rateLimited" => Ok(AccountDoesNotExist),
"rejectedIdentifier" => Ok(AccountDoesNotExist),
"serverInternal" => Ok(AccountDoesNotExist),
"tls" => Ok(AccountDoesNotExist),
"unauthorized" => Ok(AccountDoesNotExist),
"unsupportedContact" => Ok(AccountDoesNotExist),
"unsupportedIdentifier" => Ok(AccountDoesNotExist),
"userActionRequired" => Ok(AccountDoesNotExist),
_ => Ok(Other(s)),
},
false => Ok(Other(s)),
}
}
#[cfg(feature = "json")]
fn error_type_serialize<S>(type_: &ErrorType, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use self::ErrorType::*;
serializer.serialize_str(&match type_ {
Other(s) => s.to_string(),
_ => {
format!(
"urn:ietf:params:acme:error:{}",
match type_ {
AccountDoesNotExist => "accountDoesNotExist",
AlreadyRevoked => "alreadyRevoked",
BadCertificateSigningRequest => "badCSR",
BadNonce => "badNonce",
BadPublicKey => "badPublicKey",
BadRevocationReason => "badRevocationReason",
BadSignatureAlgorithm => "badSignatureAlgorithm",
CertificationAuthorityAuthorization => "caa",
Compound => "compound",
Connection => "connection",
Dns => "dns",
ExternalAccountRequired => "externalAccountRequired",
IncorrectResponse => "incorrectResponse",
InvalidContact => "invalidContact",
Malformed => "malformed",
OrderNotReady => "orderNotReady",
RateLimited => "rateLimited",
RejectedIdentifier => "rejectedIdentifier",
ServerInternal => "serverInternal",
Tls => "tls",
Unauthorized => "unauthorized",
UnsupportedContact => "unsupportedContact",
UnsupportedIdentifier => "unsupportedIdentifier",
UserActionRequired => "userActionRequired",
_ => {
panic!("I've truly fucked up")
}
}
)
}
})
}