use http::StatusCode;
use crate::authorizer::Unsent;
use crate::outcome::IssueType;
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum InvalidInput {
#[error("an assigning authority is not an absolute URI")]
System,
#[error("the source identifier value is empty")]
EmptyValue,
#[error("the PIX Manager base URL is not an http(s) URL without a query or a fragment")]
Base,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum PixmError {
#[error("the PIX Manager does not recognise the source identifier's assigning authority")]
SourceDomainNotRecognized,
#[error("the PIX Manager does not recognise a target system")]
TargetDomainNotRecognized,
#[error("the PIX Manager answered {status}")]
Rejected {
status: StatusCode,
issues: Vec<IssueType>,
},
#[error("the PIX Manager did not answer within the timeout")]
Timeout,
#[error("the PIX Manager could not be reached")]
Transport(#[source] reqwest::Error),
#[error("the request to the PIX Manager could not be authenticated")]
Unauthenticated(#[source] crate::authorizer::AuthorizerError),
#[error("the PIX Manager's answer does not hold to ITI-83")]
Malformed(#[from] Malformation),
#[error("the request to the PIX Manager could not be written")]
Unwritable(#[source] serde_json::Error),
#[cfg(feature = "balp")]
#[error("the ITI-83 audit record could not be recorded")]
Audit(#[source] ihe_atna::balp::AuditError),
}
#[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 is not JSON (line {line}, column {column})")]
NotJson {
line: usize,
column: usize,
},
#[error("the answer is not a FHIR resource")]
NotAResource,
#[error("the answer is a resource ITI-83 does not answer with")]
UnexpectedResource,
#[error("the resource does not decode as FHIR R4: {kind}")]
Decode {
kind: fhir_types::codec::DecodeErrorKind,
},
#[error("the Bundle answer holds entries")]
BundleWithEntries,
#[error("parameter {index} is not an output of $ihe-pix")]
UnexpectedParameter {
index: usize,
},
#[error("parameter {index} carries a resource or parts")]
UnexpectedShape {
index: usize,
},
#[error("parameter {index} is a targetIdentifier without a valueIdentifier")]
NotAnIdentifier {
index: usize,
},
#[error("parameter {index} is an identifier without an assigning authority")]
NoAssigningAuthority {
index: usize,
},
#[error("parameter {index} is an identifier without a value")]
NoIdentifierValue {
index: usize,
},
#[error("parameter {index} is an identifier from a domain the request did not ask about")]
UnaskedDomain {
index: usize,
},
#[error("parameter {index} returns the source identifier")]
SourceEchoed {
index: usize,
},
#[error("parameter {index} is a targetId without a reference")]
NoReference {
index: usize,
},
}
pub(super) fn transport(error: reqwest::Error) -> PixmError {
let error = error.without_url();
if error.is_timeout() {
PixmError::Timeout
} else {
PixmError::Transport(error)
}
}
pub(super) fn unsent(error: Unsent) -> PixmError {
match error {
Unsent::Unauthenticated(source) => PixmError::Unauthenticated(source),
Unsent::Timeout => PixmError::Timeout,
Unsent::Transport(source) => transport(source),
}
}