Skip to main content

spectrashop_to_json/
spectrashop_to_json.rs

1//! Convert a SpectraShop `.txt` export to the `spectral-io` JSON format.
2//!
3//! # Usage
4//!
5//! ```text
6//! spectrashop_to_json [-c <copyright>] <input.txt> [output.json]
7//! ```
8//!
9//! If no output path is given the JSON is written to stdout.
10
11use spectral_io::SpectrumFile;
12use std::{env, fs, path::PathBuf, process};
13
14fn usage(prog: &str) -> ! {
15    eprintln!("Usage: {prog} [-c <copyright>] <input.txt> [output.json]");
16    eprintln!();
17    eprintln!("Options:");
18    eprintln!("  -c <string>   Copyright notice embedded in every spectrum record.");
19    eprintln!();
20    eprintln!("If no output file is given the JSON is written to stdout.");
21    process::exit(1);
22}
23
24fn main() {
25    let args: Vec<String> = env::args().collect();
26    let prog = &args[0];
27
28    let mut copyright: Option<String> = None;
29    let mut positional: Vec<String> = Vec::new();
30
31    let mut i = 1;
32    while i < args.len() {
33        match args[i].as_str() {
34            "-c" => {
35                i += 1;
36                if i >= args.len() {
37                    eprintln!("error: -c requires an argument");
38                    usage(prog);
39                }
40                copyright = Some(args[i].clone());
41            }
42            arg if arg.starts_with('-') => {
43                eprintln!("error: unknown option '{arg}'");
44                usage(prog);
45            }
46            _ => positional.push(args[i].clone()),
47        }
48        i += 1;
49    }
50
51    if positional.is_empty() {
52        usage(prog);
53    }
54
55    let input = PathBuf::from(&positional[0]);
56    let output: Option<PathBuf> = positional.get(1).map(PathBuf::from);
57
58    let mut file = SpectrumFile::from_spectrashop_path(&input).unwrap_or_else(|e| {
59        eprintln!("error: {e}");
60        process::exit(1);
61    });
62
63    if let Some(ref cr) = copyright {
64        match &mut file {
65            SpectrumFile::Single { spectrum, .. } => {
66                spectrum.metadata.copyright = Some(cr.clone());
67            }
68            SpectrumFile::Batch { spectra, .. } => {
69                for sp in spectra.iter_mut() {
70                    sp.metadata.copyright = Some(cr.clone());
71                }
72            }
73        }
74    }
75
76    let json = serde_json::to_string_pretty(&file).unwrap_or_else(|e| {
77        eprintln!("error serialising to JSON: {e}");
78        process::exit(1);
79    });
80
81    match output {
82        Some(ref path) => {
83            fs::write(path, &json).unwrap_or_else(|e| {
84                eprintln!("error writing to {}: {e}", path.display());
85                process::exit(1);
86            });
87            eprintln!("Written to {}", path.display());
88        }
89        None => print!("{json}"),
90    }
91}