datamuse_api_wrapper/
lib.rs

1#![deny( //These lint options are copied from https://pascalhertleif.de/artikel/good-practices-for-writing-rust-libraries/
2    missing_docs,
3    missing_debug_implementations,
4    missing_copy_implementations,
5    trivial_casts,
6    trivial_numeric_casts,
7    unsafe_code,
8    unstable_features,
9    unused_import_braces,
10    unused_qualifications
11)]
12
13//! # Datamuse Api Wrapper
14//! This library provides an unofficial wrapper around the Datamuse api for use in rust projects.
15//! The Datamuse api allows users to retrieve lists of words from different vocabulary lists
16//! based on a large number of different parameters. Additionally, it can be used to retrieve
17//! words based on a short string of letters, allowing for autocomplete functionality.
18//! Currently, the api does not require an api key and can be used to make up to 100,000
19//! requests per day after which the requests may be rate-limited (for higher usage see website).
20//! If you use this api you should make reference to the Datamuse api in your project.
21//! For more information see the official documentation at [https://www.datamuse.com/api/](https://www.datamuse.com/api/)
22//!
23//! ## Examples
24//! ### Words Endpoint
25//! ```rust
26//! extern crate tokio;
27//! extern crate datamuse_api_wrapper;
28//! use datamuse_api_wrapper::{ DatamuseClient, Vocabulary, EndPoint, RelatedType };
29//!
30//! #[tokio::main]
31//! async fn main() -> datamuse_api_wrapper::Result<()> {
32//!     let client = DatamuseClient::new();
33//!     let request = client.new_query(Vocabulary::English, EndPoint::Words)
34//!         .means_like("breakfast") // The words we're looking for are related to "breakfast"
35//!         .related(RelatedType::Rhyme, "grape"); // and rhyme with "grape"
36//!     let word_list = request.list().await?; // Get the list of words from the api
37//!
38//!     assert_eq!("crepe", word_list[0].word); // "crepe" is the only result as of writing this
39//!
40//!     Ok(())
41//! }
42//! ```
43//!
44//! ### Suggest EndPoint
45//! ```rust
46//! extern crate tokio;
47//! extern crate datamuse_api_wrapper;
48//! use datamuse_api_wrapper::{ DatamuseClient, Vocabulary, EndPoint };
49//!
50//! #[tokio::main]
51//! async fn main() -> datamuse_api_wrapper::Result<()> {
52//!     let client = DatamuseClient::new();
53//!     let request = client.new_query(Vocabulary::English, EndPoint::Suggest)
54//!         .hint_string("hello wor") // The user has alread typed in "hello wor"
55//!         .max_results(2); // We only want the first 2 results to be returned
56//!
57//!     let request = request.build()?; // Build the request
58//!     let response = request.send().await?; // Send the request
59//!     let word_list = response.list()?; // Parse the response into a word_list
60//!
61//!     assert_eq!("hello world", word_list[0].word); // "hello world" is the first result as of writing this
62//!
63//!     Ok(())
64//! }
65//! ```
66
67extern crate reqwest;
68extern crate serde;
69extern crate serde_json;
70
71use std::error;
72use std::fmt::{self, Display, Formatter};
73use std::result;
74
75mod request;
76mod response;
77
78pub use request::*;
79pub use response::*;
80
81/// This struct represents the client which can be used to make requests
82/// to the Datamuse api. Requests can be created using the new_query() method
83#[derive(Debug)]
84pub struct DatamuseClient {
85    client: reqwest::Client,
86}
87
88impl DatamuseClient {
89    /// Returns a new DatamuseClient struct
90    pub fn new() -> Self {
91        DatamuseClient {
92            client: reqwest::Client::new(),
93        }
94    }
95
96    /// Returns a new [RequestBuilder](request::RequestBuilder) struct with which requests can be created
97    /// and later sent. As parameters the vocabulary set and endpoint of the request are required. See
98    /// their individual documentations for more information
99    pub fn new_query<'a>(
100        &'a self,
101        vocabulary: Vocabulary,
102        endpoint: EndPoint,
103    ) -> RequestBuilder<'a> {
104        RequestBuilder::new(self, vocabulary, endpoint)
105    }
106}
107
108/// A type alias for Results with the library Error type
109pub type Result<T> = result::Result<T, Error>;
110
111/// An enum representing the different kind of Errors that can be returned within the library
112#[derive(Debug)]
113pub enum Error {
114    /// An error resulting from an underlying call to reqwest
115    ReqwestError(reqwest::Error),
116    /// An error resulting from an underlying call to serde
117    SerdeError(serde_json::Error),
118    /// An error resulting from the use of a parameter not availible for a specific vocabulary list
119    VocabularyError((String, String)),
120    /// An error resulting from the use of a parameter not intended for the specified endpoint
121    EndPointError((String, String)),
122}
123
124impl Display for Error {
125    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
126        match self {
127            Self::ReqwestError(err) => write!(f, "{}", err),
128            Self::SerdeError(err) => write!(f, "{}", err),
129            Self::VocabularyError((lang, param)) => write!(
130                f,
131                "Error: The parameter {} is not yet supported for {}",
132                param, lang
133            ),
134            Self::EndPointError((endpoint, param)) => write!(
135                f,
136                "Error: The parameter {} is not supported for {}",
137                param, endpoint
138            ),
139        }
140    }
141}
142
143impl error::Error for Error {}
144
145impl From<reqwest::Error> for Error {
146    fn from(error: reqwest::Error) -> Self {
147        Error::ReqwestError(error)
148    }
149}
150
151impl From<serde_json::Error> for Error {
152    fn from(error: serde_json::Error) -> Self {
153        Error::SerdeError(error)
154    }
155}