datamuse_api_rs/
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_rs;
28//! use datamuse_api_rs::{ DatamuseClient, Vocabulary, EndPoint, RelatedType };
29//!
30//! #[tokio::main]
31//! async fn main() -> datamuse_api_rs::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_rs;
48//! use datamuse_api_rs::{ DatamuseClient, Vocabulary, EndPoint };
49//!
50//! #[tokio::main]
51//! async fn main() -> datamuse_api_rs::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 Default for DatamuseClient {
89    fn default() -> Self {
90        Self::new()
91    }
92}
93
94impl DatamuseClient {
95    /// Returns a new DatamuseClient struct
96    pub fn new() -> Self {
97        DatamuseClient {
98            client: reqwest::Client::new(),
99        }
100    }
101
102    /// Returns a new [RequestBuilder](RequestBuilder) struct with which requests can be created
103    /// and later sent. As parameters the vocabulary set and endpoint of the request are required. See
104    /// their individual documentations for more information
105    pub fn new_query(
106        &self,
107        vocabulary: Vocabulary,
108        endpoint: EndPoint,
109    ) -> RequestBuilder {
110        RequestBuilder::new(self, vocabulary, endpoint)
111    }
112}
113
114/// A type alias for Results with the library Error type
115pub type Result<T> = result::Result<T, Error>;
116
117/// An enum representing the different kind of Errors that can be returned within the library
118#[derive(Debug)]
119pub enum Error {
120    /// An error resulting from an underlying call to reqwest
121    ReqwestError(reqwest::Error),
122    /// An error resulting from an underlying call to serde
123    SerdeError(serde_json::Error),
124    /// An error resulting from the use of a parameter not availible for a specific vocabulary list
125    VocabularyError((String, String)),
126    /// An error resulting from the use of a parameter not intended for the specified endpoint
127    EndPointError((String, String)),
128}
129
130impl Display for Error {
131    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
132        match self {
133            Self::ReqwestError(err) => write!(f, "{}", err),
134            Self::SerdeError(err) => write!(f, "{}", err),
135            Self::VocabularyError((lang, param)) => write!(
136                f,
137                "Error: The parameter {} is not yet supported for {}",
138                param, lang
139            ),
140            Self::EndPointError((endpoint, param)) => write!(
141                f,
142                "Error: The parameter {} is not supported for {}",
143                param, endpoint
144            ),
145        }
146    }
147}
148
149impl error::Error for Error {}
150
151impl From<reqwest::Error> for Error {
152    fn from(error: reqwest::Error) -> Self {
153        Error::ReqwestError(error)
154    }
155}
156
157impl From<serde_json::Error> for Error {
158    fn from(error: serde_json::Error) -> Self {
159        Error::SerdeError(error)
160    }
161}