Skip to main content

a2kit/commands/
get_img.rs

1//! ## get from image
2//! 
3//! Handles getting item types that do not require resolution of the file system.
4//! This is invoked from the `get` module.
5
6use clap;
7use std::io::Write;
8use std::str::FromStr;
9use log::error;
10use super::{ItemType,CommandError};
11use crate::img::DiskImage;
12use crate::img::tracks::Method;
13use crate::STDRESULT;
14
15const RCH: &str = "unreachable was reached";
16
17fn output_get(dat: Vec<u8>,typ: ItemType,img: Box<dyn DiskImage>,console_fmt: bool) {
18    if atty::is(atty::Stream::Stdout) || console_fmt {
19        match typ {
20            ItemType::Track => println!("{}",img.display_track(&dat)),
21            _ => crate::display_block(0,&dat)
22        };
23    } else {
24        std::io::stdout().write_all(&dat).expect("could not write stdout")
25    }
26}
27
28pub fn get(cmd: &clap::ArgMatches) -> STDRESULT {
29    // presence of arguments should already be resolved
30    let src_path = cmd.get_one::<String>("file").expect(RCH);
31    let typ = ItemType::from_str(&cmd.get_one::<String>("type").expect(RCH)).expect(RCH);
32    let maybe_img_path = cmd.get_one::<String>("dimg");
33    let fmt = super::get_fmt(cmd)?;
34    let maybe_explicit_list = cmd.get_one::<String>("explicit");
35
36    match crate::create_img_from_file_or_stdin(maybe_img_path) {
37        Ok(mut img) => {
38            img.change_method(Method::from_str(cmd.get_one::<String>("method").unwrap())?);
39            if let Some(fmt) = fmt {
40                img.change_format(fmt)?;
41            }
42            let bytes = match typ {
43                ItemType::Sector => {
44                    let mut cum: Vec<u8> = Vec::new();
45                    let mut sector_list = super::parse_sector_request(&src_path,img.motor_steps_per_cyl())?;
46                    if let Some(explicit_list) = maybe_explicit_list {
47                        super::to_explicit(&explicit_list,&mut sector_list)?;
48                    }
49                    for (trk,sec) in sector_list {
50                        cum.append(&mut img.read_sector(trk,sec)?);
51                    }
52                    cum
53                },
54                ItemType::Track => {
55                    img.get_track_nibbles(super::request_one_track(&src_path,img.motor_steps_per_cyl())?)?
56                },
57                ItemType::RawTrack => {
58                    img.get_track_buf(super::request_one_track(&src_path,img.motor_steps_per_cyl())?)?
59                },
60                _ => panic!("{}",RCH)
61            };
62            return Ok(output_get(bytes,typ,img,cmd.get_flag("console")));
63        },
64        Err(e) => return Err(e)
65    }
66}
67
68pub fn get_meta(cmd: &clap::ArgMatches) -> STDRESULT {
69    // presence of arguments should already be resolved
70    let maybe_selection = cmd.get_one::<String>("file");
71    let maybe_img_path = cmd.get_one::<String>("dimg");
72
73    match crate::create_img_from_file_or_stdin(maybe_img_path) {
74        Ok(img) => {
75            match maybe_selection {
76                None => {
77                    println!("{}",img.get_metadata(Some(4)));
78                    Ok(())
79                }
80                Some(selection) => {
81                    if selection.chars().next()!=Some('/') {
82                        error!("selection string should start with `/`");
83                        return Err(Box::new(CommandError::KeyNotFound));
84                    }
85                    match json::parse(&img.get_metadata(None)) {
86                        Ok(parsed) => {
87                            let mut keys = selection.split('/');
88                            let mut obj = parsed;
89                            keys.next();
90                            while let Some(key) = keys.next() {
91                                if key=="" {
92                                    break;
93                                }
94                                match obj[key].clone() {
95                                    json::JsonValue::Null => return Err(Box::new(CommandError::KeyNotFound)),
96                                    x => { obj = x }
97                                };
98                            }
99                            println!("{}",json::stringify_pretty(obj, 4));
100                            Ok(())
101                        },
102                        Err(e) => Err(Box::new(e))
103                    }
104                }
105            }
106        },
107        Err(e) => return Err(e)
108    }
109}