qsym2/io/
mod.rs

1//! QSym² I/O operations.
2
3use std::fs::File;
4use std::io::{BufReader, BufWriter};
5use std::path::Path;
6
7use anyhow::{self, format_err};
8use bincode;
9use serde::{de::DeserializeOwned, Serialize};
10use serde_yaml;
11
12pub(crate) mod format;
13pub(crate) mod numeric;
14
15/// Enumerated type for `QSym2` file types.
16pub enum QSym2FileType {
17    /// Variant for binary files containing symmetry-group detection results.
18    Sym,
19
20    /// Variant for binary files containing symmetry groups.
21    Grp,
22
23    /// Variant for binary files containing representation analysis results.
24    Rep,
25
26    /// Variant for binary files containing character tables.
27    Chr,
28}
29
30impl QSym2FileType {
31    /// Returns the extension of the file type.
32    pub fn ext(&self) -> String {
33        match self {
34            QSym2FileType::Sym => "qsym2.sym".to_string(),
35            QSym2FileType::Grp => "qsym2.grp".to_string(),
36            QSym2FileType::Rep => "qsym2.rep".to_string(),
37            QSym2FileType::Chr => "qsym2.chr".to_string(),
38        }
39    }
40}
41
42/// Reads a `QSym2` binary file and deserialises it into an appropriate structure.
43///
44/// # Arguments
45///
46/// * `name` - The name of the file to be read in (without `QSym2`-specific extensions).
47/// * `file_type` - The type of the `QSym2` file to be read in.
48///
49/// # Returns
50///
51/// A `Result` containing the structure deserialised from the read-in file.
52pub fn read_qsym2_binary<T, P: AsRef<Path>>(
53    name: P,
54    file_type: QSym2FileType,
55) -> Result<T, anyhow::Error>
56where
57    T: DeserializeOwned,
58{
59    let mut path = name.as_ref().to_path_buf();
60    path.set_extension(file_type.ext());
61    let mut reader = BufReader::new(File::open(path).map_err(|err| format_err!(err))?);
62    bincode::serde::decode_from_std_read(&mut reader, bincode::config::legacy())
63        .map_err(|err| format_err!(err))
64}
65
66/// Serialises a structure and writes into a `QSym2` binary file.
67///
68/// # Arguments
69///
70/// * `name` - The name of the file to be written (without `QSym2`-specific extensions).
71/// * `file_type` - The type of the `QSym2` file to be written.
72///
73/// # Returns
74///
75/// A `Result` indicating if the serialisation and writing processes have been successful.
76pub fn write_qsym2_binary<T, P: AsRef<Path>>(
77    name: P,
78    file_type: QSym2FileType,
79    value: &T,
80) -> Result<usize, anyhow::Error>
81where
82    T: Serialize,
83{
84    let mut path = name.as_ref().to_path_buf();
85    path.set_extension(file_type.ext());
86    let mut writer = BufWriter::new(File::create(path)?);
87    bincode::serde::encode_into_std_write(value, &mut writer, bincode::config::legacy())
88        .map_err(|err| format_err!(err))
89}
90
91/// Reads a `QSym2` configuration YAML file and deserialises it into an appropriate structure.
92///
93/// # Arguments
94///
95/// * `name` - The name of the file to be read in (with its `.yml` or `.yaml` extension).
96///
97/// # Returns
98///
99/// A `Result` containing the structure deserialised from the read-in file.
100pub fn read_qsym2_yaml<T, P: AsRef<Path>>(name: P) -> Result<T, anyhow::Error>
101where
102    T: DeserializeOwned,
103{
104    let mut reader = BufReader::new(File::open(name).map_err(|err| format_err!(err))?);
105    serde_yaml::from_reader(&mut reader).map_err(|err| format_err!(err))
106}
107
108/// Serialises a structure and writes into a `QSym2` configuration YAML file.
109///
110/// # Arguments
111///
112/// * `name` - The name of the YAML file to be written (without extensions). The resulting file
113/// will have the `.yml` extension.
114///
115/// # Returns
116///
117/// A `Result` indicating if the serialisation and writing processes have been successful.
118pub fn write_qsym2_yaml<T, P: AsRef<Path>>(name: P, value: &T) -> Result<(), anyhow::Error>
119where
120    T: Serialize,
121{
122    let mut path = name.as_ref().to_path_buf();
123    path.set_extension("yml");
124    let mut writer = BufWriter::new(File::create(path)?);
125    serde_yaml::to_writer(&mut writer, value).map_err(|err| format_err!(err))
126}