1use serde_json::Value;
2use std::fmt;
3
4pub enum QText {
6 Str(String),
7 ListStr(Vec<String>),
8}
9
10impl QText {
11 fn is_empty(&self) -> bool {
12 match self {
13 QText::Str(value) => value.is_empty(),
14 QText::ListStr(value) => value.is_empty(),
15 }
16 }
17}
18impl From<String> for QText {
19 fn from(value: String) -> QText {
20 QText::Str(value)
21 }
22}
23
24impl From<Vec<String>> for QText {
25 fn from(value: Vec<String>) -> QText {
26 QText::ListStr(value)
27 }
28}
29
30impl fmt::Display for QText {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 match self {
33 QText::Str(value) => write!(f, "{}", value),
34 QText::ListStr(value) => write!(f, "{:?}", value),
35 }
36 }
37}
38
39async fn get_request_body<T: Into<QText>>(text: T, api_key: &str) -> Value {
41 debug_assert!(
42 !api_key.is_empty(),
43 "you need to get an API_KEY for this to work. \n\
44 Get one for free here: https://detectlanguage.com/documentation"
45 );
46
47 let text = T::into(text);
48
49 debug_assert!(!text.is_empty(), "Please provide an input text");
50
51 let mut client = reqwest::Client::builder();
52 #[cfg(not(target_arch = "wasm32"))]
53 {
54 client = client.user_agent("Detect Language API Rust Client 1.4.0");
55 }
56
57 let req: Value = client
58 .build()
59 .unwrap()
60 .post("https://ws.detectlanguage.com/0.2/detect")
61 .header("User-Agent", format!("Bearer {api_key}").as_str())
62 .json(&serde_json::json!({
63 "q": text.to_string()
64 }))
65 .send()
66 .await
67 .unwrap()
68 .json()
69 .await
70 .unwrap();
71
72 println!("req -> {:?}", &req);
73 req["data"].clone()
74}
75
76pub async fn single(text: &str, api_key: &str, detailed: bool) -> Value {
78 let body = get_request_body(text.to_string(), api_key).await;
79 println!("body -> {:?}", &body);
80 let detections = &body["detections"];
81
82 if detailed {
83 return detections[0].clone();
84 }
85
86 detections[0]["language"].clone()
87}
88
89pub async fn batch(text_list: Vec<String>, api_key: &str, detailed: bool) -> Vec<Value> {
91 let body = get_request_body(text_list, api_key).await;
92 println!("body -> {:?}", &body);
93 let detections = &body["detections"];
94
95 let Value::Array(detections) = detections else { unreachable!() };
96 let res = detections.iter().map(|obj| obj[0].clone()).collect();
97
98 if detailed {
99 res
100 } else {
101 res.iter().map(|obj| obj["language"].clone()).collect()
102 }
103}