use http::StatusCode;
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum InvalidInput {
#[error(
"the Localization Service base URL is not an http(s) URL without a query or a fragment"
)]
Base,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum NviError {
#[error("the Localization Service answered {status}")]
Rejected {
status: StatusCode,
},
#[error("the Localization Service did not answer within the timeout")]
Timeout,
#[error("the Localization Service could not be reached")]
Transport(#[source] reqwest::Error),
#[error("the request to the Localization Service could not be authenticated")]
Unauthenticated(#[source] crate::authorizer::AuthorizerError),
#[error("the Localization Service's answer does not hold to the IG")]
Malformed(#[from] Malformation),
}
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum Malformation {
#[error("the answer is not application/fhir+json")]
NotFhirJson,
#[error("the answer exceeds {limit} bytes")]
TooLarge {
limit: usize,
},
#[error("the answer runs to more than {limit} pages")]
TooManyPages {
limit: usize,
},
#[error("the answer is not JSON (line {line}, column {column})")]
NotJson {
line: usize,
column: usize,
},
#[error("the answer is not a Bundle")]
NotABundle,
#[error("the Bundle does not decode as FHIR R4: {kind}")]
Decode {
kind: fhir_types::codec::DecodeErrorKind,
},
#[error("the Bundle is not a searchset")]
NotASearchset,
#[error("the next link is missing or leaves the search endpoint")]
NextLink,
#[error("entry {index} carries no resource")]
NoResource {
index: usize,
},
#[error("entry {index} is not a localization record")]
UnexpectedEntry {
index: usize,
},
#[error("entry {index} has no document reference status")]
Status {
index: usize,
},
#[error("entry {index} is about another subject")]
OtherSubject {
index: usize,
},
#[error("entry {index} is of another type")]
OtherType {
index: usize,
},
#[error("entry {index} names no custodian by URA")]
NoCustodian {
index: usize,
},
}
pub(super) fn transport(error: reqwest::Error) -> NviError {
let error = error.without_url();
if error.is_timeout() {
NviError::Timeout
} else {
NviError::Transport(error)
}
}