Skip to main content

limnifs_write/config/
toml.rs

1//! TOML load/serialise for `WriteConfig`.
2
3use std::path::Path;
4
5use crate::config::error::ConfigError;
6use crate::config::WriteConfig;
7
8impl WriteConfig {
9    /// Load a config from a TOML file.
10    /// # Errors
11    /// Returns [`ConfigError::Io`] on read errors, [`ConfigError::Toml`]
12    /// on parse errors, or [`ConfigError::InvalidValue`] on validation
13    /// errors.
14    pub fn from_toml(path: &Path) -> Result<Self, ConfigError> {
15        let contents = std::fs::read_to_string(path)?;
16        let config: Self = toml::from_str(&contents)?;
17        config.validate()?;
18        Ok(config)
19    }
20
21    /// Serialise to a TOML string.
22    /// # Errors
23    /// Returns [`ConfigError::TomlSer`] on serialisation errors.
24    pub fn to_toml(&self) -> Result<String, ConfigError> {
25        Ok(toml::to_string_pretty(self)?)
26    }
27
28    /// Write a serialised config to a file.
29    /// # Errors
30    /// Returns [`ConfigError::Io`] on write errors or [`ConfigError::TomlSer`]
31    /// on serialisation errors.
32    pub fn write_to_toml(&self, path: &Path) -> Result<(), ConfigError> {
33        let s = self.to_toml()?;
34        std::fs::write(path, s)?;
35        Ok(())
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn round_trip_default() {
45        let original = WriteConfig::default_v0_1();
46        let s = original.to_toml().expect("serialise");
47        let parsed: WriteConfig = toml::from_str(&s).expect("parse");
48        assert_eq!(parsed, original);
49    }
50
51    #[test]
52    fn parsed_with_all_fields() {
53        let toml = r#"
54[defaults]
55text_codec = "brotli"
56binary_codec = "lz4"
57metadata_codec = "brotli"
58metadata_quality = 5
59inline_threshold = 4096
60
61[[categorizer]]
62name = "dna"
63extensions = ["fasta", "fa"]
64codec = "glza"
65max_size = 524288
66enabled = true
67
68[chunking]
69avg_chunk_size = 8192
70min_chunk_size = 1024
71max_chunk_size = 65536
72
73[tournament]
74codecs = ["store", "lz4", "zstd", "brotli"]
75min_size_threshold = 256
76skip_for_binary = true
77
78[encryption]
79aead = "chacha20-poly1305"
80key_wrap = "x25519-hkdf"
81
82[dictionaries]
83enabled = true
84min_class_size = 100
85max_dict_size = 65536
86"#;
87        let config: WriteConfig = toml::from_str(toml).expect("parse");
88        config.validate().expect("validate");
89        assert_eq!(config.categorizers.len(), 1);
90        assert_eq!(config.categorizers[0].name, "dna");
91        assert_eq!(config.categorizers[0].max_size, Some(524_288));
92    }
93
94    #[test]
95    fn defaults_resolved_correctly() {
96        let config = WriteConfig::default_v0_1();
97        assert_eq!(config.text_codec_id().unwrap(), 0x04);
98        assert_eq!(config.binary_codec_id().unwrap(), 0x01);
99    }
100}