2025-06-25 16:48:00 +00:00
|
|
|
|
use std::fmt;
|
|
|
|
|
|
|
2025-06-25 23:15:33 +00:00
|
|
|
|
use crate::sharry;
|
|
|
|
|
|
|
2025-06-25 16:48:00 +00:00
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
|
|
|
|
pub enum Parameter {
|
|
|
|
|
|
#[error("given URI {0:?}")]
|
2025-07-01 15:20:07 +00:00
|
|
|
|
Uri(sharry::Uri),
|
2025-06-25 16:48:00 +00:00
|
|
|
|
|
|
|
|
|
|
#[error("given Alias ID {0:?}")]
|
2025-06-27 01:47:38 +00:00
|
|
|
|
AliasID(sharry::AliasID),
|
2025-06-25 16:48:00 +00:00
|
|
|
|
|
|
|
|
|
|
#[error("stored Share ID {0:?}")]
|
2025-06-27 01:47:38 +00:00
|
|
|
|
ShareID(sharry::ShareID),
|
2025-06-25 16:48:00 +00:00
|
|
|
|
|
2025-06-25 23:15:33 +00:00
|
|
|
|
#[error("stored {0:?}")]
|
|
|
|
|
|
FileID(sharry::FileID),
|
2025-06-25 16:48:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-01 15:20:07 +00:00
|
|
|
|
// a helper to generate all the `From<T> for Parameter` impls
|
|
|
|
|
|
macro_rules! impl_param_from {
|
|
|
|
|
|
// $typ: the source type; $var: the enum‐variant name
|
|
|
|
|
|
( $( $typ:path => $var:ident ),* $(,)? ) => {
|
|
|
|
|
|
$(
|
|
|
|
|
|
impl From<$typ> for Parameter {
|
|
|
|
|
|
fn from(value: $typ) -> Self {
|
|
|
|
|
|
Self::$var(value)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
)*
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl_param_from! {
|
|
|
|
|
|
sharry::Uri => Uri,
|
|
|
|
|
|
sharry::AliasID => AliasID,
|
|
|
|
|
|
sharry::ShareID => ShareID,
|
|
|
|
|
|
sharry::FileID => FileID,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-25 16:48:00 +00:00
|
|
|
|
impl Parameter {
|
|
|
|
|
|
fn is_fatal(&self) -> bool {
|
|
|
|
|
|
matches!(self, Self::Uri(_) | Self::AliasID(_))
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
|
|
|
|
pub enum Error {
|
|
|
|
|
|
#[error(transparent)]
|
|
|
|
|
|
StdIo(#[from] std::io::Error),
|
|
|
|
|
|
|
2025-06-26 09:56:29 +00:00
|
|
|
|
#[error("Response error: {0}")]
|
2025-06-25 16:48:00 +00:00
|
|
|
|
Response(String),
|
|
|
|
|
|
|
|
|
|
|
|
#[error("Invalid {0}")]
|
|
|
|
|
|
InvalidParameter(Parameter),
|
|
|
|
|
|
|
2025-06-26 09:56:29 +00:00
|
|
|
|
#[error("Mismatch, expected {expected:?} but got {actual:?}")]
|
|
|
|
|
|
Mismatch { expected: String, actual: String },
|
|
|
|
|
|
|
2025-06-25 16:48:00 +00:00
|
|
|
|
#[error("Unknown error: {0}")]
|
|
|
|
|
|
Unknown(String),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-01 15:20:07 +00:00
|
|
|
|
// a helper to generate all the `From<T> for Error` impls
|
|
|
|
|
|
macro_rules! impl_error_from {
|
2025-07-01 18:51:49 +00:00
|
|
|
|
// $typ: the source type
|
|
|
|
|
|
( $( $typ:path ),* $(,)? ) => {
|
2025-07-01 15:20:07 +00:00
|
|
|
|
$(
|
|
|
|
|
|
// // implement for values
|
|
|
|
|
|
// impl From<$typ> for Error {
|
|
|
|
|
|
// fn from(value: $typ) -> Self {
|
|
|
|
|
|
// Self::InvalidParameter(value.into())
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// implement for references
|
|
|
|
|
|
impl From<&$typ> for Error {
|
|
|
|
|
|
fn from(value: &$typ) -> Self {
|
|
|
|
|
|
Self::InvalidParameter(value.clone().into())
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
)*
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl_error_from! {
|
2025-07-01 18:51:49 +00:00
|
|
|
|
sharry::Uri,
|
|
|
|
|
|
sharry::AliasID,
|
|
|
|
|
|
sharry::ShareID,
|
|
|
|
|
|
sharry::FileID,
|
2025-07-01 15:20:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-25 16:48:00 +00:00
|
|
|
|
#[allow(clippy::needless_pass_by_value)]
|
|
|
|
|
|
fn into_string(val: impl ToString) -> String {
|
|
|
|
|
|
val.to_string()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Error {
|
|
|
|
|
|
pub fn res_status_check<T>(actual: T, expected: T) -> Result<()>
|
|
|
|
|
|
where
|
|
|
|
|
|
T: PartialEq + fmt::Display + Copy,
|
|
|
|
|
|
{
|
|
|
|
|
|
if actual == expected {
|
|
|
|
|
|
Ok(())
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Err(Self::Response(format!(
|
|
|
|
|
|
"unexpected status: {actual} (expected {expected})"
|
|
|
|
|
|
)))
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn response(e: impl ToString) -> Self {
|
|
|
|
|
|
Self::Response(into_string(e))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-26 09:56:29 +00:00
|
|
|
|
pub fn mismatch(expected: impl ToString, actual: impl ToString) -> Self {
|
|
|
|
|
|
Self::Mismatch {
|
|
|
|
|
|
expected: into_string(expected),
|
|
|
|
|
|
actual: into_string(actual),
|
|
|
|
|
|
}
|
2025-06-25 16:48:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-03 17:20:56 +00:00
|
|
|
|
pub fn is_mismatch<E, A>(&self, has_expected: E, has_actual: A) -> bool
|
|
|
|
|
|
where
|
|
|
|
|
|
String: PartialEq<E> + PartialEq<A>,
|
|
|
|
|
|
{
|
|
|
|
|
|
matches!(
|
|
|
|
|
|
self,
|
|
|
|
|
|
Self::Mismatch { expected, actual }
|
|
|
|
|
|
if *expected == has_expected
|
|
|
|
|
|
&& *actual == has_actual
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-01 15:24:26 +00:00
|
|
|
|
#[must_use]
|
2025-07-01 15:20:07 +00:00
|
|
|
|
pub fn get_invalid_param(&self) -> Option<&Parameter> {
|
|
|
|
|
|
if let Self::InvalidParameter(p) = self {
|
|
|
|
|
|
Some(p)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
None
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-25 16:48:00 +00:00
|
|
|
|
#[must_use]
|
|
|
|
|
|
pub fn is_fatal(&self) -> bool {
|
|
|
|
|
|
match self {
|
|
|
|
|
|
Self::InvalidParameter(p) => p.is_fatal(),
|
2025-06-26 10:13:23 +00:00
|
|
|
|
Self::Mismatch { .. } | Self::Unknown(_) => true,
|
2025-06-25 16:48:00 +00:00
|
|
|
|
_ => false,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub type Result<T> = std::result::Result<T, Error>;
|