merriam_webster_http/
lib.rs

1#![doc = include_str!("../README.md")]
2use connector::Connector;
3use error::MerriamWebsterError;
4use hyper::{
5    client::Client as HyperClient,
6    header::{CONTENT_TYPE, USER_AGENT},
7    Body, Method, Request
8};
9use merriam_webster_model::{entry::Entry, top_words::APIGetTopWordsJSONResponse};
10use secrecy::{ExposeSecret, Secret};
11
12mod connector;
13pub mod error;
14
15/// A client for the Merriam Webster API.
16pub struct MerriamWebsterClient {
17    key: Secret<String>,
18    http: HyperClient<Connector>,
19}
20
21const MERRIAM_WEBSTER_USER_AGENT: &str = concat!(
22    "MerriumWebsterHttpRust (",
23    env!("CARGO_PKG_HOMEPAGE"),
24    ", ",
25    env!("CARGO_PKG_VERSION"),
26    ")",
27);
28
29impl MerriamWebsterClient {
30    /// Create a new Merriam Webster client.
31    pub fn new(key: Secret<String>) -> Self {
32        let connector = connector::create();
33        let http = hyper::Client::builder().build(connector);
34
35        Self { http, key }
36    }
37
38    /// Fetch a definition from the Merriam Webster API.
39    pub async fn collegiate_definition(
40        &self,
41        word: String,
42    ) -> Result<Vec<Entry>, MerriamWebsterError> {
43        let request = Request::builder()
44            .method(Method::GET)
45            .uri(format!("https://www.dictionaryapi.com/api/v3/references/collegiate/json/{word}?key={}", self.key.expose_secret()))
46            .header(USER_AGENT, MERRIAM_WEBSTER_USER_AGENT)
47            .header(CONTENT_TYPE, "application/json")
48            .body(Body::from(vec![0; 0]))
49            .expect("request builder");
50
51        let response = self.http.request(request).await?;
52
53        let body_bytes = hyper::body::to_bytes(response).await?;
54        let body = serde_json::from_slice::<Vec<Entry>>(&body_bytes)?;
55
56        Ok(body)
57    }
58
59    /// Fetch the currently most-searched words from the Merriam Webster API.
60    pub async fn top_words(&self) -> Result<APIGetTopWordsJSONResponse, MerriamWebsterError> {
61        let request = Request::builder()
62            .method(Method::GET)
63            .uri("https://www.merriam-webster.com/lapi/v1/mwol-mp/get-lookups-data-homepage")
64            .header(USER_AGENT, MERRIAM_WEBSTER_USER_AGENT)
65            .header(CONTENT_TYPE, "application/json")
66            .body(Body::from(vec![0; 0]))
67            .expect("request builder");
68
69        let response = self.http.request(request).await?;
70
71        let body_bytes = hyper::body::to_bytes(response).await?;
72        let body = serde_json::from_slice::<APIGetTopWordsJSONResponse>(&body_bytes)?;
73
74        Ok(body)
75    }
76}