Finish truncate applet (untested)
This commit is contained in:
parent
8e302f3f85
commit
97679e43a6
@ -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,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user