1use comfy_table::{Table, presets::UTF8_FULL};
2use core_types::{EventKind, SecurityLevel, TrustProfileName};
3use owo_colors::OwoColorize;
4
5use crate::ipc::{connect, rpc};
6
7pub(crate) async fn cmd_clipboard_history(profile: &str, limit: u32) -> anyhow::Result<()> {
8 let client = connect().await?;
9 let profile = TrustProfileName::try_from(profile).map_err(|e| anyhow::anyhow!("{e}"))?;
10
11 let event = EventKind::ClipboardHistory { profile, limit };
12
13 match rpc(&client, event, SecurityLevel::Internal).await? {
14 EventKind::ClipboardHistoryResponse { entries } => {
15 if entries.is_empty() {
16 println!("{}", "No clipboard history.".dimmed());
17 } else {
18 let mut table = Table::new();
19 table.load_preset(UTF8_FULL);
20 table.set_header(vec!["ID", "Type", "Sensitivity", "Preview"]);
21
22 for e in &entries {
23 table.add_row(vec![
24 &e.entry_id.to_string(),
25 &e.content_type,
26 &format!("{:?}", e.sensitivity),
27 &e.preview,
28 ]);
29 }
30
31 println!("{table}");
32 }
33 }
34 other => anyhow::bail!("unexpected response: {other:?}"),
35 }
36
37 Ok(())
38}
39
40pub(crate) async fn cmd_clipboard_clear(profile: &str) -> anyhow::Result<()> {
41 let client = connect().await?;
42 let profile = TrustProfileName::try_from(profile).map_err(|e| anyhow::anyhow!("{e}"))?;
43
44 match rpc(
45 &client,
46 EventKind::ClipboardClear { profile },
47 SecurityLevel::Internal,
48 )
49 .await?
50 {
51 EventKind::ClipboardClearResponse { success: true } => {
52 println!("{}", "Clipboard history cleared.".green());
53 }
54 EventKind::ClipboardClearResponse { success: false } => {
55 anyhow::bail!("failed to clear clipboard history");
56 }
57 other => anyhow::bail!("unexpected response: {other:?}"),
58 }
59
60 Ok(())
61}
62
63pub(crate) async fn cmd_clipboard_get(entry_id: &str) -> anyhow::Result<()> {
64 let client = connect().await?;
65
66 let uuid = entry_id.strip_prefix("clip-").unwrap_or(entry_id);
67 let uuid: uuid::Uuid = uuid
68 .parse()
69 .map_err(|_| anyhow::anyhow!("invalid clipboard entry ID: {entry_id}"))?;
70 let entry_id_parsed = core_types::ClipboardEntryId::from_uuid(uuid);
71
72 match rpc(
73 &client,
74 EventKind::ClipboardGet {
75 entry_id: entry_id_parsed,
76 },
77 SecurityLevel::Internal,
78 )
79 .await?
80 {
81 EventKind::ClipboardGetResponse {
82 content: Some(c),
83 content_type,
84 } => {
85 if let Some(ct) = content_type {
86 eprintln!("Content-Type: {ct}");
87 }
88 println!("{c}");
89 }
90 EventKind::ClipboardGetResponse { content: None, .. } => {
91 anyhow::bail!("clipboard entry not found or expired");
92 }
93 other => anyhow::bail!("unexpected response: {other:?}"),
94 }
95
96 Ok(())
97}