Skip to main content

psyche_subtitle_toolkit/translation/
mod.rs

1/// Anthropic Messages API provider (`/v1/messages`).
2pub mod anthropic;
3/// DeepL Translation API provider (`/v2/translate`).
4pub mod deepl;
5/// Google Gemini `generateContent` provider.
6pub mod gemini;
7/// Google Cloud Translation v2 provider (`/language/translate/v2`).
8pub mod google;
9/// Ollama local LLM provider (`/api/generate`).
10pub mod ollama;
11/// OpenAI Chat Completions provider (`/v1/chat/completions`).
12pub mod openai;
13/// OpenRouter unified LLM provider (`/api/v1/chat/completions`).
14pub mod openrouter;
15
16use async_trait::async_trait;
17
18use crate::error::Result;
19
20/// A translation backend.
21///
22/// Implement this trait to provide custom translation providers.
23/// Built-in implementations:
24/// - [`anthropic::AnthropicTranslator`] — calls the Anthropic Messages API
25/// - [`ollama::OllamaTranslator`] — calls the Ollama `/api/generate` endpoint
26/// - [`openai::OpenAiTranslator`] — calls the OpenAI `/v1/chat/completions` endpoint
27/// - [`deepl::DeepLTranslator`] — calls the DeepL `/v2/translate` endpoint
28/// - [`google::GoogleTranslator`] — calls the Google Cloud Translation v2 endpoint
29/// - [`gemini::GeminiTranslator`] — calls the Google Gemini `generateContent` endpoint
30/// - [`openrouter::OpenRouterTranslator`] — calls the OpenRouter `/api/v1/chat/completions` endpoint
31///
32/// Each provider owns its own prompt construction and HTTP client.
33/// The pipeline calls [`Translator::translate`] with numbered subtitle text
34/// in `<N> text` format and expects the same format back.
35#[async_trait]
36pub trait Translator: Send + Sync {
37    /// Translate the source text and return the translated string.
38    ///
39    /// The returned string should preserve the `<N>` numbered line format
40    /// from the input.
41    async fn translate(&self, request: TranslationRequest<'_>) -> Result<String>;
42}
43
44/// A translation request sent to a [`Translator`].
45#[derive(Debug, Clone)]
46pub struct TranslationRequest<'a> {
47    /// Numbered subtitle dialogue text in `<N> text` format.
48    pub source_text: &'a str,
49    /// Target language code (e.g. `"pt-BR"`, `"en"`, `"ja"`).
50    pub target_language: &'a str,
51    /// Optional source language code (e.g. `"en"`, `"ja"`).
52    /// Providers that support it (DeepL, Google) pass it to the API.
53    /// LLM providers include it in the prompt when set.
54    pub source_language: Option<&'a str>,
55}