feat: add transcription backend contracts

This commit is contained in:
Evandro committed 2026-06-10 20:55:10 -03:00
1 parent 3b05cb22a0
commit 54e8b42330
9 files changed
+461

No files matched your search

+116
View File
@@ -0,0 +1,116 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct FocusTarget {
pub platform: Platform,
pub display_server: DisplayServer,
pub window_title: Option<String>,
pub process_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub enum Platform {
Windows,
Linux,
Unknown,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub enum DisplayServer {
Windows,
X11,
Wayland,
Unknown,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub enum InsertCapability {
Full,
Partial,
Unsupported,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub enum InsertMethod {
ClipboardPaste,
KeyTyping,
ManualCopy,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct InsertRequest {
pub text: String,
pub target: Option<FocusTarget>,
pub method: InsertMethod,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct InsertResult {
pub capability: InsertCapability,
pub method_used: InsertMethod,
pub message: String,
}
pub trait TextInjector {
fn can_insert(&self, target: Option<&FocusTarget>) -> InsertCapability;
fn insert_text(&self, request: InsertRequest) -> InsertResult;
}
#[derive(Debug, Default, Clone)]
pub struct FallbackInjector;
impl TextInjector for FallbackInjector {
fn can_insert(&self, target: Option<&FocusTarget>) -> InsertCapability {
match target.map(|target| &target.display_server) {
Some(DisplayServer::Windows | DisplayServer::X11) => InsertCapability::Full,
Some(DisplayServer::Wayland) => InsertCapability::Partial,
_ => InsertCapability::Unsupported,
}
}
fn insert_text(&self, request: InsertRequest) -> InsertResult {
let capability = self.can_insert(request.target.as_ref());
let message = match capability {
InsertCapability::Full => {
"Inserção automática preparada; implementação nativa será conectada ao adaptador."
}
InsertCapability::Partial => {
"Wayland pode bloquear automação. Texto mantido para cópia manual com Ctrl+V."
}
InsertCapability::Unsupported => {
"Destino não confiável. Copie o texto manualmente a partir do modal."
}
};
InsertResult {
capability,
method_used: request.method,
message: message.to_string(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn wayland_reports_partial_insert_capability() {
let injector = FallbackInjector;
let target = FocusTarget {
platform: Platform::Linux,
display_server: DisplayServer::Wayland,
window_title: Some("Editor".to_string()),
process_name: Some("app".to_string()),
};
assert_eq!(injector.can_insert(Some(&target)), InsertCapability::Partial);
}
}