langcodec/
traits.rs

1//! Traits for format-agnostic parsing and serialization in langcodec.
2
3use std::{
4    fs::File,
5    io::{BufRead, BufReader, BufWriter, Cursor, Write},
6    path::Path,
7};
8
9use crate::error::Error;
10
11/// A trait for parsing and writing localization resources from/to one file.
12///
13/// # Example
14///
15/// ```rust,no_run
16/// use langcodec::traits::Parser;
17/// let format = langcodec::formats::strings::Format::read_from("en.strings")?;
18/// format.write_to("en_copy.strings")?;
19/// Ok::<(), Box<dyn std::error::Error>>(())
20/// ```
21pub trait Parser {
22    /// Parse from any reader.
23    fn from_reader<R: BufRead>(reader: R) -> Result<Self, Error>
24    where
25        Self: Sized;
26
27    /// Parse from file path.
28    fn read_from<P: AsRef<Path>>(path: P) -> Result<Self, Error>
29    where
30        Self: Sized,
31    {
32        let file = File::open(path).map_err(Error::Io)?;
33        let reader = BufReader::new(file);
34        Self::from_reader(reader)
35    }
36
37    /// Write to any writer (file, memory, etc.).
38    fn to_writer<W: Write>(&self, writer: W) -> Result<(), Error>;
39
40    /// Write to file path.
41    /// Ensures all parent directories are created before writing.
42    fn write_to<P: AsRef<Path>>(&self, path: P) -> Result<(), Error> {
43        let path = path.as_ref();
44        if let Some(parent) = path.parent() {
45            std::fs::create_dir_all(parent).map_err(Error::Io)?;
46        }
47        let file = File::create(path).map_err(Error::Io)?;
48        let writer = BufWriter::new(file);
49        self.to_writer(writer)
50    }
51
52    /// Parse from a string.
53    fn from_str(s: &str) -> Result<Self, Error>
54    where
55        Self: Sized,
56    {
57        Self::from_reader(Cursor::new(s))
58    }
59
60    /// Parse from bytes.
61    fn from_bytes(bytes: &[u8]) -> Result<Self, Error>
62    where
63        Self: Sized,
64    {
65        Self::from_reader(Cursor::new(bytes))
66    }
67}