generated from PlexSheep/baserepo
read from multiple sources
cargo devel CI / cargo CI (push) Successful in 2m6s
Details
cargo devel CI / cargo CI (push) Successful in 2m6s
Details
implements #60
This commit is contained in:
parent
fd0d1e3c22
commit
2bc75970a4
|
@ -10,10 +10,10 @@ use anyhow::{bail, Result};
|
|||
use libpt_log::{debug, error, trace, warn};
|
||||
use std::io::{prelude::*, Read, SeekFrom};
|
||||
|
||||
const BYTES_PER_LINE: usize = 16;
|
||||
const LINE_SEP_HORIZ: char = '─';
|
||||
const LINE_SEP_VERT: char = '│';
|
||||
const CHAR_BORDER: &'static str = "|";
|
||||
pub const BYTES_PER_LINE: usize = 16;
|
||||
pub const LINE_SEP_HORIZ: char = '─';
|
||||
pub const LINE_SEP_VERT: char = '│';
|
||||
pub const CHAR_BORDER: &'static str = "|";
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HeduConfig {
|
||||
|
@ -70,14 +70,12 @@ impl DataSource for std::fs::File {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
|
||||
// prepare some variables
|
||||
|
||||
pub fn dump(data: &mut dyn DataSource, config: &mut HeduConfig) -> Result<()> {
|
||||
// skip a given number of bytes
|
||||
if config.skip > 0 {
|
||||
data.skip(config.skip)?;
|
||||
config.data_idx += config.skip;
|
||||
adjust_data_idx(&mut config);
|
||||
adjust_data_idx(config);
|
||||
debug!("Skipped {}", humanbytes(config.skip));
|
||||
}
|
||||
|
||||
|
@ -95,7 +93,7 @@ pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
|
|||
config.display();
|
||||
|
||||
// data dump loop
|
||||
rd_data(data, &mut config)?;
|
||||
rd_data(data, config)?;
|
||||
while config.len > 0 {
|
||||
config.display_buf += &format!("{:08X} {LINE_SEP_VERT} ", config.data_idx);
|
||||
for i in 0..config.len {
|
||||
|
@ -129,7 +127,7 @@ pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
|
|||
}
|
||||
|
||||
// after line logic
|
||||
rd_data(data, &mut config)?;
|
||||
rd_data(data, config)?;
|
||||
config.alt_buf ^= 1; // toggle the alt buf
|
||||
if config.buf[0] == config.buf[1] && config.len == BYTES_PER_LINE && !config.show_identical
|
||||
{
|
||||
|
@ -139,7 +137,7 @@ pub fn dump(data: &mut dyn DataSource, mut config: HeduConfig) -> Result<()> {
|
|||
);
|
||||
let start_line = config.data_idx;
|
||||
while config.buf[0] == config.buf[1] && config.len == BYTES_PER_LINE {
|
||||
rd_data(data, &mut config)?;
|
||||
rd_data(data, config)?;
|
||||
}
|
||||
config.alt_buf ^= 1; // toggle the alt buf (now that we have a not same line)
|
||||
config.display_buf += &format!(
|
||||
|
|
|
@ -18,7 +18,7 @@ use libpt::{bintols::hedu::*, log::*};
|
|||
use clap::Parser;
|
||||
use clap_verbosity_flag::{InfoLevel, Verbosity};
|
||||
|
||||
use std::{fs::File, io::IsTerminal};
|
||||
use std::{fs::File, io::IsTerminal, path::PathBuf};
|
||||
|
||||
//// TYPES /////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -87,7 +87,7 @@ pub struct Cli {
|
|||
///
|
||||
/// If left empty or set as "-", the program will read from stdin.
|
||||
// TODO: take many sources #60
|
||||
pub data_source: Option<String>,
|
||||
pub data_source: Vec<String>,
|
||||
}
|
||||
|
||||
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -96,36 +96,46 @@ pub struct Cli {
|
|||
|
||||
//// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////
|
||||
fn main() {
|
||||
let cli = cli_parse();
|
||||
let mut source: Box<dyn DataSource>;
|
||||
if cli.data_source.is_some() && cli.data_source.clone().is_some_and(|val| val != "-") {
|
||||
let data_source = cli.data_source.unwrap();
|
||||
trace!("Trying to open '{}'", data_source);
|
||||
source = match File::open(&data_source) {
|
||||
Ok(file) => Box::new(file),
|
||||
Err(err) => {
|
||||
error!("Could not open file '{}': {err}", data_source);
|
||||
std::process::exit(1);
|
||||
let mut cli = cli_parse();
|
||||
let mut sources: Vec<Box<dyn DataSource>> = Vec::new();
|
||||
if cli.data_source.len() > 0 && cli.data_source[0] != "-" {
|
||||
for data_source in &cli.data_source {
|
||||
let data_source: PathBuf = PathBuf::from(data_source);
|
||||
if !data_source.is_file() {
|
||||
debug!("Not a regular file'{:?}'", data_source);
|
||||
// std::process::exit(1);
|
||||
continue
|
||||
}
|
||||
};
|
||||
trace!("Trying to open '{:?}'", data_source);
|
||||
match File::open(&data_source) {
|
||||
Ok(file) => sources.push(Box::new(file)),
|
||||
Err(err) => {
|
||||
error!("Could not open '{:?}': {err}", data_source);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
}
|
||||
} else {
|
||||
trace!("Trying to open stdout");
|
||||
trace!("Trying to open stdin");
|
||||
let stdin = std::io::stdin();
|
||||
if stdin.is_terminal() {
|
||||
warn!("Refusing to dump from interactive terminal");
|
||||
std::process::exit(2)
|
||||
}
|
||||
source = Box::new(stdin);
|
||||
// just for the little header
|
||||
cli.data_source = Vec::new();
|
||||
cli.data_source.push(format!("stdin"));
|
||||
sources.push(Box::new(stdin));
|
||||
}
|
||||
|
||||
match dump(
|
||||
&mut *source,
|
||||
HeduConfig::new(cli.chars, cli.skip, cli.show_identical, cli.limit),
|
||||
) {
|
||||
Ok(_) => (),
|
||||
Err(err) => {
|
||||
error!("Could not dump data of file: {err}");
|
||||
std::process::exit(3);
|
||||
for (i, source) in sources.iter_mut().enumerate() {
|
||||
println!("{:=^59}", format!(" {} ", cli.data_source[i]));
|
||||
let mut config = HeduConfig::new(cli.chars, cli.skip, cli.show_identical, cli.limit);
|
||||
match dump(&mut **source, &mut config) {
|
||||
Ok(_) => (),
|
||||
Err(err) => {
|
||||
error!("Could not dump data of file: {err}");
|
||||
std::process::exit(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue