cortical_io/
client.rs

1use std::error::Error;
2
3use crate::{CompareResponse, CreateCategoryFilterRequest, CreateCategoryFilterResponse, Fingerprint, GetTermsContextsRequest, GetTermsContextsResponse, GetTermsRequest, GetTermsResponse, GetTermsSimilarTermsRequest, LanguageResponse, PosType, Retina, TextEnvelope, TextSlice, TextSliceRequest};
4
5pub struct Cortical {
6    pub client: reqwest::Client,
7    pub base_url: String,
8}
9
10impl Cortical {
11    pub fn new() -> Cortical {
12        Cortical {
13            client: reqwest::Client::new(),
14            base_url: std::env::var("CORTICAL_API_URL").unwrap_or("https://languages.cortical.io".to_string()),
15        }
16    }
17
18    pub async fn get_retinas(&self) -> Result<Vec<Retina>, Box<dyn Error>> {
19        let response =
20            self.client
21                .get(format!("{}{}", &self.base_url, "/rest/retinas"))
22                .send()
23                .await?;
24
25        Ok(
26            response
27                .json()
28                .await?
29        )
30    }
31
32    pub async fn get_text_analysis(
33        &self,
34        text: &str,
35        retina_name: Option<&str>,
36    ) -> Result<Vec<Fingerprint>, Box<dyn Error>> {
37        let retina_name = retina_name.unwrap_or("en_general");
38
39        let response =
40            self.client
41                .post(format!("{}/rest/text?retina_name={}", &self.base_url, retina_name))
42                .header("Accept", "application/json")
43                .header("Referer", "")
44                .header("Content-Type", "application/json")
45                .body(text.to_string())
46                .send()
47                .await?;
48
49        Ok(
50            response
51                .json()
52                .await?
53        )
54    }
55
56    pub async fn get_text_keywords(
57        &self,
58        text: &str,
59        retina_name: Option<&str>,
60    ) -> Result<Vec<String>, Box<dyn Error>> {
61        let retina_name = retina_name.unwrap_or("en_general");
62
63        let response =
64            self.client
65                .post(format!("{}/rest/text/keywords?retina_name={}", &self.base_url, retina_name))
66                .header("Accept", "application/json")
67                .header("Referer", "")
68                .header("Content-Type", "text/plain;charset=UTF-8")
69                .body(text.to_string())
70                .send()
71                .await?;
72
73        Ok(
74            response
75                .json()
76                .await?
77        )
78    }
79
80    pub async fn get_text_slices(
81        &self,
82        text: &str,
83        params: Option<TextSliceRequest>,
84    ) -> Result<Vec<TextSlice>, Box<dyn Error>> {
85        let params = params.unwrap_or_default();
86
87        let response =
88            self.client
89                .post(
90                    format!(
91                        "{}/rest/text/slices?retina_name={}&start_index={}&max_results={}&get_fingerprint={}",
92                        &self.base_url,
93                        params.retina_name,
94                        params.start_index,
95                        params.max_results,
96                        params.get_fingerprint
97                    )
98                )
99                .header("Accept", "application/json")
100                .header("Referer", "")
101                .header("Content-Type", "application/json")
102                .body(text.to_string())
103                .send()
104                .await?;
105
106        Ok(
107            response
108                .json()
109                .await?
110        )
111    }
112
113    pub async fn get_text_detect_language(
114        &self,
115        text: &str,
116    ) -> Result<LanguageResponse, Box<dyn Error>> {
117        let response =
118            self.client
119                .post(format!("{}/rest/text/detect_language", &self.base_url))
120                .header("Accept", "application/json")
121                .header("Referer", "")
122                .header("Content-Type", "application/json")
123                .body(text.to_string())
124                .send()
125                .await?;
126
127        Ok(
128            response
129                .json()
130                .await?
131        )
132    }
133
134    pub async fn create_category_filter(
135        &self,
136        positive_examples: Vec<String>,
137        negative_examples: Vec<String>,
138        retina_name: Option<&str>,
139    ) -> Result<CreateCategoryFilterResponse, Box<dyn Error>> {
140        let retina_name = retina_name.unwrap_or("en_general");
141
142        let positive_examples = positive_examples
143            .into_iter()
144            .map(|text| TextEnvelope { text })
145            .collect();
146
147        let negative_examples = negative_examples
148            .into_iter()
149            .map(|text| TextEnvelope { text })
150            .collect();
151
152        let request = CreateCategoryFilterRequest {
153            category_name: None,
154            positive_examples,
155            negative_examples,
156        };
157
158        Ok(
159            self.client
160                .post(
161                    format!(
162                        "{}/rest/classify/create_category_filter?retina_name={}&filter_name={}",
163                        &self.base_url,
164                        retina_name,
165                        "filter_name"
166                    )
167                )
168                .header("Accept", "application/json")
169                .header("Referer", "")
170                .header("Content-Type", "application/json")
171                .body(serde_json::to_string(&request)?)
172                .send()
173                .await?
174                .json()
175                .await?
176        )
177    }
178
179    pub async fn get_compare(
180        &self,
181        (text1, text2): (&str, &str),
182        retina_name: Option<&str>,
183    ) -> Result<CompareResponse, Box<dyn Error>> {
184        let retina_name = retina_name.unwrap_or("en_general");
185
186        Ok(
187            self.client
188                .post(format!("{}/rest/compare?retina_name={}", &self.base_url, retina_name))
189                .header("Accept", "application/json")
190                .header("Referer", "")
191                .header("Content-Type", "application/json")
192                .body(
193                    serde_json::to_string(
194                        &vec![
195                            TextEnvelope::new(text1),
196                            TextEnvelope::new(text2),
197                        ]
198                    )?
199                )
200                .send()
201                .await?
202                .json()
203                .await?
204        )
205    }
206
207    pub async fn get_terms(
208        &self,
209        retina_name: Option<&str>,
210        term: Option<&str>,
211        get_fingerpint: Option<bool>,
212        start_index: Option<u32>,
213        max_results: Option<u32>,
214    ) -> Result<GetTermsResponse, Box<dyn Error>> {
215        let retina_name = retina_name.unwrap_or("en_general");
216
217        let query =
218            GetTermsRequest {
219                retina_name: retina_name.to_string(),
220                term: term.map(|term| term.to_string()),
221                start_index,
222                max_results,
223                get_fingerprint: get_fingerpint.unwrap_or(false),
224            };
225
226        let response =
227            self.client
228                .get(format!("{}/rest/terms", &self.base_url))
229                .header("Accept", "application/json")
230                .header("Referer", "")
231                .header("Content-Type", "application/json")
232                .query(&query)
233                .send()
234                .await?;
235
236        Ok(
237            response
238                .json()
239                .await?
240        )
241    }
242
243    pub async fn get_terms_contexts(
244        &self,
245        term: &str,
246        retina_name: Option<&str>,
247        get_fingerpint: Option<bool>,
248        start_index: Option<u32>,
249        max_results: Option<u32>,
250    ) -> Result<GetTermsContextsResponse, Box<dyn Error>> {
251        let retina_name = retina_name.unwrap_or("en_general");
252
253        let query =
254            GetTermsContextsRequest {
255                retina_name: retina_name.to_string(),
256                term: term.to_string(),
257                start_index,
258                max_results,
259                get_fingerprint: get_fingerpint.unwrap_or(false),
260            };
261
262        let response =
263            self.client
264                .get(format!("{}/rest/terms/contexts", &self.base_url))
265                .header("Accept", "application/json")
266                .header("Referer", "")
267                .header("Content-Type", "application/json")
268                .query(&query)
269                .send()
270                .await?;
271
272        Ok(
273            response
274                .json()
275                .await?
276        )
277    }
278
279    pub async fn get_terms_similar_terms(
280        &self,
281        term: &str,
282        retina_name: Option<&str>,
283        context_id: Option<&str>,
284        pos_type: Option<PosType>,
285        get_fingerpint: Option<bool>,
286        start_index: Option<u32>,
287        max_results: Option<u32>,
288    ) -> Result<GetTermsResponse, Box<dyn Error>> {
289        let retina_name = retina_name.unwrap_or("en_general");
290
291        let query =
292            GetTermsSimilarTermsRequest {
293                retina_name: retina_name.to_string(),
294                term: term.to_string(),
295                context_id: context_id.map(|c| c.to_string()),
296                pos_type,
297                start_index,
298                max_results,
299                get_fingerprint: get_fingerpint.unwrap_or(false),
300            };
301
302        let response =
303            self.client
304                .get(format!("{}/rest/terms/contexts", &self.base_url))
305                .header("Accept", "application/json")
306                .header("Referer", "")
307                .header("Content-Type", "application/json")
308                .query(&query)
309                .send()
310                .await?;
311
312        Ok(
313            response
314                .json()
315                .await?
316        )
317    }
318}