use crate::clipboard::X11Clipboard;
use crate::error::TalkError;
use crate::telemetry::TelemetrySink;
use async_trait::async_trait;
use super::nodes::{
chunk::ChunkNode, clipboard::ClipboardNode, detect::DetectDisplayServerNode,
foreground_app::MatchForegroundAppNode, wm_class::MatchWmClassNode, xtest::XtestTypeNode,
};
pub use crate::paste_config::{ForegroundAppPattern, PasteNodeConfig, WmClassPattern};
pub struct PasteCtx<'a> {
pub target_window: Option<&'a str>,
pub delete_chars_before_paste: usize,
pub t_stop: Option<std::time::Instant>,
pub sink: &'a dyn TelemetrySink,
pub(crate) clipboard: &'a X11Clipboard,
pub(crate) target_client_base: Option<u32>,
pub(crate) expected_target_fetches: std::sync::Arc<std::sync::atomic::AtomicU32>,
pub(crate) alert: Option<std::sync::Arc<dyn Fn() + Send + Sync>>,
}
#[async_trait]
pub trait PasteNode: Send + Sync {
async fn paste(&self, text: &str, ctx: &PasteCtx<'_>) -> Result<(), TalkError>;
fn chunks_text(&self) -> bool {
false
}
}
impl PasteNodeConfig {
pub fn build(&self) -> Box<dyn PasteNode> {
match self {
Self::DetectDisplayServer { x11, wayland } => Box::new(DetectDisplayServerNode {
x11: x11.build(),
wayland: wayland.as_ref().map(|w| w.build()),
}),
Self::MatchWmClass { patterns, default } => {
let compiled = patterns
.iter()
.map(|p| (p.pattern.clone(), p.child.build()))
.collect();
Box::new(MatchWmClassNode {
patterns: compiled,
default: default.build(),
})
}
Self::MatchForegroundApp { patterns, default } => {
let compiled = patterns
.iter()
.map(|pattern| (pattern.pattern.clone(), pattern.child.build()))
.collect();
Box::new(MatchForegroundAppNode::system(compiled, default.build()))
}
Self::Chunk { chunk_chars, child } => Box::new(ChunkNode {
chunk_chars: *chunk_chars,
child: child.build(),
}),
Self::Clipboard {
shortcut,
restore_settle_ms,
chunk_fetch_timeout_ms,
target_quiescence_ms,
target_fetch_retries,
} => Box::new(ClipboardNode {
shortcut: *shortcut,
restore_settle_ms: *restore_settle_ms,
chunk_fetch_timeout_ms: *chunk_fetch_timeout_ms,
target_quiescence_ms: *target_quiescence_ms,
target_fetch_retries: *target_fetch_retries,
}),
Self::XtestType {} => Box::new(XtestTypeNode {}),
}
}
}