gdritter repos rrecutils / 54f9ea9
Switch over to Failure instead of custom errors Getty Ritter 6 years ago
5 changed file(s) with 71 addition(s) and 52 deletion(s). Collapse all Expand all
1313 serde_json = "*"
1414 clap = "2.27.1"
1515 rustache = "*"
16 failure = "*"
1617
1718 [[bin]]
1819 name = "rr-pretty"
1 #[macro_use] extern crate failure;
2
13 pub mod contlines;
24
35 use contlines::ContinuationLines;
5557 }
5658 }
5759
60 #[derive(Debug, Fail)]
61 pub enum RecError {
62 #[fail(display = "Error parsing records: {}", message)]
63 GenericError {
64 message: String,
65 },
66
67 #[fail(display = "Found cont line in nonsensical place: {}", ln)]
68 BadContLine {
69 ln: String,
70 },
71
72 #[fail(display = "Invalid line: {}", ln)]
73 InvalidLine {
74 ln: String,
75 },
76 }
77
5878
5979 impl Recfile {
60 pub fn parse<I>(i: I) -> Result<Recfile, String>
80 pub fn parse<I>(i: I) -> Result<Recfile, RecError>
6181 where I: std::io::BufRead
6282 {
6383 let mut iter = ContinuationLines::new(i.lines());
93113 &ln[1..]
94114 });
95115 } else {
96 return Err(format!(
97 "Found continuation line in nonsensical place: {}",
98 ln));
116 return Err(RecError::BadContLine{ ln: ln.to_owned() });
99117 }
100118 } else if let Some(pos) = ln.find(':') {
101119 let (key, val) = ln.split_at(pos);
106124 ctx.current_record_type = Some(val[1..].trim_left().to_owned());
107125 }
108126 } else {
109 return Err(format!("Invalid line: {:?}", ln));
127 return Err(RecError::InvalidLine { ln: ln.to_owned() });
110128 }
111129 }
112130
1 #![allow(dead_code)]
2
13 use std::{fs,io};
24
5 /// This can be changed to modify all the tool metadata all at once
36 pub const VERSION: &'static str = "0.0";
47 pub const AUTHOR: &'static str =
58 "Getty Ritter <rrecutils@infinitenegativeutility.com>";
11 extern crate clap;
22 extern crate rrecutils;
33 extern crate rustache;
4 #[macro_use] extern crate failure;
45
56 use std::{fs,io};
6 use std::convert::From;
7 use std::string::FromUtf8Error;
87
98 mod common;
109
3029 hb = hb.insert(&field.0, field.1.clone());
3130 }
3231 hb.render(template, writer)
33 }
34 }
35
36 enum FormatErr {
37 IOError(io::Error),
38 Utf8Error(FromUtf8Error),
39 Rustache(rustache::RustacheError),
40 Generic(String),
41 }
42
43 impl From<io::Error> for FormatErr {
44 fn from(err: io::Error) -> FormatErr {
45 FormatErr::IOError(err)
46 }
47 }
48
49 impl From<FromUtf8Error> for FormatErr {
50 fn from(err: FromUtf8Error) -> FormatErr {
51 FormatErr::Utf8Error(err)
52 }
53 }
54
55 impl From<rustache::RustacheError> for FormatErr {
56 fn from(err: rustache::RustacheError) -> FormatErr {
57 FormatErr::Rustache(err)
58 }
59 }
60
61 impl From<String> for FormatErr {
62 fn from(err: String) -> FormatErr {
63 FormatErr::Generic(err)
6432 }
6533 }
6634
10573 .get_matches()
10674 }
10775
108 fn run() -> Result<(), FormatErr> {
76 fn run() -> Result<(), failure::Error> {
10977 let matches = rr_format_args();
11078
11179 let input = common::input_from_spec(
12088 fs::File::open(path)?.read_to_end(&mut buf)?;
12189 String::from_utf8(buf)?
12290 },
123 None => Err(format!("No template specified!"))?,
91 None => bail!("No template specified!"),
12492 };
12593
12694 let mut recfile = rrecutils::Recfile::parse(input)?;
140108 output.write(j.as_bytes())?;
141109 output.write(&['\n' as u8])?;
142110 }
143 R { rec: r }.render(&template, &mut output.as_mut())?;
111 R { rec: r }.render(&template, &mut output.as_mut())
112 .map_err(|e| format_err!("Rustache error: {:?}", e))?;
144113 }
145114
146115 Ok(())
147116 }
148117
149118 fn main() {
150 use FormatErr::*;
151119 match run() {
152120 Ok(()) => (),
153 Err(IOError(_)) => panic!("IO Error"),
154 Err(Utf8Error(_)) => panic!("Cannot decode as UTF-8"),
155 Err(Rustache(r)) => panic!("Rustache error: {:?}", r),
156 Err(Generic(s)) => panic!("{}", s),
121 Err(e) => println!("{}", e),
157122 }
158123 }
11 extern crate clap;
22 extern crate rrecutils;
3 extern crate failure;
34
45 mod common;
56
6 fn main() {
7 let matches = clap::App::new("rr-sel")
7 use failure::Error;
8
9 fn rr_select_args() -> clap::ArgMatches<'static> {
10 clap::App::new("rr-sel")
811 .version(common::VERSION)
912 .author(common::AUTHOR)
1013 .about("Print records from a recfile")
14
15 .arg(clap::Arg::with_name("input")
16 .short("i")
17 .long("input")
18 .value_name("FILE")
19 .help("The input recfile (or - for stdin)"))
20
21 .arg(clap::Arg::with_name("output")
22 .short("o")
23 .long("output")
24 .value_name("FILE")
25 .help("The desired output location (or - for stdout)"))
1126
1227 .arg(clap::Arg::with_name("type")
1328 .long("type")
3954 .required(false)
4055 .takes_value(true))
4156
42 .get_matches();
57 .get_matches()
58 }
4359
44 let source = std::io::stdin();
45 let mut records = rrecutils::Recfile::parse(source.lock()).unwrap();
60 fn run() -> Result<(), Error> {
61 let matches = rr_select_args();
62
63 let input = common::input_from_spec(
64 matches.value_of("input"))?;
65 let mut output = common::output_from_spec(
66 matches.value_of("output"))?;
67
68 let mut records = rrecutils::Recfile::parse(input)?;
4669
4770 if let Some(typ) = matches.value_of("type") {
4871 records.filter_by_type(typ);
4972 }
5073
51 records.write(&mut std::io::stdout());
74 records.write(&mut output)?;
75
76 Ok(())
5277 }
78
79 fn main() {
80 match run() {
81 Ok(()) => (),
82 Err(e) => println!("{}", e),
83 }
84 }