use anyhow::Result;
use std::fmt::Display;
use url::Url;
use crate::api::data::AsQuery;
#[macro_export]
macro_rules! route_display {
($routes:ty) => {
impl std::fmt::Display for $routes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "/api/{}/{}", self.api_version(), self.to_fragment())
}
}
};
}
pub trait RouteSignature: Display {
fn to_fragment(&self) -> String;
fn api_version(&self) -> &str;
}
pub struct RouteUrl<'a, 'b, Route: RouteSignature, Params: AsQuery = ()>(
pub &'a Url,
pub Route,
pub Option<&'b Params>,
);
impl<'a, 'b, Route: RouteSignature, Params: AsQuery> TryFrom<RouteUrl<'a, 'b, Route, Params>>
for Url
{
type Error = anyhow::Error;
fn try_from(value: RouteUrl<'a, 'b, Route, Params>) -> Result<Self, Self::Error> {
let RouteUrl(api_base, route, params) = value;
let mut url = api_base.clone();
url.set_path(&route.to_string());
if let Some(params) = params {
url.set_query(params.as_query()?.as_deref());
} else {
url.set_query(None);
}
Ok(url)
}
}