little cleanup

This commit is contained in:
Mateusz Faderewski 2024-09-29 20:42:17 +02:00
parent 3b54b6f8bc
commit 802e882b13
2 changed files with 215 additions and 220 deletions

View File

@ -874,126 +874,123 @@ fn handle_sd_command(connection: Connection, command: &SDCommands) -> Result<(),
sc64.reset_state()?;
sc64::ff::run(sc64, |ff| {
match command {
SDCommands::List { path } => {
for item in ff.list(path.clone().unwrap_or(PathBuf::from("/")))? {
let sc64::ff::Entry {
info,
datetime,
name,
} = item;
let name = match info {
sc64::ff::EntryInfo::Directory => ("/".to_owned() + &name).bright_blue(),
sc64::ff::EntryInfo::File { size: _ } => name.bright_green(),
};
println!("{info} {datetime} | {}", name.bold());
}
}
SDCommands::Stat { path } => {
let mut ff = sc64::ff::FatFs::new(sc64)?;
match command {
SDCommands::List { path } => {
for item in ff.list(path.clone().unwrap_or(PathBuf::from("/")))? {
let sc64::ff::Entry {
info,
datetime,
name,
} = ff.stat(path)?;
} = item;
let name = match info {
sc64::ff::EntryInfo::Directory => ("/".to_owned() + &name).bright_blue(),
sc64::ff::EntryInfo::File { size: _ } => name.bright_green(),
};
println!("{info} {datetime} | {}", name.bold());
}
SDCommands::Move { src, dst } => {
ff.rename(src, dst)?;
println!(
"Successfully moved {} to {}",
}
SDCommands::Stat { path } => {
let sc64::ff::Entry {
info,
datetime,
name,
} = ff.stat(path)?;
let name = match info {
sc64::ff::EntryInfo::Directory => ("/".to_owned() + &name).bright_blue(),
sc64::ff::EntryInfo::File { size: _ } => name.bright_green(),
};
println!("{info} {datetime} | {}", name.bold());
}
SDCommands::Move { src, dst } => {
ff.rename(src, dst)?;
println!(
"Successfully moved {} to {}",
src.to_str().unwrap_or_default().bright_green(),
dst.to_str().unwrap_or_default().bright_green()
);
}
SDCommands::Delete { path } => {
ff.delete(path)?;
println!(
"Successfully deleted {}",
path.to_str().unwrap_or_default().bright_green()
);
}
SDCommands::CreateDirectory { path } => {
ff.mkdir(path)?;
println!(
"Successfully created {}",
path.to_str().unwrap_or_default().bright_green()
);
}
SDCommands::Download { src, dst } => {
let dst = &dst.clone().unwrap_or(
src.file_name()
.map(PathBuf::from)
.ok_or(sc64::ff::Error::InvalidParameter)?,
);
let mut src_file = ff.open(src)?;
let mut dst_file = std::fs::File::create(dst)?;
let mut buffer = vec![0; 128 * 1024];
log_wait(
format!(
"Downloading {} to {}",
src.to_str().unwrap_or_default().bright_green(),
dst.to_str().unwrap_or_default().bright_green()
);
}
SDCommands::Delete { path } => {
ff.delete(path)?;
println!(
"Successfully deleted {}",
path.to_str().unwrap_or_default().bright_green()
);
}
SDCommands::CreateDirectory { path } => {
ff.mkdir(path)?;
println!(
"Successfully created {}",
path.to_str().unwrap_or_default().bright_green()
);
}
SDCommands::Download { src, dst } => {
let dst = &dst.clone().unwrap_or(
src.file_name()
.map(PathBuf::from)
.ok_or(sc64::ff::Error::InvalidParameter)?,
);
let mut src_file = ff.open(src)?;
let mut dst_file = std::fs::File::create(dst)?;
let mut buffer = vec![0; 128 * 1024];
print!(
"{}",
format!(
"Downloading {} to {}... ",
src.to_str().unwrap_or_default().bright_green(),
dst.to_str().unwrap_or_default().bright_green()
)
);
stdout().flush().unwrap();
loop {
),
|| loop {
match src_file.read(&mut buffer)? {
0 => break,
bytes => dst_file.write_all(&buffer[0..bytes])?,
0 => return Ok(()),
bytes => {
if let Err(e) = dst_file.write_all(&buffer[0..bytes]) {
return Err(e);
}
}
}
}
println!("{}", "done!".bright_green());
}
SDCommands::Upload { src, dst } => {
let dst = &dst.clone().unwrap_or(
src.file_name()
.map(PathBuf::from)
.ok_or(sc64::ff::Error::InvalidParameter)?,
);
let mut src_file = std::fs::File::open(src)?;
let mut dst_file = ff.create(dst)?;
let mut buffer = vec![0; 128 * 1024];
print!(
"{}",
format!(
"Uploading {} to {}... ",
src.to_str().unwrap_or_default().bright_green(),
dst.to_str().unwrap_or_default().bright_green()
)
);
stdout().flush().unwrap();
loop {
match src_file.read(&mut buffer)? {
0 => break,
bytes => dst_file.write_all(&buffer[0..bytes])?,
}
}
println!("{}", "done!".bright_green());
}
SDCommands::Format => {
let answer = prompt(format!(
"{}",
"Do you really want to format the SD card? [y/N] ".bold()
));
if answer.to_ascii_lowercase() != "y" {
println!("{}", "Format operation aborted".red());
return Ok(());
}
print!("Formatting the SD card... ",);
stdout().flush().unwrap();
ff.mkfs()?;
println!("{}", "done!".bright_green());
}
},
)?;
}
Ok(())
})?;
SDCommands::Upload { src, dst } => {
let dst = &dst.clone().unwrap_or(
src.file_name()
.map(PathBuf::from)
.ok_or(sc64::ff::Error::InvalidParameter)?,
);
let mut src_file = std::fs::File::open(src)?;
let mut dst_file = ff.create(dst)?;
let mut buffer = vec![0; 128 * 1024];
log_wait(
format!(
"Uploading {} to {}",
src.to_str().unwrap_or_default().bright_green(),
dst.to_str().unwrap_or_default().bright_green()
),
|| loop {
match src_file.read(&mut buffer)? {
0 => return Ok(()),
bytes => {
if let Err(e) = dst_file.write_all(&buffer[0..bytes]) {
return Err(e);
}
}
}
},
)?;
}
SDCommands::Format => {
let answer = prompt(format!(
"{}",
"Do you really want to format the SD card? [y/N] ".bold()
));
if answer.to_ascii_lowercase() != "y" {
println!("{}", "Format operation aborted".red());
return Ok(());
}
log_wait(format!("Formatting the SD card"), || ff.mkfs())?;
}
}
Ok(())
}

View File

@ -120,121 +120,6 @@ pub type Error = fatfs::Error;
static mut DRIVER: std::sync::Mutex<Option<Box<dyn FFDriver>>> = std::sync::Mutex::new(None);
pub struct FF {
fs: Box<fatfs::FATFS>,
}
impl FF {
fn new() -> Self {
Self {
fs: Box::new(unsafe { std::mem::zeroed() }),
}
}
fn mount(&mut self) -> Result<(), Error> {
match unsafe { fatfs::f_mount(&mut *self.fs, fatfs::path("")?.as_ptr(), 0) } {
fatfs::FRESULT_FR_OK => Ok(()),
error => Err(error.into()),
}
}
fn unmount(&self) -> Result<(), Error> {
match unsafe { fatfs::f_mount(std::ptr::null_mut(), fatfs::path("")?.as_ptr(), 0) } {
fatfs::FRESULT_FR_OK => Ok(()),
error => Err(error.into()),
}
}
pub fn open<P: AsRef<std::path::Path>>(&self, path: P) -> Result<File, Error> {
File::open(
path,
fatfs::FA_OPEN_EXISTING | fatfs::FA_READ | fatfs::FA_WRITE,
)
}
pub fn create<P: AsRef<std::path::Path>>(&self, path: P) -> Result<File, Error> {
File::open(
path,
fatfs::FA_CREATE_ALWAYS | fatfs::FA_READ | fatfs::FA_WRITE,
)
}
pub fn stat<P: AsRef<std::path::Path>>(&self, path: P) -> Result<Entry, Error> {
let mut fno = unsafe { std::mem::zeroed() };
match unsafe { fatfs::f_stat(fatfs::path(path)?.as_ptr(), &mut fno) } {
fatfs::FRESULT_FR_OK => Ok(fno.into()),
error => Err(error.into()),
}
}
pub fn opendir<P: AsRef<std::path::Path>>(&self, path: P) -> Result<Directory, Error> {
Directory::open(path)
}
pub fn list<P: AsRef<std::path::Path>>(&self, path: P) -> Result<Vec<Entry>, Error> {
let mut dir = self.opendir(path)?;
let mut list = vec![];
while let Some(entry) = dir.read()? {
list.push(entry);
}
list.sort_by_key(|k| (k.info, k.name.to_lowercase()));
Ok(list)
}
pub fn mkdir<P: AsRef<std::path::Path>>(&self, path: P) -> Result<(), Error> {
match unsafe { fatfs::f_mkdir(fatfs::path(path)?.as_ptr()) } {
fatfs::FRESULT_FR_OK => Ok(()),
error => Err(error.into()),
}
}
pub fn delete<P: AsRef<std::path::Path>>(&self, path: P) -> Result<(), Error> {
match unsafe { fatfs::f_unlink(fatfs::path(path)?.as_ptr()) } {
fatfs::FRESULT_FR_OK => Ok(()),
error => Err(error.into()),
}
}
pub fn rename<P: AsRef<std::path::Path>>(&self, old: P, new: P) -> Result<(), Error> {
match unsafe { fatfs::f_rename(fatfs::path(old)?.as_ptr(), fatfs::path(new)?.as_ptr()) } {
fatfs::FRESULT_FR_OK => Ok(()),
error => Err(error.into()),
}
}
pub fn mkfs(&self) -> Result<(), Error> {
let mut work = [0u8; 16 * 1024];
match unsafe {
fatfs::f_mkfs(
fatfs::path("")?.as_ptr(),
std::ptr::null(),
work.as_mut_ptr().cast(),
size_of_val(&work) as u32,
)
} {
fatfs::FRESULT_FR_OK => Ok(()),
error => Err(error.into()),
}
}
}
pub fn run<F: FnOnce(&mut FF) -> Result<(), super::Error>>(
driver: impl FFDriver + 'static,
runner: F,
) -> Result<(), super::Error> {
install_driver(driver)?;
let mut ff = FF::new();
ff.mount()?;
let result = runner(&mut ff);
ff.unmount().ok();
uninstall_driver().ok();
result
}
fn install_driver(driver: impl FFDriver + 'static) -> Result<(), Error> {
let mut d = unsafe { DRIVER.lock().unwrap() };
if d.is_some() {
@ -253,6 +138,119 @@ fn uninstall_driver() -> Result<(), Error> {
Ok(())
}
pub struct FatFs {
fs: Box<fatfs::FATFS>,
}
impl FatFs {
pub fn new(driver: impl FFDriver + 'static) -> Result<Self, Error> {
install_driver(driver)?;
let mut ff = Self {
fs: Box::new(unsafe { std::mem::zeroed() }),
};
ff.mount(false)?;
Ok(ff)
}
fn mount(&mut self, force: bool) -> Result<(), Error> {
let opt = if force { 1 } else { 0 };
match unsafe { fatfs::f_mount(&mut *self.fs, fatfs::path("")?.as_ptr(), opt) } {
fatfs::FRESULT_FR_OK => Ok(()),
error => Err(error.into()),
}
}
fn unmount(&mut self) -> Result<(), Error> {
match unsafe { fatfs::f_mount(std::ptr::null_mut(), fatfs::path("")?.as_ptr(), 0) } {
fatfs::FRESULT_FR_OK => Ok(()),
error => Err(error.into()),
}
}
pub fn open<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<File, Error> {
File::open(
path,
fatfs::FA_OPEN_EXISTING | fatfs::FA_READ | fatfs::FA_WRITE,
)
}
pub fn create<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<File, Error> {
File::open(
path,
fatfs::FA_CREATE_ALWAYS | fatfs::FA_READ | fatfs::FA_WRITE,
)
}
pub fn stat<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<Entry, Error> {
let mut fno = unsafe { std::mem::zeroed() };
match unsafe { fatfs::f_stat(fatfs::path(path)?.as_ptr(), &mut fno) } {
fatfs::FRESULT_FR_OK => Ok(fno.into()),
error => Err(error.into()),
}
}
pub fn opendir<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<Directory, Error> {
Directory::open(path)
}
pub fn list<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<Vec<Entry>, Error> {
let mut dir = self.opendir(path)?;
let mut list = vec![];
while let Some(entry) = dir.read()? {
list.push(entry);
}
list.sort_by_key(|k| (k.info, k.name.to_lowercase()));
Ok(list)
}
pub fn mkdir<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<(), Error> {
match unsafe { fatfs::f_mkdir(fatfs::path(path)?.as_ptr()) } {
fatfs::FRESULT_FR_OK => Ok(()),
error => Err(error.into()),
}
}
pub fn delete<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<(), Error> {
match unsafe { fatfs::f_unlink(fatfs::path(path)?.as_ptr()) } {
fatfs::FRESULT_FR_OK => Ok(()),
error => Err(error.into()),
}
}
pub fn rename<P: AsRef<std::path::Path>>(&mut self, old: P, new: P) -> Result<(), Error> {
match unsafe { fatfs::f_rename(fatfs::path(old)?.as_ptr(), fatfs::path(new)?.as_ptr()) } {
fatfs::FRESULT_FR_OK => Ok(()),
error => Err(error.into()),
}
}
pub fn mkfs(&mut self) -> Result<(), Error> {
let mut work = [0u8; 16 * 1024];
match unsafe {
fatfs::f_mkfs(
fatfs::path("")?.as_ptr(),
std::ptr::null(),
work.as_mut_ptr().cast(),
size_of_val(&work) as u32,
)
} {
fatfs::FRESULT_FR_OK => Ok(()),
error => Err(error.into()),
}
}
}
impl Drop for FatFs {
fn drop(&mut self) {
self.unmount().ok();
uninstall_driver().ok();
}
}
pub enum IOCtl {
Sync,
GetSectorCount(fatfs::LBA_t),