use http::{Method, StatusCode, response::Parts, status::InvalidStatusCode};
use crate::{
dav::{PutResourceParseError, WebDavError},
encoding::NormalisationError,
};
#[derive(thiserror::Error, Debug)]
pub enum ParseResponseError {
#[error("invalid status code in response: {0}")]
InvalidStatusCode(#[from] InvalidStatusCode),
#[error("parsing XML response: {0}")]
Xml(#[from] roxmltree::Error),
#[error("http request returned {0}")]
BadStatusCode(StatusCode),
#[error("invalid response: {0}")]
InvalidResponse(String),
#[error("decoding response as utf-8: {0}")]
NotUtf8(#[from] std::str::Utf8Error),
}
impl From<StatusCode> for ParseResponseError {
fn from(status: StatusCode) -> Self {
ParseResponseError::BadStatusCode(status)
}
}
impl From<NormalisationError> for ParseResponseError {
fn from(error: NormalisationError) -> Self {
ParseResponseError::InvalidResponse(error.to_string())
}
}
impl<E> From<ParseResponseError> for WebDavError<E> {
fn from(error: ParseResponseError) -> Self {
match error {
ParseResponseError::InvalidStatusCode(e) => WebDavError::InvalidStatusCode(e),
ParseResponseError::Xml(e) => WebDavError::Xml(e),
ParseResponseError::BadStatusCode(s) => WebDavError::BadStatusCode(s),
ParseResponseError::InvalidResponse(msg) => WebDavError::InvalidResponse(msg.into()),
ParseResponseError::NotUtf8(e) => WebDavError::NotUtf8(e),
}
}
}
impl<E> From<PutResourceParseError> for WebDavError<E> {
fn from(error: PutResourceParseError) -> Self {
match error {
PutResourceParseError::BadStatusCode(s) => WebDavError::BadStatusCode(s),
PutResourceParseError::NotUtf8(e) => WebDavError::NotUtf8(e),
PutResourceParseError::PreconditionFailed(p) => WebDavError::PreconditionFailed(p),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PreparedRequest {
pub method: Method,
pub path: String,
pub body: String,
pub headers: Vec<(String, String)>,
}
#[must_use]
pub fn xml_content_type_header() -> (String, String) {
(
"Content-Type".to_string(),
"application/xml; charset=utf-8".to_string(),
)
}
pub trait DavRequest {
type Response;
type ParseError;
type Error<E>;
fn prepare_request(&self) -> Result<PreparedRequest, http::Error>;
fn parse_response(
&self,
parts: &Parts,
body: &[u8],
) -> Result<Self::Response, Self::ParseError>;
}