1use crate::file_format::OutputFormat;
2use crate::{Cosmogony, Zone};
3use anyhow::{anyhow, Error};
4use std::path::Path;
5
6fn 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
25pub 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
33pub 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
56fn 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}