1use std::{error::Error, fmt::Display, path::PathBuf, thread, time::Duration};
2
3use arboard::Clipboard;
4
5use crate::{reads::Reads, store::Store};
6
7#[derive(Debug)]
8pub enum Output {
9 Read(Reads<Store>),
10 List(Vec<String>),
11 Backup(PathBuf),
12 Nothing,
13}
14
15impl From<Reads<Store>> for Output {
16 fn from(value: Reads<Store>) -> Self {
17 Output::Read(value)
18 }
19}
20
21impl From<Vec<String>> for Output {
22 fn from(value: Vec<String>) -> Self {
23 Output::List(value)
24 }
25}
26
27impl From<()> for Output {
28 fn from(_value: ()) -> Self {
29 Output::Nothing
30 }
31}
32
33impl Output {
34 pub fn finish(&self) -> Result<(), Box<dyn Error>> {
35 match self {
36 Self::Read(reads) => {
37 if !reads.data.is_empty() {
38 let mut clipboard = Clipboard::new()?;
39 let orig = clipboard.get_text().unwrap_or("".to_string());
40 for (key, value) in reads.data.clone().into_iter() {
41 println!("{}", key);
42 match value {
43 Store::Password(pass) => {
44 clipboard.set_text(pass)?;
45 println!(" password: <Copied to clipboard>");
46 thread::sleep(Duration::from_secs(5));
47 }
48 Store::UsernamePassword(user, pass) => {
49 clipboard.set_text(pass)?;
50 println!(" username: {}", user);
51 println!(" password: <Copied to clipboard>");
52 thread::sleep(Duration::from_secs(5));
53 }
54 }
55 }
56 clipboard.set_text(orig)?;
57 println!("Resetting clipboard");
58 thread::sleep(Duration::from_secs(1));
59 } else {
60 println!("Nothing read from vault");
61 }
62
63 Ok(())
64 }
65 Self::List(items) => {
66 if items.is_empty() {
67 println!("No entries");
68 } else {
69 println!("Available entries:");
70 for item in items {
71 println!("- {}", item);
72 }
73 }
74 Ok(())
75 }
76 Self::Backup(path) => {
77 println!("Backed up to {}", path.to_str().unwrap());
78 Ok(())
79 }
80 _ => Ok(()),
81 }
82 }
83}
84
85impl Display for Output {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 match self {
88 Self::Nothing => write!(f, ""),
89 Self::Backup(path) => write!(f, "Backed up to {}", path.to_str().unwrap()),
90 Self::List(items) => {
91 if items.is_empty() {
92 write!(f, "No entries")
93 } else {
94 for item in items {
95 writeln!(f, "{}", item)?;
96 }
97 Ok(())
98 }
99 }
100 Self::Read(reads) => {
101 write!(f, "{}", reads)
102 }
103 }
104 }
105}