use crate::connector::{curl::Curl, Connector};
use http::Method;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use smol::stream::StreamExt;
use std::io::Result;
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Body {
pub entry_path: String,
pub path: Option<String>,
#[serde(with = "http_serde::option::method")]
pub method: Option<Method>,
}
impl Default for Body {
fn default() -> Self {
Body {
entry_path: "/count".to_string(),
path: None,
method: None,
}
}
}
impl Body {
pub fn new(entry_path: String, path: Option<String>, method: Option<Method>) -> Self {
Body {
entry_path,
path,
method,
}
}
#[instrument(name = "body::count")]
pub async fn count(&self, connector: &Curl) -> Result<Option<usize>> {
let mut connector = connector.clone();
let mut document = connector.document()?.clone_box();
document.set_entry_path(self.entry_path.clone());
connector.set_document(document)?;
if let Some(ref path) = self.path {
connector.path = path.clone();
}
if let Some(ref method) = self.method {
connector.method = method.clone();
}
let mut dataset = match connector.fetch().await? {
Some(dataset) => dataset,
None => {
trace!("No data found");
return Ok(None);
}
};
let value = dataset
.next()
.await
.map_or(Value::Null, |data| data.to_value());
let count_opt = match value {
Value::Number(n) => n.as_u64().map(|number| number as usize),
Value::String(s) => s.parse::<usize>().ok(),
_ => None,
};
info!(count = count_opt, "✅ Count with success");
Ok(count_opt)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::document::json::Json;
use macro_rules_attribute::apply;
use smol_macros::test;
#[apply(test!)]
async fn count_return_value() {
let document = Json::default();
let mut connector = Curl::default();
connector.endpoint = "http://localhost:8080".to_string();
connector.method = Method::POST;
connector.path = "/anything?count=10".to_string();
connector.set_document(Box::new(document)).unwrap();
let mut counter = Body::default();
counter.entry_path = "/args/count".to_string();
assert!(
Some(0) < counter.count(&connector).await.unwrap(),
"Counter count() must return a value upper than 0."
);
}
#[apply(test!)]
async fn count_not_return_value() {
let document = Json::default();
let mut connector = Curl::default();
connector.endpoint = "http://localhost:8080".to_string();
connector.method = Method::POST;
connector.path = "/anything?count=10".to_string();
connector.set_document(Box::new(document)).unwrap();
let mut counter = Body::default();
counter.entry_path = "/args/not_found".to_string();
assert_eq!(None, counter.count(&connector).await.unwrap());
}
}