pants_store/
output.rs

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}