Support "-" as stdin/stdout shortcut filename for input/output

This commit is contained in:
Marcin Kulik
2025-05-06 14:40:57 +02:00
parent 8c589baf67
commit d6cc282ed8
2 changed files with 31 additions and 12 deletions

View File

@@ -228,14 +228,16 @@ pub struct Cat {
#[derive(Debug, Args)] #[derive(Debug, Args)]
pub struct Convert { pub struct Convert {
/// File to convert from, in asciicast format (use - for stdin)
#[arg(value_name = "INPUT_FILENAME_OR_URL")] #[arg(value_name = "INPUT_FILENAME_OR_URL")]
pub input_filename: String, pub input_filename: String,
/// File to convert to (use - for stdout)
pub output_filename: String, pub output_filename: String,
/// Output file format [default: asciicast-v3] /// Output file format [default: asciicast-v3]
#[arg(short, long, value_enum)] #[arg(short = 'f', long, value_enum, value_name = "FORMAT")]
pub format: Option<Format>, pub output_format: Option<Format>,
/// Overwrite target file if it already exists /// Overwrite target file if it already exists
#[arg(long)] #[arg(long)]

View File

@@ -13,16 +13,17 @@ use crate::util;
impl cli::Convert { impl cli::Convert {
pub fn run(self, _config: &Config) -> Result<()> { pub fn run(self, _config: &Config) -> Result<()> {
let path = util::get_local_path(&self.input_filename)?; let input_path = self.get_input_path()?;
let cast = asciicast::open_from_path(&*path)?; let output_path = self.get_output_path();
let cast = asciicast::open_from_path(&*input_path)?;
let mut encoder = self.get_encoder(); let mut encoder = self.get_encoder();
let mut file = self.open_file()?; let mut output_file = self.open_output_file(output_path)?;
encoder.encode_to_file(cast, &mut file) encoder.encode_to_file(cast, &mut output_file)
} }
fn get_encoder(&self) -> Box<dyn encoder::Encoder> { fn get_encoder(&self) -> Box<dyn encoder::Encoder> {
let format = self.format.unwrap_or_else(|| { let format = self.output_format.unwrap_or_else(|| {
if self.output_filename.to_lowercase().ends_with(".txt") { if self.output_filename.to_lowercase().ends_with(".txt") {
Format::Txt Format::Txt
} else { } else {
@@ -38,22 +39,38 @@ impl cli::Convert {
} }
} }
fn open_file(&self) -> Result<fs::File> { fn get_input_path(&self) -> Result<Box<dyn AsRef<Path>>> {
let overwrite = self.get_mode()?; if self.input_filename == "-" {
Ok(Box::new(Path::new("/dev/stdin")))
} else {
util::get_local_path(&self.input_filename)
}
}
fn get_output_path(&self) -> String {
if self.output_filename == "-" {
"/dev/stdout".to_owned()
} else {
self.output_filename.clone()
}
}
fn open_output_file(&self, path: String) -> Result<fs::File> {
let overwrite = self.get_mode(&path)?;
let file = fs::OpenOptions::new() let file = fs::OpenOptions::new()
.write(true) .write(true)
.create(overwrite) .create(overwrite)
.create_new(!overwrite) .create_new(!overwrite)
.truncate(overwrite) .truncate(overwrite)
.open(&self.output_filename)?; .open(&path)?;
Ok(file) Ok(file)
} }
fn get_mode(&self) -> Result<bool> { fn get_mode(&self, path: &str) -> Result<bool> {
let mut overwrite = self.overwrite; let mut overwrite = self.overwrite;
let path = Path::new(&self.output_filename); let path = Path::new(path);
if path.exists() { if path.exists() {
let metadata = fs::metadata(path)?; let metadata = fs::metadata(path)?;