diff --git a/src/commands/decode.rs b/src/commands/decode.rs index b545f53..4cff4a2 100644 --- a/src/commands/decode.rs +++ b/src/commands/decode.rs @@ -3,6 +3,7 @@ use crate::db::{ClipboardDb, SqliteClipboardDb}; use std::io::{Read, Write}; use crate::db::StashError; +use wl_clipboard_rs::paste::{ClipboardType, MimeType, Seat, get_contents}; pub trait DecodeCommand { fn decode( @@ -16,12 +17,59 @@ pub trait DecodeCommand { impl DecodeCommand for SqliteClipboardDb { fn decode( &self, - in_: impl Read, - out: impl Write, + mut in_: impl Read, + mut out: impl Write, input: Option, ) -> Result<(), StashError> { - self.decode_entry(in_, out, input)?; - log::info!("Entry decoded"); + let input_str = if let Some(s) = input { + s + } else { + let mut buf = String::new(); + if let Err(e) = in_.read_to_string(&mut buf) { + log::error!("Failed to read stdin for decode: {e}"); + } + buf + }; + + // If input is empty or whitespace, treat as error and trigger fallback + if input_str.trim().is_empty() { + log::info!("No input provided to decode; relaying clipboard to stdout"); + if let Ok((mut reader, _mime)) = + get_contents(ClipboardType::Regular, Seat::Unspecified, MimeType::Any) + { + let mut buf = Vec::new(); + if let Err(err) = reader.read_to_end(&mut buf) { + log::error!("Failed to read clipboard for relay: {err}"); + } else { + let _ = out.write_all(&buf); + } + } else { + log::error!("Failed to get clipboard contents for relay"); + } + return Ok(()); + } + + // Try decode as usual + match self.decode_entry(input_str.as_bytes(), &mut out, Some(input_str.clone())) { + Ok(()) => { + log::info!("Entry decoded"); + } + Err(e) => { + log::error!("Failed to decode entry: {e}"); + if let Ok((mut reader, _mime)) = + get_contents(ClipboardType::Regular, Seat::Unspecified, MimeType::Any) + { + let mut buf = Vec::new(); + if let Err(err) = reader.read_to_end(&mut buf) { + log::error!("Failed to read clipboard for relay: {err}"); + } else { + let _ = out.write_all(&buf); + } + } else { + log::error!("Failed to get clipboard contents for relay"); + } + } + } Ok(()) } } diff --git a/src/db/mod.rs b/src/db/mod.rs index 7b18dee..0e7b943 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -145,8 +145,7 @@ impl SqliteClipboardDb { })); } - Ok(serde_json::to_string_pretty(&entries) - .map_err(|e| StashError::ListDecode(e.to_string()))?) + serde_json::to_string_pretty(&entries).map_err(|e| StashError::ListDecode(e.to_string())) } } diff --git a/src/main.rs b/src/main.rs index f41ccac..ecfaa3e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -148,15 +148,15 @@ fn main() { // Implement JSON output match db.list_json() { Ok(json) => { - println!("{}", json); + println!("{json}"); } Err(e) => { - log::error!("Failed to list entries as JSON: {}", e); + log::error!("Failed to list entries as JSON: {e}"); } } } _ => { - log::error!("Unsupported format: {}", format); + log::error!("Unsupported format: {format}"); } } }