Finish truncate applet (untested)

This commit is contained in:
Nathan Fisher 2023-04-17 22:40:49 -04:00
parent 8e302f3f85
commit 97679e43a6

View File

@ -1,7 +1,9 @@
use std::fs::File;
use { use {
super::Cmd, super::Cmd,
clap::{Arg, ArgAction, ArgGroup, Command, ValueHint}, clap::{Arg, ArgAction, ArgGroup, Command, ValueHint},
std::{error::Error, fmt, fs, num::ParseIntError}, std::{error::Error, fmt, fs, num::ParseIntError, path::PathBuf},
}; };
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -65,12 +67,49 @@ impl Cmd for Truncate {
fn run(&self, matches: &clap::ArgMatches) -> Result<(), Box<dyn std::error::Error>> { fn run(&self, matches: &clap::ArgMatches) -> Result<(), Box<dyn std::error::Error>> {
let size = if let Some(file) = matches.get_one::<String>("reference") { let size = if let Some(file) = matches.get_one::<String>("reference") {
let num: i64 = fs::metadata(file)?.len().try_into()?; let num: i64 = fs::metadata(file)?.len().try_into()?;
Size { operator: Operator::Equal, num } Size {
operator: Operator::Equal,
num,
}
} else if let Some(s) = matches.get_one::<String>("size") { } else if let Some(s) = matches.get_one::<String>("size") {
parse_size(s)? parse_size(s)?
} else { } else {
unreachable!(); unreachable!();
}; };
matches
.get_many::<String>("file")
.unwrap()
.try_for_each(|file| {
let path = PathBuf::from(file);
if !matches.get_flag("create") && !path.exists() {
return Ok(());
}
let fd = File::options().write(true).create(true).open(&path)?;
let current: i64 = fd.metadata()?.len().try_into()?;
let len = match size.operator {
Operator::Equal => size.num,
Operator::Add => size.num + current,
Operator::Remove => current - size.num,
Operator::ModUp => {
if current % size.num == 0 {
current
} else {
let fraction = current / size.num;
(fraction + 1) * size.num
}
}
Operator::ModDown => {
if current % size.num == 0 {
current
} else {
let fraction = current / size.num;
fraction * size.num
}
}
};
unistd::ftruncate(&fd, len)?;
Ok::<(), Box<dyn Error>>(())
})?;
Ok(()) Ok(())
} }
@ -79,6 +118,7 @@ impl Cmd for Truncate {
} }
} }
#[derive(PartialEq)]
enum Operator { enum Operator {
Equal, Equal,
Add, Add,
@ -201,13 +241,16 @@ fn parse_size(size: &str) -> Result<Size, ParseSizeError> {
if let Some(m) = multiplier { if let Some(m) = multiplier {
match m { match m {
Multiplier::Kilo => num *= 1024, Multiplier::Kilo => num *= 1024,
Multiplier::Mega => num *= (1024 * 1024), Multiplier::Mega => num *= 1024 * 1024,
Multiplier::Giga => num *= (1024 * 1024 * 1024), Multiplier::Giga => num *= 1024 * 1024 * 1024,
Multiplier::Tera => num *= (1024 * 1024 * 1024 * 1024), Multiplier::Tera => num *= 1024 * 1024 * 1024 * 1024,
} }
} }
match operator { match operator {
Some(operator) => Ok(Size { operator, num }), Some(operator) => Ok(Size { operator, num }),
None => Ok(Size { operator: Operator::Equal, num }), None => Ok(Size {
operator: Operator::Equal,
num,
}),
} }
} }