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    /// Variant for binary files containing Python-exposed multi-determinants.
30    Pymdet,
31}
32
33impl QSym2FileType {
34    /// Returns the extension of the file type.
35    pub fn ext(&self) -> String {
36        match self {
37            QSym2FileType::Sym => "qsym2.sym".to_string(),
38            QSym2FileType::Grp => "qsym2.grp".to_string(),
39            QSym2FileType::Rep => "qsym2.rep".to_string(),
40            QSym2FileType::Chr => "qsym2.chr".to_string(),
41            QSym2FileType::Pymdet => "qsym2.pymdet".to_string(),
42        }
43    }
44}
45
46/// Reads a `QSym2` binary file and deserialises it into an appropriate structure.
47///
48/// # Arguments
49///
50/// * `name` - The name of the file to be read in (without `QSym2`-specific extensions).
51/// * `file_type` - The type of the `QSym2` file to be read in.
52///
53/// # Returns
54///
55/// A `Result` containing the structure deserialised from the read-in file.
56pub fn read_qsym2_binary<T, P: AsRef<Path>>(
57    name: P,
58    file_type: QSym2FileType,
59) -> Result<T, anyhow::Error>
60where
61    T: DeserializeOwned,
62{
63    let mut path = name.as_ref().to_path_buf();
64    path.set_extension(file_type.ext());
65    let mut reader = BufReader::new(File::open(path).map_err(|err| format_err!(err))?);
66    bincode::serde::decode_from_std_read(&mut reader, bincode::config::legacy())
67        .map_err(|err| format_err!(err))
68}
69
70/// Serialises a structure and writes into a `QSym2` binary file.
71///
72/// # Arguments
73///
74/// * `name` - The name of the file to be written (without `QSym2`-specific extensions).
75/// * `file_type` - The type of the `QSym2` file to be written.
76///
77/// # Returns
78///
79/// A `Result` indicating if the serialisation and writing processes have been successful.
80pub fn write_qsym2_binary<T, P: AsRef<Path>>(
81    name: P,
82    file_type: QSym2FileType,
83    value: &T,
84) -> Result<usize, anyhow::Error>
85where
86    T: Serialize,
87{
88    let mut path = name.as_ref().to_path_buf();
89    path.set_extension(file_type.ext());
90    let mut writer = BufWriter::new(File::create(path)?);
91    bincode::serde::encode_into_std_write(value, &mut writer, bincode::config::legacy())
92        .map_err(|err| format_err!(err))
93}
94
95/// Reads a `QSym2` configuration YAML file and deserialises it into an appropriate structure.
96///
97/// # Arguments
98///
99/// * `name` - The name of the file to be read in (with its `.yml` or `.yaml` extension).
100///
101/// # Returns
102///
103/// A `Result` containing the structure deserialised from the read-in file.
104pub fn read_qsym2_yaml<T, P: AsRef<Path>>(name: P) -> Result<T, anyhow::Error>
105where
106    T: DeserializeOwned,
107{
108    let mut reader = BufReader::new(File::open(name).map_err(|err| format_err!(err))?);
109    serde_yaml::from_reader(&mut reader).map_err(|err| format_err!(err))
110}
111
112/// Serialises a structure and writes into a `QSym2` configuration YAML file.
113///
114/// # Arguments
115///
116/// * `name` - The name of the YAML file to be written (without extensions). The resulting file
117///   will have the `.yml` extension.
118///
119/// # Returns
120///
121/// A `Result` indicating if the serialisation and writing processes have been successful.
122pub fn write_qsym2_yaml<T, P: AsRef<Path>>(name: P, value: &T) -> Result<(), anyhow::Error>
123where
124    T: Serialize,
125{
126    let mut path = name.as_ref().to_path_buf();
127    path.set_extension("yml");
128    let mut writer = BufWriter::new(File::create(path)?);
129    serde_yaml::to_writer(&mut writer, value).map_err(|err| format_err!(err))
130}