chur_build/cfg/
builder.rs

1use std::fmt::Display;
2
3#[cfg(feature = "codegen")]
4use std::path::PathBuf;
5
6use crate::{defined_constants::ROOT_MANIFEST_DIR, dependency::Dependency};
7
8use super::Config;
9use crate::error::ChurResult;
10
11#[derive(Debug, Default)]
12pub struct ConfigBuilder {
13    root_dir: String,
14
15    dependencies: Vec<Dependency>,
16
17    protos: Vec<String>,
18    file_descriptors: bool,
19
20    #[cfg(feature = "codegen")]
21    codegen: Option<String>,
22}
23
24impl ConfigBuilder {
25    pub fn new() -> Self {
26        Self::default()
27    }
28
29    /// Root Directory of the location of your `.proto` files.
30    ///
31    /// This is a folder relative to the workspace directory.
32    pub fn root_dir(mut self, root_dir: impl Display) -> Self {
33        self.root_dir = root_dir.to_string();
34        self
35    }
36
37    /// Define the dependencies of this project, refer to [Dependency](crate::Dependency)
38    /// for documentation.
39    ///
40    /// Can be called multiple times for multiple dependencies.
41    pub fn dependency(mut self, dependency: Dependency) -> Self {
42        self.dependencies.push(dependency);
43        self
44    }
45
46    /// Define the proto files for compilation.
47    ///
48    /// For a gRPC setup this would only require you to references the wanted services,
49    /// dependencies of those services will be imported.
50    pub fn protos(mut self, protos: impl IntoIterator<Item = impl Display>) -> Self {
51        let mut protos_as_strings = protos
52            .into_iter()
53            .map(|item| item.to_string())
54            .collect::<Vec<String>>();
55        self.protos.append(&mut protos_as_strings);
56
57        self
58    }
59
60    /// Generate file descriptors
61    pub fn file_descriptors(mut self, file_descriptors: bool) -> Self {
62        self.file_descriptors = file_descriptors;
63        self
64    }
65
66    #[cfg(feature = "codegen")]
67    /// Instead of just making the manifest, forcing to use [`chur::include_tree`][include_tree]
68    /// just dump the code into a file at the provided path.
69    ///
70    /// This works better with rust-analyzer.
71    ///
72    /// Provided path should be relative to the workspace `Cargo.toml`.
73    ///
74    /// [include_tree]: https://docs.rs/chur/latest/chur/macro.include_tree.html
75    pub fn codegen(mut self, codegen_path: impl ToString) -> Self {
76        self.codegen = Some(codegen_path.to_string());
77        self
78    }
79
80    /// Build the [ConfigBuilder] into a [Config]
81    ///
82    /// This changes the directories used to be absolute.
83    pub fn build(self) -> ChurResult<Config> {
84        let root_dir = ROOT_MANIFEST_DIR.join(self.root_dir);
85
86        let protos = self
87            .protos
88            .into_iter()
89            .map(|dir| root_dir.join(dir))
90            .collect::<Vec<_>>();
91
92        Ok(Config {
93            root_dir,
94            protos,
95            dependencies: self.dependencies,
96            file_descriptors: self.file_descriptors,
97
98            #[cfg(feature = "codegen")]
99            codegen: self.codegen.map(PathBuf::from),
100        })
101    }
102}