1use std::error::Error;
2
3use crate::{
4 cli::{CLICommands, EntryStyle},
5 errors::ConversionError,
6 schema::Schema,
7 store::Store,
8};
9
10#[derive(Debug, Clone)]
11pub enum Instructions {
12 Interaction(Interaction),
13 Commands(Commands),
14}
15
16#[derive(Debug, Clone)]
17pub enum Command {
18 Read { key: String },
19 Update { key: String, value: Store },
20 Delete { key: String },
21}
22
23#[derive(Debug, Clone)]
24pub enum Interaction {
25 List,
26 Backup,
27 Rotate,
28}
29
30#[derive(Debug, Clone)]
31pub struct Commands {
32 pub commands: Vec<Command>,
33}
34
35impl IntoIterator for Commands {
36 type Item = Command;
37 type IntoIter = std::vec::IntoIter<Self::Item>;
38
39 fn into_iter(self) -> Self::IntoIter {
40 self.commands.into_iter()
41 }
42}
43
44impl Default for Commands {
45 fn default() -> Self {
46 Self::new()
47 }
48}
49
50impl Commands {
51 pub fn new() -> Self {
52 Self { commands: vec![] }
53 }
54
55 pub fn push(&mut self, command: Command) {
56 self.commands.push(command);
57 }
58
59 }
64
65impl Instructions {
66 fn handle_new(name: String, schema: Schema, style: &str) -> Result<Self, Box<dyn Error>> {
67 match schema.get(&name) {
68 Some(_) => Err(Box::new(ConversionError::Exists)),
69 None => {
70 let value = Store::prompt(style)?;
71 let commands: Commands = vec![Command::Update { key: name, value }].into();
72 Ok(commands.into())
73 }
74 }
75 }
76 pub fn from_commands(commands: CLICommands, schema: Schema) -> Result<Self, Box<dyn Error>> {
77 match commands {
78 CLICommands::New { style } => match style {
79 EntryStyle::Password { name } => Self::handle_new(name, schema, "password"),
80 EntryStyle::UsernamePassword { name } => {
81 Self::handle_new(name, schema, "username-password")
82 }
83 },
84 CLICommands::Get { key } => {
85 let commands: Commands = vec![Command::Read { key }].into();
86 Ok(commands.into())
87 }
88 CLICommands::Update { key } => match schema.get(&key) {
89 None => Err(Box::new(ConversionError::NoEntry)),
90 Some(value) => {
91 let value = Store::prompt(value)?;
92 let commands: Commands = vec![Command::Update { key, value }].into();
93 Ok(commands.into())
94 }
95 },
96 CLICommands::Delete { key } => {
97 let commands: Commands = vec![Command::Delete { key }].into();
98 Ok(commands.into())
99 }
100 CLICommands::List => Ok(Interaction::List.into()),
101 CLICommands::Backup => Ok(Interaction::Backup.into()),
102 CLICommands::Rotate => Ok(Interaction::Rotate.into()),
103 _ => todo!(),
104 }
105 }
106}
107
108impl From<Vec<Command>> for Commands {
109 fn from(value: Vec<Command>) -> Self {
110 Self { commands: value }
111 }
112}
113
114impl From<Commands> for Instructions {
115 fn from(value: Commands) -> Self {
116 Instructions::Commands(value)
117 }
118}
119
120impl From<Interaction> for Instructions {
121 fn from(value: Interaction) -> Self {
122 Instructions::Interaction(value)
123 }
124}