use std::path::PathBuf;
use std::process;
use std::time::Duration;
use clap::{Parser, Subcommand};
use flipperzero_tools::storage::FlipperPath;
use flipperzero_tools::{serial, storage};
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[arg(short, long)]
port: Option<String>,
#[command(subcommand)]
command: Option<Commands>,
}
#[derive(Subcommand)]
enum Commands {
Mkdir {
flipper_path: FlipperPath,
},
Format,
Remove {
flipper_path: FlipperPath,
},
Read,
Size {
flipper_path: FlipperPath,
},
Receive {
flipper_path: FlipperPath,
local_path: PathBuf,
},
Send {
local_path: PathBuf,
flipper_path: FlipperPath,
},
List {
#[arg(default_value = "/")]
flipper_path: FlipperPath,
},
Md5sum {
flipper_path: FlipperPath,
},
}
fn main() {
let cli = Cli::parse();
let command = match &cli.command {
None => {
eprintln!("No subcommand specified");
process::exit(2);
}
Some(c) => c,
};
let port_info =
serial::find_flipperzero(cli.port.as_deref()).expect("unable to find Flipper Zero");
let port = serialport::new(port_info.port_name, serial::BAUD_115200)
.timeout(Duration::from_secs(30))
.open()
.expect("unable to open serial port");
let mut store = storage::FlipperStorage::new(port);
store.start().expect("failed to start storage");
let result = match command {
Commands::Mkdir { flipper_path } => store.mkdir(flipper_path),
Commands::Format => store.format_ext(),
Commands::Remove { flipper_path } => store.remove(flipper_path),
Commands::Read => todo!(),
Commands::Size { flipper_path } => match store.size(flipper_path) {
Err(err) => Err(err),
Ok(size) => {
println!("{size}");
Ok(())
}
},
Commands::Receive {
flipper_path,
local_path,
} => store.receive_file(flipper_path, local_path),
Commands::Send {
local_path,
flipper_path,
} => store.send_file(local_path.as_path(), flipper_path),
Commands::List { flipper_path } => store.list_tree(flipper_path),
Commands::Md5sum { flipper_path } => match store.md5sum(flipper_path) {
Err(err) => Err(err),
Ok(md5sum) => {
println!("{md5sum}");
Ok(())
}
},
};
if let Err(err) = result {
eprintln!("ERROR: {err}");
process::exit(1);
}
}