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