module_util/file/
format.rs

1use std::fmt;
2use std::path::{Path, PathBuf};
3
4use module::Error;
5use serde::Deserialize;
6use serde::de::DeserializeOwned;
7
8/// Imports of a [`Module`].
9///
10/// See: [`Module::imports`]
11#[derive(Default, Clone, Deserialize)]
12pub struct Imports(pub(crate) Vec<PathBuf>);
13
14impl fmt::Debug for Imports {
15    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16        self.0.fmt(f)
17    }
18}
19
20impl From<Vec<PathBuf>> for Imports {
21    fn from(value: Vec<PathBuf>) -> Self {
22        Self(value)
23    }
24}
25
26impl<A> FromIterator<A> for Imports
27where
28    A: Into<PathBuf>,
29{
30    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
31        Self(iter.into_iter().map(Into::into).collect())
32    }
33}
34
35/// The top-level structure of a [`File`] module.
36///
37/// [`File`]: super::File
38#[derive(Debug, Default, Clone, Deserialize)]
39pub struct Module<T> {
40    /// Imports of the module.
41    ///
42    /// This field instructs [`File`] to additionally [`read()`] all modules
43    /// specified here.
44    ///
45    /// [`File`]: super::File
46    /// [`read()`]: super::File::read
47    #[serde(default)]
48    pub imports: Imports,
49
50    /// Value of the module.
51    #[serde(flatten)]
52    pub value: T,
53}
54
55/// The format of a file.
56///
57/// The job of a [`Format`] is to read a file, parse it and convert it to a
58/// [`Module`] so it can be merged.
59///
60/// [`File`]: super::File
61pub trait Format {
62    /// Read the module at `path`.
63    ///
64    /// See [trait-level docs](Format) for more information.
65    fn read<T>(&mut self, path: &Path) -> Result<Module<T>, Error>
66    where
67        T: DeserializeOwned;
68}