1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#![deny(warnings, missing_docs, missing_copy_implementations, missing_debug_implementations)]
pub fn search(query: &str) -> Result<Vec<SearchResult>, Error> {
search_with_options(query, Options::default())
}
pub fn search_with_options(query: &str, options: Options) -> Result<Vec<SearchResult>, Error> {
let language = options.language.to_string();
Ok(ureq::post("https://learngaelic.scot/dictionary/search")
.send_form(&[
("abairt", query),
("slang", &language[..]),
("wholeword", if options.whole_word { "true" } else { "false" }),
])?
.into_json()?)
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Language {
English,
Gaelic,
Both,
}
impl std::fmt::Display for Language {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
use Language::*;
Ok(match self {
English => f.write_fmt(format_args!("en"))?,
Gaelic => f.write_fmt(format_args!("gd"))?,
Both => f.write_fmt(format_args!("both"))?,
})
}
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct SearchResult {
pub id: usize,
pub headword: String,
pub source: Option<String>,
pub translation: String,
pub grammar: String,
pub ipa: String,
pub wordclass: String,
#[serde(rename = "hasAudio")]
pub has_audio: bool,
#[serde(rename = "audioVersion")]
pub audio_version: usize,
#[serde(rename = "gdKeys")]
pub gd_keys: Option<String>,
#[serde(rename = "enKeys")]
pub en_keys: Option<String>,
#[serde(rename = "commitMessage")]
pub commit_message: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Options {
whole_word: bool,
language: Language,
}
impl Options {
pub fn whole_word(&mut self) -> &mut Options {
self.whole_word = true;
self
}
pub fn language(&mut self, language: Language) -> &mut Options {
self.language = language;
self
}
}
impl std::default::Default for Options {
fn default() -> Options {
Options {
whole_word: false,
language: Language::Gaelic,
}
}
}
#[derive(Debug, Display)]
pub enum Error {
Ureq(ureq::Error),
Io(std::io::Error),
}
impl std::error::Error for Error {}
impl From<std::io::Error> for Error {
fn from(e: std::io::Error) -> Error {
Error::Io(e)
}
}
impl From<ureq::Error> for Error {
fn from(e: ureq::Error) -> Error {
Error::Ureq(e)
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
let result = super::search("saor").expect("Problem when searching for 'saor'");
assert_eq!(result[0].translation, "1 free, liberate! 2 absolve! 3 exempt!");
}
}
use derive_more::Display;
use serde::{Deserialize, Serialize};