|
|
@ -1,5 +1,7 @@ |
|
|
|
use clap::{Parser, Subcommand}; |
|
|
|
use clap::{Parser, Subcommand}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use std::collections::HashSet; |
|
|
|
|
|
|
|
|
|
|
|
use std::fs; |
|
|
|
use std::fs; |
|
|
|
use std::io::{self, Write, BufRead}; |
|
|
|
use std::io::{self, Write, BufRead}; |
|
|
|
use std::path::Path; |
|
|
|
use std::path::Path; |
|
|
@ -9,6 +11,9 @@ const STORAGE_FOLDER: &str = "storage"; |
|
|
|
const STORAGE_PATH: &str = "storage/db.mps"; // TODO: concat from STORAGE_FOLDER
|
|
|
|
const STORAGE_PATH: &str = "storage/db.mps"; // TODO: concat from STORAGE_FOLDER
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type DB = HashSet<String>; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Parser)] |
|
|
|
#[derive(Parser)] |
|
|
|
#[command(name = "mps", version = "0.0.1", about = "MyPasswordStorage: Tool for storing your passwords locally with git synchronization")] |
|
|
|
#[command(name = "mps", version = "0.0.1", about = "MyPasswordStorage: Tool for storing your passwords locally with git synchronization")] |
|
|
|
struct Cli { |
|
|
|
struct Cli { |
|
|
@ -33,6 +38,23 @@ enum Commands { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn read_db() -> io::Result<DB> { |
|
|
|
|
|
|
|
let file = fs::File::open(STORAGE_PATH)?; |
|
|
|
|
|
|
|
let reader = io::BufReader::new(file); |
|
|
|
|
|
|
|
let mut db = DB::new(); |
|
|
|
|
|
|
|
for line in reader.lines() { |
|
|
|
|
|
|
|
match line { |
|
|
|
|
|
|
|
Ok(content) => { |
|
|
|
|
|
|
|
db.insert(content); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
Err(e) => { |
|
|
|
|
|
|
|
eprintln!("Error reading line , {}", e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Ok(db) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fn is_inited() -> bool { |
|
|
|
fn is_inited() -> bool { |
|
|
|
let path = Path::new(STORAGE_FOLDER); |
|
|
|
let path = Path::new(STORAGE_FOLDER); |
|
|
|
return path.exists(); |
|
|
|
return path.exists(); |
|
|
@ -53,6 +75,14 @@ fn init() -> io::Result<()> { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fn add(id: &String) -> io::Result<()> { |
|
|
|
fn add(id: &String) -> io::Result<()> { |
|
|
|
|
|
|
|
let db = read_db()?; |
|
|
|
|
|
|
|
if db.contains(id) { |
|
|
|
|
|
|
|
// TODO: ask to edit existing in outer function which invoked this one
|
|
|
|
|
|
|
|
return Err(io::Error::new( |
|
|
|
|
|
|
|
io::ErrorKind::InvalidInput, |
|
|
|
|
|
|
|
format!("Dublicate item id: {}. Item id's must be unique.", id) |
|
|
|
|
|
|
|
)) |
|
|
|
|
|
|
|
} |
|
|
|
let mut file = fs::OpenOptions::new() |
|
|
|
let mut file = fs::OpenOptions::new() |
|
|
|
.write(true) |
|
|
|
.write(true) |
|
|
|
.append(true) |
|
|
|
.append(true) |
|
|
@ -62,19 +92,10 @@ fn add(id: &String) -> io::Result<()> { |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// TODO: make this to return just set on values, will need later to check ids
|
|
|
|
|
|
|
|
fn list() -> io:: Result<()> { |
|
|
|
fn list() -> io:: Result<()> { |
|
|
|
let file = fs::File::open(STORAGE_PATH)?; |
|
|
|
let db = read_db()?; |
|
|
|
let reader = io::BufReader::new(file); |
|
|
|
for item in db.iter() { |
|
|
|
for line in reader.lines() { |
|
|
|
println!("{}", item); |
|
|
|
match line { |
|
|
|
|
|
|
|
Ok(content) => { |
|
|
|
|
|
|
|
println!("{}", content) |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
Err(e) => { |
|
|
|
|
|
|
|
eprintln!("Error reading line , {}", e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|