use clap;
use std::io::Write;
use std::str::FromStr;
use log::error;
use super::{ItemType,CommandError};
use crate::img::DiskImage;
use crate::img::tracks::Method;
use crate::STDRESULT;
const RCH: &str = "unreachable was reached";
fn output_get(dat: Vec<u8>,typ: ItemType,img: Box<dyn DiskImage>,console_fmt: bool) {
if atty::is(atty::Stream::Stdout) || console_fmt {
match typ {
ItemType::Track => println!("{}",img.display_track(&dat)),
_ => crate::display_block(0,&dat)
};
} else {
std::io::stdout().write_all(&dat).expect("could not write stdout")
}
}
pub fn get(cmd: &clap::ArgMatches) -> STDRESULT {
let src_path = cmd.get_one::<String>("file").expect(RCH);
let typ = ItemType::from_str(&cmd.get_one::<String>("type").expect(RCH)).expect(RCH);
let maybe_img_path = cmd.get_one::<String>("dimg");
let fmt = super::get_fmt(cmd)?;
let maybe_explicit_list = cmd.get_one::<String>("explicit");
match crate::create_img_from_file_or_stdin(maybe_img_path) {
Ok(mut img) => {
img.change_method(Method::from_str(cmd.get_one::<String>("method").unwrap())?);
if let Some(fmt) = fmt {
img.change_format(fmt)?;
}
let bytes = match typ {
ItemType::Sector => {
let mut cum: Vec<u8> = Vec::new();
let mut sector_list = super::parse_sector_request(&src_path,img.motor_steps_per_cyl())?;
if let Some(explicit_list) = maybe_explicit_list {
super::to_explicit(&explicit_list,&mut sector_list)?;
}
for (trk,sec) in sector_list {
cum.append(&mut img.read_sector(trk,sec)?);
}
cum
},
ItemType::Track => {
img.get_track_nibbles(super::request_one_track(&src_path,img.motor_steps_per_cyl())?)?
},
ItemType::RawTrack => {
img.get_track_buf(super::request_one_track(&src_path,img.motor_steps_per_cyl())?)?
},
_ => panic!("{}",RCH)
};
return Ok(output_get(bytes,typ,img,cmd.get_flag("console")));
},
Err(e) => return Err(e)
}
}
pub fn get_meta(cmd: &clap::ArgMatches) -> STDRESULT {
let maybe_selection = cmd.get_one::<String>("file");
let maybe_img_path = cmd.get_one::<String>("dimg");
match crate::create_img_from_file_or_stdin(maybe_img_path) {
Ok(img) => {
match maybe_selection {
None => {
println!("{}",img.get_metadata(Some(4)));
Ok(())
}
Some(selection) => {
if selection.chars().next()!=Some('/') {
error!("selection string should start with `/`");
return Err(Box::new(CommandError::KeyNotFound));
}
match json::parse(&img.get_metadata(None)) {
Ok(parsed) => {
let mut keys = selection.split('/');
let mut obj = parsed;
keys.next();
while let Some(key) = keys.next() {
if key=="" {
break;
}
match obj[key].clone() {
json::JsonValue::Null => return Err(Box::new(CommandError::KeyNotFound)),
x => { obj = x }
};
}
println!("{}",json::stringify_pretty(obj, 4));
Ok(())
},
Err(e) => Err(Box::new(e))
}
}
}
},
Err(e) => return Err(e)
}
}