|
|
|
@ -27,13 +27,13 @@ enum Commands {
|
|
|
|
|
/// Lists all ids stored in db
|
|
|
|
|
List, |
|
|
|
|
|
|
|
|
|
/// Show content of item
|
|
|
|
|
/// Show content of an item
|
|
|
|
|
Show { |
|
|
|
|
#[arg(value_name="item_id")] |
|
|
|
|
id: String |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
/// Adds new item with unique id to the db
|
|
|
|
|
/// Adds new item with unique id to the storage
|
|
|
|
|
Add { |
|
|
|
|
#[arg(value_name="item_id")] |
|
|
|
|
id: String |
|
|
|
@ -68,139 +68,156 @@ fn get_prompt(question: &str) -> io::Result<PROMPT> {
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO: change password functionality
|
|
|
|
|
// TODO: return storage inited
|
|
|
|
|
fn login() -> io::Result<String> { |
|
|
|
|
print!("Enter passphrase for storage: "); |
|
|
|
|
io::stdout().flush()?; |
|
|
|
|
// TODO: check in db
|
|
|
|
|
// TODO: return error if db is not inited
|
|
|
|
|
let password = rpassword::read_password()?; |
|
|
|
|
if password != "pass" { |
|
|
|
|
return Err(io::Error::new(io::ErrorKind::InvalidData, "Wrong passphrase")); |
|
|
|
|
} |
|
|
|
|
print!("\x1B[1A\x1B[2K"); // Move cursor up one line and clear that line
|
|
|
|
|
io::stdout().flush()?; // Ensure the changes are reflected immediately
|
|
|
|
|
Ok(String::from(password)) |
|
|
|
|
struct MPS { |
|
|
|
|
storage: Option<Storage> |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn init() -> io::Result<()> { |
|
|
|
|
if Storage::is_inited() { |
|
|
|
|
return Err(io::Error::new(io::ErrorKind::AlreadyExists, "Reinitialization attempted")); |
|
|
|
|
impl MPS { |
|
|
|
|
pub fn new() -> MPS { |
|
|
|
|
MPS { storage: None } |
|
|
|
|
} |
|
|
|
|
print!("Enter passphrase for storage: "); |
|
|
|
|
io::stdout().flush()?; |
|
|
|
|
let ps = rpassword::read_password()?; |
|
|
|
|
print!("Reenter passphrase: "); |
|
|
|
|
io::stdout().flush()?; |
|
|
|
|
let ps2 = rpassword::read_password()?; |
|
|
|
|
if ps != ps2 { |
|
|
|
|
return Err(io::Error::new(io::ErrorKind::InvalidInput, "Passphrases must be equal")); |
|
|
|
|
} |
|
|
|
|
Storage::init(ps)?; |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn list() -> io:: Result<()> { |
|
|
|
|
// TODO: get storage from login
|
|
|
|
|
let passphrase = login()?; |
|
|
|
|
let st = Storage::from_db(passphrase)?; |
|
|
|
|
for id in st.ids() { |
|
|
|
|
println!("{}", id); |
|
|
|
|
fn init() -> io::Result<()> { |
|
|
|
|
if Storage::is_inited() { |
|
|
|
|
return Err(io::Error::new(io::ErrorKind::AlreadyExists, "Reinitialization attempted")); |
|
|
|
|
} |
|
|
|
|
print!("Enter passphrase for storage: "); |
|
|
|
|
io::stdout().flush()?; |
|
|
|
|
let ps = rpassword::read_password()?; |
|
|
|
|
print!("Reenter passphrase: "); |
|
|
|
|
io::stdout().flush()?; |
|
|
|
|
let ps2 = rpassword::read_password()?; |
|
|
|
|
if ps != ps2 { |
|
|
|
|
return Err(io::Error::new(io::ErrorKind::InvalidInput, "Passphrases must be equal")); |
|
|
|
|
} |
|
|
|
|
Storage::init(ps)?; |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn add(id: &String) -> io::Result<()> { |
|
|
|
|
let passphrase = login()?; |
|
|
|
|
let mut st = Storage::from_db(passphrase)?; |
|
|
|
|
if st.contains(id) { |
|
|
|
|
let question = format!("Item [{}] exist. Do you want to edit it instead?", id); |
|
|
|
|
match get_prompt(&question)? { |
|
|
|
|
PROMPT::YES => { |
|
|
|
|
edit(id)?; |
|
|
|
|
return Ok(()); |
|
|
|
|
}, |
|
|
|
|
PROMPT::NO => return Ok(()), |
|
|
|
|
// TODO: change password functionality
|
|
|
|
|
// TODO: set self.storage inited
|
|
|
|
|
pub fn login(&mut self) -> io::Result<String> { |
|
|
|
|
// TODO: do nothing if already storate inited
|
|
|
|
|
print!("Enter passphrase for storage: "); |
|
|
|
|
io::stdout().flush()?; |
|
|
|
|
// TODO: check in db
|
|
|
|
|
// TODO: return error if db is not inited
|
|
|
|
|
let password = rpassword::read_password()?; |
|
|
|
|
if password != "pass" { |
|
|
|
|
return Err(io::Error::new(io::ErrorKind::InvalidData, "Wrong passphrase")); |
|
|
|
|
} |
|
|
|
|
print!("\x1B[1A\x1B[2K"); // Move cursor up one line and clear that line
|
|
|
|
|
io::stdout().flush()?; // Ensure the changes are reflected immediately
|
|
|
|
|
Ok(String::from(password)) |
|
|
|
|
} |
|
|
|
|
// set empty string because there is no content yet
|
|
|
|
|
let content = editor::open_to_edit(&String::from(""))?; |
|
|
|
|
st.add(Item::from(id.clone(), content)); |
|
|
|
|
st.dump()?; |
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
fn list(&mut self) -> io:: Result<()> { |
|
|
|
|
// TODO: get storage from login
|
|
|
|
|
let passphrase = self.login()?; |
|
|
|
|
// TODO: use self.storage
|
|
|
|
|
let st = Storage::from_db(passphrase)?; |
|
|
|
|
for id in st.ids() { |
|
|
|
|
println!("{}", id); |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn edit(id: &String) -> io::Result<()> { |
|
|
|
|
// TODO: implement
|
|
|
|
|
let passphrase = login()?; |
|
|
|
|
let mut st = Storage::from_db(passphrase)?; |
|
|
|
|
if !st.contains(id) { |
|
|
|
|
let question = format!("Item [{}] exist. Do you want to add it instead?", id); |
|
|
|
|
match get_prompt(&question)? { |
|
|
|
|
PROMPT::YES => { |
|
|
|
|
add(id)?; |
|
|
|
|
return Ok(()); |
|
|
|
|
fn add(&mut self, id: &String) -> io::Result<()> { |
|
|
|
|
let passphrase = self.login()?; |
|
|
|
|
// TODO: use self.storage
|
|
|
|
|
let mut st = Storage::from_db(passphrase)?; |
|
|
|
|
if st.contains(id) { |
|
|
|
|
let question = format!("Item [{}] exist. Do you want to edit it instead?", id); |
|
|
|
|
match get_prompt(&question)? { |
|
|
|
|
PROMPT::YES => { |
|
|
|
|
self.edit(id)?; |
|
|
|
|
return Ok(()); |
|
|
|
|
}, |
|
|
|
|
PROMPT::NO => return Ok(()), |
|
|
|
|
} |
|
|
|
|
PROMPT::NO => return Ok(()) |
|
|
|
|
} |
|
|
|
|
// set empty string because there is no content yet
|
|
|
|
|
let content = editor::open_to_edit(&String::from(""))?; |
|
|
|
|
st.add(Item::from(id.clone(), content)); |
|
|
|
|
st.dump()?; |
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let mut item = (*st.get(id)).clone(); |
|
|
|
|
let new_content = editor::open_to_edit(&item.content)?; |
|
|
|
|
item.content = new_content; |
|
|
|
|
st.update(item); |
|
|
|
|
st.dump()?; |
|
|
|
|
fn edit(&mut self, id: &String) -> io::Result<()> { |
|
|
|
|
// TODO: implement
|
|
|
|
|
let passphrase = self.login()?; |
|
|
|
|
// TODO: use self.storage
|
|
|
|
|
let mut st = Storage::from_db(passphrase)?; |
|
|
|
|
if !st.contains(id) { |
|
|
|
|
let question = format!("Item [{}] exist. Do you want to add it instead?", id); |
|
|
|
|
match get_prompt(&question)? { |
|
|
|
|
PROMPT::YES => { |
|
|
|
|
self.add(id)?; |
|
|
|
|
return Ok(()); |
|
|
|
|
} |
|
|
|
|
PROMPT::NO => return Ok(()) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let mut item = (*st.get(id)).clone(); |
|
|
|
|
let new_content = editor::open_to_edit(&item.content)?; |
|
|
|
|
item.content = new_content; |
|
|
|
|
st.update(item); |
|
|
|
|
st.dump()?; |
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn show(id: &String) -> io::Result<()> { |
|
|
|
|
// TODO: get storage from login
|
|
|
|
|
let passphrase = login()?; |
|
|
|
|
let st = Storage::from_db(passphrase)?; |
|
|
|
|
if !st.contains(id) { |
|
|
|
|
return Err(io::Error::new( |
|
|
|
|
io::ErrorKind::InvalidInput, |
|
|
|
|
format!("Can`t find id: {}", id) |
|
|
|
|
)); |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let item = st.get(id); |
|
|
|
|
//editor::open_to_show(&item.content)?;
|
|
|
|
|
println!("---------"); |
|
|
|
|
println!("{}", item.content); |
|
|
|
|
println!("---------"); |
|
|
|
|
Ok(()) |
|
|
|
|
fn show(&mut self, id: &String) -> io::Result<()> { |
|
|
|
|
// TODO: get storage from login
|
|
|
|
|
let passphrase = self.login()?; |
|
|
|
|
// TODO: use self.storage
|
|
|
|
|
let st = Storage::from_db(passphrase)?; |
|
|
|
|
if !st.contains(id) { |
|
|
|
|
return Err(io::Error::new( |
|
|
|
|
io::ErrorKind::InvalidInput, |
|
|
|
|
format!("Can`t find id: {}", id) |
|
|
|
|
)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let item = st.get(id); |
|
|
|
|
editor::open_to_show(&item.content)?; |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn run_command() -> io::Result<()> { |
|
|
|
|
let cli = Cli::parse(); |
|
|
|
|
match &cli.command { |
|
|
|
|
Some(Commands::Init) => { |
|
|
|
|
init()?; |
|
|
|
|
MPS::init()?; |
|
|
|
|
} |
|
|
|
|
Some(Commands::List) => { |
|
|
|
|
list()?; |
|
|
|
|
let mut mps = MPS::new(); |
|
|
|
|
mps.list()?; |
|
|
|
|
} |
|
|
|
|
Some(Commands::Show { id }) => { |
|
|
|
|
show(id)?; |
|
|
|
|
let mut mps = MPS::new(); |
|
|
|
|
mps.show(id)?; |
|
|
|
|
} |
|
|
|
|
Some(Commands::Add { id }) => { |
|
|
|
|
add(id)?; |
|
|
|
|
let mut mps = MPS::new(); |
|
|
|
|
mps.add(id)?; |
|
|
|
|
} |
|
|
|
|
Some(Commands::Edit { id }) => { |
|
|
|
|
edit(id)? |
|
|
|
|
let mut mps = MPS::new(); |
|
|
|
|
mps.edit(id)? |
|
|
|
|
} |
|
|
|
|
None => { |
|
|
|
|
if !Storage::is_inited() { |
|
|
|
|
match get_prompt("Do you want to init your storage?")? { |
|
|
|
|
PROMPT::YES => init()?, |
|
|
|
|
PROMPT::YES => MPS::init()?, |
|
|
|
|
PROMPT::NO => Storage::print_init_hint(), |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
list()? |
|
|
|
|
let mut mps = MPS::new(); |
|
|
|
|
mps.list()? |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|