1use anyhow::Result;
2use cid::Cid;
3use std::fmt::Display;
4use url::Url;
5
6use crate::data::AsQuery;
7
8pub const API_VERSION: &str = "v0alpha1";
9
10pub enum Route {
11 Fetch,
12 Push,
13 Publish,
14 Did,
15 Identify,
16 Replicate(Option<Cid>),
17}
18
19impl Display for Route {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 let fragment = match self {
22 Route::Fetch => "fetch".into(),
23 Route::Push => "push".into(),
24 Route::Publish => "publish".into(),
25 Route::Did => "did".into(),
26 Route::Identify => "identify".into(),
27 Route::Replicate(cid) => match cid {
28 Some(cid) => format!("replicate/{cid}"),
29 None => "replicate/:memo".into(),
30 },
31 };
32
33 write!(f, "/api/{API_VERSION}/{fragment}")
34 }
35}
36
37pub struct RouteUrl<'a, 'b, Params: AsQuery = ()>(pub &'a Url, pub Route, pub Option<&'b Params>);
38
39impl<'a, 'b, Params: AsQuery> TryFrom<RouteUrl<'a, 'b, Params>> for Url {
40 type Error = anyhow::Error;
41
42 fn try_from(value: RouteUrl<'a, 'b, Params>) -> Result<Self, Self::Error> {
43 let RouteUrl(api_base, route, params) = value;
44 let mut url = api_base.clone();
45 url.set_path(&route.to_string());
46 if let Some(params) = params {
47 url.set_query(params.as_query()?.as_deref());
48 } else {
49 url.set_query(None);
50 }
51 Ok(url)
52 }
53}