yandex_translate_v2/
lib.rs

1#![warn(clippy::all, clippy::pedantic)]
2#![doc = include_str!("../README.md")]
3
4#[cfg(all(feature = "blocking", feature = "async"))]
5compile_error!("features `blocking` and `async` are mutually exclusive");
6
7use serde::{Deserialize, Serialize};
8use thiserror::Error;
9
10const API_BASE_URL: &str = "https://translate.api.cloud.yandex.net/translate/v2";
11
12#[derive(Debug, Error)]
13pub enum Error {
14    #[error("HTTP request failed: {0}")]
15    RequestFailed(#[from] reqwest::Error),
16
17    #[error("JSON serialization/deserialization failed: {0}")]
18    JsonError(#[from] serde_json::Error),
19
20    #[error("API error: {0}")]
21    ApiError(String),
22
23    #[error("Invalid configuration: {0}")]
24    ConfigError(String),
25}
26
27pub type Result<T> = std::result::Result<T, Error>;
28
29/// Authentication method for the Yandex Translate API.
30///
31/// This enum defines how requests to the API are authenticated.
32/// Exactly one authentication method must be provided when creating
33/// a translate client.
34#[derive(Debug, Clone)]
35pub enum AuthMethod {
36    /// Authenticate using a Yandex Cloud API key.
37    ///
38    /// The API key is sent in the `Authorization` header using the
39    /// `Api-Key` scheme.
40    ApiKey(String),
41
42    /// Authenticate using an IAM bearer token.
43    ///
44    /// The token is sent in the `Authorization` header using the
45    /// `Bearer` scheme.
46    IAMToken(String),
47}
48
49/// Request body for a translation operation.
50///
51/// This structure is serialized to JSON and sent to the `/translate`
52/// endpoint of the Yandex Translate API.
53///
54/// The lifetime parameter ensures that the request can borrow data
55/// without requiring additional allocations.
56#[derive(Debug, Clone, Copy, Serialize)]
57#[serde(rename_all = "camelCase")]
58pub struct TranslateRequest<'a> {
59    /// Identifier of the Yandex Cloud folder.
60    ///
61    /// This specifies the cloud folder where the translation request
62    /// is billed and authorized.
63    pub folder_id: &'a str,
64
65    /// Texts to be translated.
66    ///
67    /// Each element in the slice is translated independently, and the
68    /// results are returned in the same order.
69    pub texts: &'a [&'a str],
70
71    /// Target language code.
72    ///
73    /// Uses ISO 639-1 language codes (for example, `"en"`, `"ru"`, `"de"`).
74    pub target_language_code: &'a str,
75
76    /// Optional source language code.
77    ///
78    /// If not provided, the API will attempt to automatically detect
79    /// the source language for each input text.
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub source_language_code: Option<&'a str>,
82}
83
84/// Individual translation result.
85///
86/// Each input text produces one `Translation` entry in the response.
87#[derive(Debug, Clone, Deserialize)]
88#[serde(rename_all = "camelCase")]
89pub struct Translation {
90    /// Translated text.
91    pub text: String,
92
93    /// Detected source language code.
94    ///
95    /// This field is present only when the source language was not
96    /// explicitly specified in the request.
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub detected_language_code: Option<String>,
99}
100
101/// Response returned by the Yandex Translate API.
102///
103/// The response contains one [`Translation`] for each input text,
104/// in the same order as they were provided in the request.
105#[derive(Debug, Clone, Deserialize)]
106pub struct TranslateResponse {
107    /// List of translation results.
108    pub translations: Vec<Translation>,
109}
110
111#[cfg(feature = "blocking")]
112pub mod blocking;
113#[cfg(feature = "blocking")]
114pub use blocking::YandexTranslateClient;
115
116#[cfg(feature = "async")]
117pub mod asynchronous;
118#[cfg(feature = "async")]
119pub use asynchronous::YandexTranslateClient;