use std::sync::{Arc, OnceLock, RwLock};
use async_trait::async_trait;
use super::lang::Lang;
use crate::error::Result;
#[async_trait]
pub trait TranslationBackend: Send + Sync {
fn id(&self) -> &'static str {
"custom"
}
fn supports(&self, target: &Lang) -> bool {
let _ = target;
true
}
async fn translate_batch(&self, texts: &[String], target: &Lang) -> Result<Vec<String>>;
}
fn registry() -> &'static RwLock<Option<Arc<dyn TranslationBackend>>> {
static REGISTRY: OnceLock<RwLock<Option<Arc<dyn TranslationBackend>>>> = OnceLock::new();
REGISTRY.get_or_init(|| RwLock::new(None))
}
pub fn set_backend(backend: Arc<dyn TranslationBackend>) {
if let Ok(mut slot) = registry().write() {
*slot = Some(backend);
}
}
pub(crate) fn active_backend() -> Option<Arc<dyn TranslationBackend>> {
if let Ok(slot) = registry().read()
&& let Some(backend) = slot.as_ref()
{
return Some(backend.clone());
}
#[cfg(feature = "translation-offline")]
{
Some(super::opusmt::shared())
}
#[cfg(not(feature = "translation-offline"))]
None
}