use super::credentials::{Auth, Credentials};
use super::http::{get_request, HttpRequestInfo};
use crate::api::API_URL;
use crate::client::info;
use crate::error::NeocitiesErr;
use serde_derive::Deserialize;
use serde_derive::Serialize;
use serde_json::Value;
pub struct NcInfo {}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InfoResponse {
pub result: String,
pub info: Info,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Info {
pub sitename: String,
pub views: i64,
pub hits: i64,
#[serde(rename = "created_at")]
pub created_at: String,
#[serde(rename = "last_updated")]
pub last_updated: String,
pub domain: Value,
pub tags: Vec<String>,
}
impl NcInfo {
fn request_info(args: &Vec<String>) -> Result<HttpRequestInfo, NeocitiesErr> {
let cred = Credentials::new();
let url: String;
let mut api_key: Option<String> = None;
if args.len() > 0 {
url = format!("https://{}/info?sitename={}", API_URL, args[0]);
} else {
let auth = Auth::authenticate(cred, info::KEY, None);
match auth {
Err(e) => return Err(NeocitiesErr::HttpRequestError(e.into())),
Ok(a) => {
url = a.url;
api_key = a.api_key;
}
}
}
let ri = HttpRequestInfo {
uri: url,
api_key,
body: None,
multipart: None,
};
Ok(ri)
}
fn to_info_response(value: serde_json::Value) -> Result<InfoResponse, NeocitiesErr> {
match serde_json::from_value(value) {
Ok(res) => Ok(res),
Err(e) => Err(NeocitiesErr::SerdeDeserializationError(e)),
}
}
pub fn fetch(args: &Vec<String>) -> Result<InfoResponse, NeocitiesErr> {
let ri = NcInfo::request_info(args)?;
let res = get_request(ri.uri, ri.api_key)?;
let nci = NcInfo::to_info_response(res)?;
Ok(nci)
}
}
#[cfg(test)]
mod tests {
use super::{InfoResponse, NcInfo};
use serde_json::Value;
#[test]
fn site_info_request() {
let mock_args = vec![String::from("foo")];
let ph = NcInfo::request_info(&mock_args).unwrap();
assert_eq!(ph.uri, "https://neocities.org/api//info?sitename=foo");
}
#[test]
fn value_to_info_response() {
let mock_str = r#"
{
"result": "success",
"info": {
"sitename": "foo",
"views": 100,
"hits": 1000,
"created_at": "Tue, 12 May 2013 18:49:21 +0000",
"last_updated": "Tue, 12 May 2013 18:49:21 +0000",
"domain": null,
"tags": []
}
}"#;
let v: serde_json::Value = serde_json::from_str(mock_str).unwrap();
let ir: InfoResponse = NcInfo::to_info_response(v).unwrap();
assert_eq!(ir.result, "success");
assert_eq!(ir.info.sitename, "foo");
assert_eq!(ir.info.views, 100);
assert_eq!(ir.info.domain, Value::Null);
}
}