diff options
| author | Lorenz Leitner <lrnz.ltnr@gmail.com> | 2021-10-10 14:16:03 +0200 |
|---|---|---|
| committer | Lorenz Leitner <lrnz.ltnr@gmail.com> | 2021-10-12 12:06:57 +0200 |
| commit | f964e2c3c2338434b57b6adf25dfbc346bb89b33 (patch) | |
| tree | 6c5685be99b79b80d7e89a4574887af770b23b23 /src/hooks/wa.rs | |
| parent | add yaml file sepperate to ci file (diff) | |
Basic (re)implementation of gonzobot wolfram alpha
Diffstat (limited to '')
| -rw-r--r-- | src/hooks/wa.rs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/hooks/wa.rs b/src/hooks/wa.rs new file mode 100644 index 0000000..b6d4eff --- /dev/null +++ b/src/hooks/wa.rs @@ -0,0 +1,84 @@ +use anyhow::{bail, Context, Error, Result}; +use reqwest::{get, Url}; +use serde::{Deserialize, Serialize}; +use serde_json::Result as SerdeJsonResult; +use tracing::trace; + +#[derive(Serialize, Deserialize, Debug)] +struct WaResult { + queryresult: QueryResult, +} + +#[derive(Serialize, Deserialize, Debug)] +struct QueryResult { + pods: Vec<Pod>, +} + +#[derive(Serialize, Deserialize, Debug)] +struct Pod { + title: String, + id: String, + subpods: Vec<SubPod>, +} + +#[derive(Serialize, Deserialize, Debug)] +struct SubPod { + title: String, + plaintext: String, +} + +fn parse_json(str_data: &str) -> SerdeJsonResult<WaResult> { + let w: WaResult = serde_json::from_str(str_data)?; + Ok(w) +} + +#[tracing::instrument] +async fn wa_query(query_str: &str) -> Result<String, Error> { + let app_id = "XXX"; // TODO: Get from env + let api_url = format!( + "http://api.wolframalpha.com/v2/query?input={}&appid={}&output=json", + query_str, app_id + ); + + let body = get(Url::parse(&api_url).context("Failed to parse url")?) + .await + .context("Failed to make request")? + .text() + .await + .context("failed to get request response text")?; + + let full_wa_res = parse_json(&body)?; + trace!("got full_wa_res: {:?}", full_wa_res); + + let pod_plaintexts = full_wa_res.queryresult.pods + .iter() + .filter(|it| it.id.to_lowercase() != "input") + .map(|pod| { + let subpod_texts = pod + .subpods + .iter() + .map(|subpod| subpod.plaintext.clone()) + .collect::<Vec<String>>() + .join(", "); + + format!("{}: {}", &pod.title, subpod_texts) + }) + .collect::<Vec<String>>() + .join(" - "); + + Ok(pod_plaintexts) +} + +#[cfg(test)] +mod tests { + + use super::wa_query; + use anyhow::{Error, Result}; + + #[tokio::test] + // async fn test_query_result_json_parsing() -> Result<(), Error> { + async fn test_query_result_json_parsing() { + let res = wa_query("weather graz").await.unwrap(); + assert_eq!(res, "asdf"); + } +} |
