sfs_core/spectrum/io/
read.rs

1//! Utilities for reading spectra.
2
3use std::io::{self, Read};
4
5use crate::{Array, Input, Scs};
6
7use super::{text, Format};
8
9/// A builder to read a spectrum.
10#[derive(Debug, Default)]
11pub struct Builder {
12    input: Option<Input>,
13    format: Option<Format>,
14}
15
16impl Builder {
17    /// Read a spectrum from reader.
18    pub fn read(self) -> io::Result<Scs> {
19        let mut raw = Vec::new();
20
21        _ = match self.input.unwrap_or(Input::Stdin).open()? {
22            crate::input::Reader::File(mut reader) => reader.read_to_end(&mut raw)?,
23            crate::input::Reader::Stdin(mut reader) => reader.read_to_end(&mut raw)?,
24        };
25
26        let format = self.format.or_else(|| Format::detect(&raw));
27
28        let reader = &mut &raw[..];
29        match format {
30            Some(Format::Text) => text::read_scs(reader),
31            Some(Format::Npy) => Array::read_npy(reader).map(Scs::from),
32            None => Err(io::Error::new(io::ErrorKind::InvalidData, "invalid format")),
33        }
34    }
35
36    /// Set input source.
37    ///
38    /// If unset, the input source will default to stdin.
39    pub fn set_input(mut self, input: Input) -> Self {
40        self.input = Some(input);
41        self
42    }
43
44    /// Set format to read.
45    ///
46    /// If unset, the format will automatically be detected when reading.
47    pub fn set_format(mut self, format: Format) -> Self {
48        self.format = Some(format);
49        self
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    use crate::array::npy;
58
59    #[test]
60    fn test_detect_npy() {
61        assert_eq!(Format::detect_npy(&npy::MAGIC), Some(Format::Npy));
62
63        let mut bytes = npy::MAGIC.to_vec();
64        bytes.extend(b"foobar");
65        assert_eq!(Format::detect(&bytes), Some(Format::Npy));
66    }
67
68    #[test]
69    fn test_detect_plain_text() {
70        assert_eq!(Format::detect_plain_text(&text::START), Some(Format::Text));
71
72        let mut bytes = text::START.to_vec();
73        bytes.extend(b"=<17/19>\n1 2 3");
74        assert_eq!(Format::detect(&bytes), Some(Format::Text));
75    }
76}