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}