Allow rr-format to output several files via template
Getty Ritter
6 years ago
51 | 51 | .value_name("FILE") |
52 | 52 | .help("The desired output location (or - for stdout)")) |
53 | 53 | |
54 | .arg(clap::Arg::with_name("output-files") | |
55 | .short("O") | |
56 | .long("output-files") | |
57 | .value_name("TEMPLATE") | |
58 | .help("The desired output ")) | |
59 | ||
54 | 60 | .arg(clap::Arg::with_name("mustache") |
55 | 61 | .short("m") |
56 | 62 | .long("mustache") |
73 | 79 | .get_matches() |
74 | 80 | } |
75 | 81 | |
82 | ||
83 | fn create_output_files( | |
84 | filename_template: &str, | |
85 | recfile: rrecutils::Recfile, | |
86 | template: String, | |
87 | ) -> Result<(), failure::Error> { | |
88 | for r in recfile.records.into_iter().map( |rec| R { rec } ) { | |
89 | let mut filename = std::io::Cursor::new(Vec::new()); | |
90 | r.render(filename_template, &mut filename) | |
91 | .map_err(|e| format_err!("Rustache error: {:?}", e))?; | |
92 | let filename = String::from_utf8(filename.into_inner())?; | |
93 | println!("writing file `{}'", &filename); | |
94 | ||
95 | let mut file = std::fs::File::create(&filename)?; | |
96 | r.render(&template, &mut file) | |
97 | .map_err(|e| format_err!("Rustache error: {:?}", e))?; | |
98 | } | |
99 | Ok(()) | |
100 | } | |
101 | ||
102 | ||
103 | fn render_to_single_file( | |
104 | mut output: Box<std::io::Write>, | |
105 | joiner: Option<&str>, | |
106 | recfile: rrecutils::Recfile, | |
107 | template: String, | |
108 | ) -> Result<(), failure::Error> { | |
109 | let mut first = true; | |
110 | for r in recfile.records.into_iter() { | |
111 | if first { | |
112 | first = false; | |
113 | } else if let Some(j) = joiner { | |
114 | output.write(j.as_bytes())?; | |
115 | output.write(&['\n' as u8])?; | |
116 | } | |
117 | R { rec: r }.render(&template, &mut output.as_mut()) | |
118 | .map_err(|e| format_err!("Rustache error: {:?}", e))?; | |
119 | } | |
120 | ||
121 | Ok(()) | |
122 | } | |
123 | ||
124 | ||
76 | 125 | fn run() -> Result<(), failure::Error> { |
77 | 126 | let matches = rr_format_args(); |
78 | 127 | |
79 | 128 | let input = common::input_from_spec( |
80 | 129 | matches.value_of("input"))?; |
81 | let mut output = common::output_from_spec( | |
82 | matches.value_of("output"))?; | |
130 | ||
131 | let mut recfile = rrecutils::Recfile::parse(input)?; | |
132 | if let Some(typ) = matches.value_of("type") { | |
133 | recfile.filter_by_type(typ); | |
134 | } | |
83 | 135 | |
84 | 136 | let template: String = match matches.value_of("mustache") { |
85 | 137 | Some(path) => { |
91 | 143 | None => bail!("No template specified!"), |
92 | 144 | }; |
93 | 145 | |
94 | let mut recfile = rrecutils::Recfile::parse(input)?; | |
95 | ||
96 | if let Some(typ) = matches.value_of("type") { | |
97 | recfile.filter_by_type(typ); | |
98 | } | |
99 | ||
100 | ||
101 | let joiner = matches.value_of("joiner"); | |
102 | ||
103 | let mut first = true; | |
104 | for r in recfile.records.into_iter() { | |
105 | if first { | |
106 | first = false; | |
107 | } else if let Some(j) = joiner { | |
108 | output.write(j.as_bytes())?; | |
109 | output.write(&['\n' as u8])?; | |
110 | } | |
111 | R { rec: r }.render(&template, &mut output.as_mut()) | |
112 |
|
|
146 | if let Some(filename) = matches.value_of("output-files") { | |
147 | create_output_files(filename, recfile, template)?; | |
148 | } else { | |
149 | render_to_single_file( | |
150 | common::output_from_spec(matches.value_of("output"))?, | |
151 | matches.value_of("joiner"), | |
152 | recfile, | |
153 | template, | |
154 | )?; | |
113 | 155 | } |
114 | 156 | |
115 | 157 | Ok(()) |