use reqwest::Method;
use url::Url;
#[cfg(feature = "derive")]
pub use fav_derive::Api;
#[allow(missing_docs)]
pub enum DefaultApiKind {
Login,
QrLogin,
QrCheck,
Logout,
FetchResSet,
FetchRes,
PullRes,
}
pub trait ApiProvider<K> {
fn api(&self, api_kind: K) -> &dyn Api;
}
pub trait Api {
fn endpoint(&self) -> &'static str;
fn params(&self) -> &[&str];
fn url(&self, params: Vec<(&str, &str)>) -> Url {
#[cfg(test)]
{
use crate::error::FavCoreError;
let need = self.params();
if params.len() != need.len() || params.iter().any(|p| !need.contains(&p.0)) {
let msg = format!("Need params: {:#?}; Got {:#?}", need, params);
panic!("{:?}", FavCoreError::ParamsError(msg));
}
}
Url::parse_with_params(self.endpoint(), params).unwrap()
}
fn method(&self) -> Method {
Method::GET
}
}
#[cfg(test)]
mod tests {
use super::*;
struct Remote;
impl ApiProvider<DefaultApiKind> for Remote {
fn api(&self, api_name: DefaultApiKind) -> &dyn Api {
match api_name {
DefaultApiKind::Login => todo!(),
_ => todo!(),
}
}
}
struct LoginApi;
impl Api for LoginApi {
fn endpoint(&self) -> &'static str {
"http://abc.com"
}
fn params(&self) -> &[&str] {
&["id", "pwd"]
}
}
#[test]
#[should_panic]
fn params_panic_test() {
let remote = Remote;
let api = remote.api(DefaultApiKind::Login);
let _ = api.url(vec![("wrong_key", "")]);
}
}