deepl_rustls/
lib.rs

1//! # deepl-rs
2//!
3//! Deepl-rs is a simple library for making requests to the DeepL API endpoint easier.
4//! And it also provides types wrapping to guarantee runtime safety.
5//!
6//! This is still a **WORK IN PROGRESS** library, please open an issue on GitHub to request
7//! features. Be aware breaking changes will be released frequently.
8//!
9//! # Usage
10//!
11//! ```rust
12//! use deepl::DeepLApi;
13//!
14//! let key = std::env::var("DEEPL_API_KEY").unwrap();
15//! let api = DeepLApi::with(&key).new();
16//! let response = api.translate_text("Hello World", Lang::ZH).await.unwrap();
17//!
18//! assert!(!response.translations.is_empty());
19//! ```
20//!
21//! See [`DeepLApi`] for detailed usage.
22//!
23//! # License
24//!
25//! This project is licensed under MIT license.
26//!
27
28mod endpoint;
29mod lang;
30
31use std::sync::Arc;
32
33//- Type Re-exporting
34pub use endpoint::{
35    document::{DocumentStatusResp, DocumentTranslateStatus, UploadDocumentResp},
36    glossary,
37    languages::{LangInfo, LangType},
38    translate::{TagHandling, TranslateTextResp},
39    usage::UsageResponse,
40    Error, Formality,
41};
42pub use lang::{Lang, LangConvertError};
43pub use reqwest;
44//-
45
46/// A struct that contains necessary data for runtime. Data is stored in
47/// [`Arc`], so it is cheap to clone in your App's code.
48///
49/// # Example
50///
51/// ```
52/// // simple API creation
53/// let deepl = DeepLApi::with("Your DeepL Key").new();
54///
55/// // **OR** customize it
56/// let duration = std::time::Duration::from_secs(30);
57/// let client = reqwest::Client::builder()
58///         .timeout(duration)
59///         .build()
60///         .unwrap();
61///
62/// // use the pro version API, and a custom client with
63/// // 30 secs timeout
64/// let deepl = DeepLApi::with("Your DeepL Key")
65///                 .is_pro(true)
66///                 .client(client)
67///                 .new();
68/// ```
69#[derive(Debug, Clone)]
70pub struct DeepLApi {
71    inner: Arc<DeepLApiInner>,
72}
73
74/// The inner instance which actually holds data
75#[derive(Debug)]
76struct DeepLApiInner {
77    client: reqwest::Client,
78    key: String,
79    endpoint: reqwest::Url,
80}
81
82impl DeepLApi {
83    /// Create a new api instance with auth key.
84    pub fn with(key: &str) -> DeepLApiBuilder {
85        DeepLApiBuilder::init(key.to_string())
86    }
87
88    fn del(&self, url: reqwest::Url) -> reqwest::RequestBuilder {
89        self.inner
90            .client
91            .delete(url)
92            .header("Authorization", &self.inner.key)
93    }
94
95    fn post(&self, url: reqwest::Url) -> reqwest::RequestBuilder {
96        self.inner
97            .client
98            .post(url)
99            .header("Authorization", &self.inner.key)
100    }
101
102    fn get(&self, url: reqwest::Url) -> reqwest::RequestBuilder {
103        self.inner
104            .client
105            .get(url)
106            .header("Authorization", &self.inner.key)
107    }
108
109    fn get_endpoint(&self, route: &str) -> reqwest::Url {
110        self.inner.endpoint.join(route).unwrap()
111    }
112}
113
114/// The builder struct. **DO NOT USE IT IN YOUR APPS**
115pub struct DeepLApiBuilder {
116    is_pro: bool,
117    client: Option<reqwest::Client>,
118    key: String,
119}
120
121impl DeepLApiBuilder {
122    fn init(key: String) -> Self {
123        Self {
124            key,
125            is_pro: false,
126            client: None,
127        }
128    }
129
130    /// Set the a user defined [`reqwest::Client`]
131    pub fn client(&mut self, c: reqwest::Client) -> &mut Self {
132        self.client = Some(c);
133        self
134    }
135
136    /// Set if you want to use the pro version DeepL Api
137    pub fn is_pro(&mut self, is_pro: bool) -> &mut Self {
138        self.is_pro = is_pro;
139        self
140    }
141
142    /// Create a new instance of the DeepLApi
143    pub fn new(&self) -> DeepLApi {
144        let client = self.client.clone().unwrap_or_else(reqwest::Client::new);
145        let endpoint = if self.is_pro || !self.key.ends_with(":fx") {
146            "https://api.deepl.com/v2/"
147        } else {
148            "https://api-free.deepl.com/v2/"
149        };
150
151        let inner = DeepLApiInner {
152            key: format!("DeepL-Auth-Key {}", self.key),
153            client,
154            endpoint: reqwest::Url::parse(endpoint).unwrap(),
155        };
156
157        DeepLApi {
158            inner: Arc::new(inner),
159        }
160    }
161}