cloudflare_kv_proxy/
types.rs1use serde::{de::DeserializeOwned, Deserialize};
2
3pub type Result<T> = std::result::Result<T, Error>;
4
5#[derive(thiserror::Error, Debug)]
6pub enum Error {
7 #[error("key not found")]
8 NotFound,
9 #[error("unauthorized")]
10 Unauthorized,
11 #[error("bad request")]
12 BadRequest,
13 #[error("api error code {0}: {1}")]
14 Api(u16, String),
15
16 #[error("reqwest error")]
17 Reqwest(reqwest::Error),
18}
19
20impl From<reqwest::Error> for Error {
21 fn from(e: reqwest::Error) -> Self {
22 match e.status() {
23 Some(code) if code == 400 => Self::BadRequest,
24 Some(code) if code == 401 => Self::Unauthorized,
25 Some(code) if code == 404 => Self::NotFound,
26 _ => Self::Reqwest(e),
27 }
28 }
29}
30
31#[derive(Debug, Deserialize)]
32#[serde(untagged)]
33pub(crate) enum ApiResult<T>
34where
35 T: DeserializeOwned,
36{
37 Ok {
38 #[serde(with = "serde_with::json::nested")]
39 result: T,
40 },
41 Err {
42 code: u16,
43 error: String,
44 },
45}
46
47impl<T> From<ApiResult<T>> for Result<T>
48where
49 T: DeserializeOwned,
50{
51 fn from(r: ApiResult<T>) -> Self {
52 match r {
53 ApiResult::Ok { result } => Ok(result),
54 ApiResult::Err { code, error } => Err(Error::Api(code, error)),
55 }
56 }
57}
58
59pub trait NotFoundMapping<T> {
60 fn map_not_found_to_option(self) -> Result<Option<T>>;
61}
62
63impl<T> NotFoundMapping<T> for Result<T> {
64 fn map_not_found_to_option(self) -> Result<Option<T>> {
65 self.map(Some).or_else(|e| match e {
66 Error::NotFound => Ok(None),
67 _ => Err(e),
68 })
69 }
70}