cosmogony/
read.rs

1use crate::file_format::OutputFormat;
2use crate::{Cosmogony, Zone};
3use anyhow::{anyhow, Error};
4use std::path::Path;
5
6// Stream Cosmogony's Zone from a Reader
7fn read_zones(
8    reader: impl std::io::BufRead,
9) -> impl std::iter::Iterator<Item = Result<Zone, Error>> {
10    reader
11        .lines()
12        .map(|l| l.map_err(|err| err.into()))
13        .map(|l| l.and_then(|l| serde_json::from_str(&l).map_err(|err| anyhow!("{}", err))))
14}
15
16fn from_json_stream(reader: impl std::io::BufRead) -> Result<Cosmogony, Error> {
17    let zones = read_zones(reader).collect::<Result<_, _>>()?;
18
19    Ok(Cosmogony {
20        zones,
21        ..Default::default()
22    })
23}
24
25/// Load a cosmogony from a file
26pub fn load_cosmogony_from_file(input: impl AsRef<Path>) -> Result<Cosmogony, Error> {
27    let format = OutputFormat::from_filename(input.as_ref())?;
28    let f = std::fs::File::open(&input)?;
29    let f = std::io::BufReader::new(f);
30    load_cosmogony(f, format)
31}
32
33/// Return an iterator on the zones
34/// if the input file is a jsonstream, the zones are streamed
35/// if the input file is a json, the whole cosmogony is loaded
36pub fn read_zones_from_file(
37    input: impl AsRef<Path>,
38) -> Result<Box<dyn Iterator<Item = Result<Zone, Error>> + Send + Sync>, Error> {
39    let format = OutputFormat::from_filename(input.as_ref())?;
40    let f = std::fs::File::open(input.as_ref())?;
41    let f = std::io::BufReader::new(f);
42    match format {
43        OutputFormat::JsonGz | OutputFormat::Json => {
44            let cosmo = load_cosmogony(f, format)?;
45            Ok(Box::new(cosmo.zones.into_iter().map(Ok)))
46        }
47        OutputFormat::JsonStream => Ok(Box::new(read_zones(f))),
48        OutputFormat::JsonStreamGz => {
49            let r = flate2::bufread::GzDecoder::new(f);
50            let r = std::io::BufReader::new(r);
51            Ok(Box::new(read_zones(r)))
52        }
53    }
54}
55
56// Load a cosmogony from a reader and a file_format
57fn load_cosmogony(reader: impl std::io::BufRead, format: OutputFormat) -> Result<Cosmogony, Error> {
58    match format {
59        OutputFormat::JsonGz => {
60            let r = flate2::read::GzDecoder::new(reader);
61            serde_json::from_reader(r).map_err(|err| anyhow!("{}", err))
62        }
63        OutputFormat::Json => serde_json::from_reader(reader).map_err(|err| anyhow!("{}", err)),
64        OutputFormat::JsonStream => from_json_stream(reader),
65        OutputFormat::JsonStreamGz => {
66            let r = flate2::bufread::GzDecoder::new(reader);
67            let r = std::io::BufReader::new(r);
68            from_json_stream(r)
69        }
70    }
71}