gdext_gen/args/
icons.rs

1//! Module with the structs and enums
2
3use std::{collections::HashMap, env::var, path::PathBuf};
4
5use super::BaseDirectory;
6
7/// Represents one of the three avilable default nodes for Rust.
8#[derive(Default, Debug, Clone, Copy, PartialEq)]
9#[repr(usize)]
10#[cfg(feature = "find_icons")]
11pub enum NodeRust {
12    /// Small version of the icon based on the `godot-rust` logo.
13    #[default]
14    Small,
15    /// Large version of the icon based on the `godot-rust` logo.
16    Large,
17    /// Icon based on `Rust`'s Ferris.
18    Ferris,
19}
20
21/// Node icon to use as the default node when none are specified.
22#[derive(Default, Debug, Clone, PartialEq)]
23#[cfg(feature = "find_icons")]
24pub enum DefaultNodeIcon {
25    /// When using a custom icon. The path used is relative to the base directory for icons.
26    Custom(PathBuf),
27    /// When using the icon of the base class of the node. They will always be searched for in the editor directory for icons.
28    BaseClass,
29    #[allow(rustdoc::private_intra_doc_links)]
30    /// When using one of the [`NODES_RUST`](crate::NODES_RUST) icon. The path used is relative to the to the base directory for icons, but it's only to the folder that contains the `NodeRust` files, it must NOT have the filename in it.
31    NodeRust(NodeRust, PathBuf),
32    /// When using the default Godot node icon.
33    #[default]
34    Node,
35}
36
37/// How to copy the files needed for the icons to be displayed.
38#[derive(Default, Debug)]
39pub struct IconsCopyStrategy {
40    /// Whether or not to copy the `NodeRust` file. Available with "find_icons" feature.
41    #[cfg(feature = "find_icons")]
42    pub copy_node_rust: bool,
43    /// Whether or not to copy all the `NodeRust` files.
44    pub copy_all: bool,
45    /// Path to the folder where the icon will be copied relative to the *crate folder*.
46    pub path_node_rust: PathBuf,
47    /// Whether or not to copy if the files already exist.
48    pub force_copy: bool,
49}
50
51impl IconsCopyStrategy {
52    /// Creates a new instance of [`IconsCopyStrategy`], by giving it all its fields.
53    ///
54    /// # Parameters
55    ///
56    /// * `copy_node_rust` - Whether or not to copy the NodeRust.svg file. Available with "find_icons" feature.
57    /// * `copy_all` - Whether or not to copy all the `NodeRust` files.
58    /// * `path_node_rust` - Path to the icon copied relative to the *crate folder*.
59    /// * `force_copy` - Whether or not to copy if the files already exist.
60    ///
61    /// # Returns
62    ///
63    /// The [`IconsCopyStrategy`] instancte with its fields initialized.
64    pub fn new(
65        #[cfg(feature = "find_icons")] copy_node_rust: bool,
66        copy_all: bool,
67        path_node_rust: PathBuf,
68        force_copy: bool,
69    ) -> Self {
70        Self {
71            #[cfg(feature = "find_icons")]
72            copy_node_rust,
73            copy_all,
74            path_node_rust,
75            force_copy,
76        }
77    }
78
79    /// Changes the `copy_node_rust` field to `true` and returns the same struct.
80    ///
81    /// # Returns
82    ///
83    /// The same [`IconsCopyStrategy`] it was passed to it with `copy_node_rust` set to `true`.
84    #[cfg(feature = "find_icons")]
85    pub fn copying_node_rust(mut self) -> Self {
86        self.copy_node_rust = true;
87
88        self
89    }
90
91    /// Changes the `path_node_rust` field to the one indicated and returns the same struct.
92    ///
93    /// # Parameters
94    ///
95    /// * `path_node_rust` - Path to the icon copied relative to the *crate folder*.
96    ///
97    /// # Returns
98    ///
99    /// The same [`IconsCopyStrategy`] it was passed to it with `path_node_rust` set to one passed by parameter.
100    pub fn with_path_node_rust(mut self, path_node_rust: PathBuf) -> Self {
101        self.path_node_rust = path_node_rust;
102
103        self
104    }
105
106    /// Changes the `copy_all` field to `true` and returns the same struct.
107    ///
108    /// # Returns
109    ///
110    /// The same [`IconsCopyStrategy`] it was passed to it with `copy_node_rust` set to `true`.
111    pub fn copying_all(mut self) -> Self {
112        self.copy_all = true;
113
114        self
115    }
116
117    /// Changes the `force_copy` field to `true` and returns the same struct.
118    ///
119    /// # Returns
120    ///
121    /// The same [`IconsCopyStrategy`] it was passed to it with `force_copy` set to `true`.
122    pub fn forcing_copy(mut self) -> Self {
123        self.force_copy = true;
124
125        self
126    }
127}
128
129/// The **relative** paths of the directories where the icons are stored. They will be stored with [`to_string_lossy`](std::path::Path::to_string_lossy), so the directories must be composed of Unicode characters.
130#[derive(Debug)]
131pub struct IconsDirectories {
132    /// The path to the folder **relative** to `{relative_dir.as_str()}` where all the icons are stored. Defaults to the "addons" folder.
133    pub base_directory: PathBuf,
134    /// The path to the folder **relative** to `{relative_dir.as_str()}{base_directory}` where all the editor icons are stored. Defaults to the "editor" folder inside addons.
135    pub editor_directory: PathBuf,
136    /// The path to the folder **relative** to `{relative_dir.as_str()}{base_directory}` where all the custom icons for this library are stored. Defaults to the "{crate_name}" folder inside addons.
137    pub custom_directory: PathBuf,
138    /// The folder to use as a base for the base directory of icons. If [`None`] is provided, the one used to call [`generate_gdextension_file`](crate::generate_gdextension_file) will be used instead.
139    pub relative_directory: Option<BaseDirectory>,
140}
141
142impl Default for IconsDirectories {
143    fn default() -> Self {
144        Self {
145            base_directory: "addons".into(),
146            editor_directory: "editor".into(),
147            custom_directory: var("CARGO_PKG_NAME").map_or("rust".into(), |entry_symbol| {
148                entry_symbol.replace('-', "_").into()
149            }),
150            relative_directory: None,
151        }
152    }
153}
154
155impl IconsDirectories {
156    /// Creates a new instance of [`IconsDirectories`], by giving it all its fields.
157    ///
158    /// # Parameters
159    ///
160    /// * `base_directory` - The path to the folder **relative** to `{relative_dir.as_str()}` where all the icons are stored. Defaults to the "addons" folder.
161    /// * `editor_directory` - The path to the folder **relative** to `{relative_dir.as_str()}{base_directory}` where all the editor icons are stored. Defaults to the "editor" folder inside addons.
162    /// * `custom_directory` - The path to the folder **relative** to `{relative_dir.as_str()}{base_directory}` where all the custom icons for this library are stored. Defaults to "", so the same as the base directory.
163    /// * `relative_directory` - The folder to use as a base for the base directory of icons. If [`None`] is provided, the one used to call [`generate_gdextension_file`](crate::generate_gdextension_file) will be used instead.
164    ///
165    /// # Returns
166    ///
167    /// The [`IconsDirectories`] instance with its fields initialized.
168    pub fn new(
169        base_directory: PathBuf,
170        editor_directory: PathBuf,
171        custom_directory: PathBuf,
172        relative_directory: Option<BaseDirectory>,
173    ) -> Self {
174        Self {
175            base_directory,
176            editor_directory,
177            custom_directory,
178            relative_directory,
179        }
180    }
181
182    /// Creates a new instance of [`IconsDirectories`], by giving it the necessary [`PathBuf`] fields. It assumes the default as the base these folders are relative to, [`BaseDirectory::ProjectFolder`].
183    ///
184    /// # Parameters
185    ///
186    /// * `base_directory` - The path to the folder **relative** to `{relative_dir.as_str()}` where all the icons are stored. Defaults to the "addons" folder.
187    /// * `editor_directory` - The path to the folder **relative** to `{relative_dir.as_str()}{base_directory}` where all the editor icons are stored. Defaults to the "editor" folder inside addons.
188    /// * `custom_directory` - The path to the folder **relative** to `{relative_dir.as_str()}{base_directory}` where all the custom icons for this library are stored. Defaults to "", so the same as the base directory.
189    ///
190    /// # Returns
191    ///
192    /// The [`IconsDirectories`] instance with its fields initialized.
193    pub fn from_directories(
194        base_directory: PathBuf,
195        editor_directory: PathBuf,
196        custom_directory: PathBuf,
197    ) -> Self {
198        Self {
199            base_directory,
200            editor_directory,
201            custom_directory,
202            relative_directory: None,
203        }
204    }
205
206    /// Modifies the instance of [`IconsDirectories`], by giving it the necessary [`PathBuf`] fields.
207    ///
208    /// # Parameters
209    ///
210    /// * `base_directory` - The path to the folder **relative** to `{relative_dir.as_str()}` where all the icons are stored. Defaults to the "addons" folder.
211    /// * `editor_directory` - The path to the folder **relative** to `{relative_dir.as_str()}{base_directory}` where all the editor icons are stored. Defaults to the "editor" folder inside addons.
212    /// * `custom_directory` - The path to the folder **relative** to `{relative_dir.as_str()}{base_directory}` where all the custom icons for this library are stored. Defaults to "", so the same as the base directory.
213    ///
214    /// # Returns
215    ///
216    /// The [`IconsDirectories`] instance with its directories changed.
217    pub fn with_directories(
218        mut self,
219        base_directory: PathBuf,
220        editor_directory: PathBuf,
221        custom_directory: PathBuf,
222    ) -> Self {
223        self.base_directory = base_directory;
224        self.editor_directory = editor_directory;
225        self.custom_directory = custom_directory;
226        self
227    }
228
229    /// Modifies the instance of [`IconsDirectories`], by giving it the `base_directory` field.
230    ///
231    /// # Parameters
232    ///
233    /// * `base_directory` - The path to the folder **relative** to `{relative_dir.as_str()}` where all the icons are stored. Defaults to the "addons" folder.
234    pub fn with_base_directory(mut self, base_directory: PathBuf) -> Self {
235        self.base_directory = base_directory;
236        self
237    }
238
239    /// Modifies the instance of [`IconsDirectories`], by giving it the `editor_directory` field.
240    ///
241    /// # Parameters
242    ///
243    /// * `editor_directory` - The path to the folder **relative** to `{relative_dir.as_str()}{base_directory}` where all the editor icons are stored. Defaults to the "editor" folder inside addons.
244    pub fn with_editor_directory(mut self, editor_directory: PathBuf) -> Self {
245        self.editor_directory = editor_directory;
246        self
247    }
248
249    /// Modifies the instance of [`IconsDirectories`], by giving it the `custom_directory` field.
250    ///
251    /// # Parameters
252    ///
253    /// * `custom_directory` - The path to the folder **relative** to `{relative_dir.as_str()}{base_directory}` where all the custom icons for this library are stored. Defaults to "", so the same as the base directory.
254    pub fn with_custom_directory(mut self, custom_directory: PathBuf) -> Self {
255        self.custom_directory = custom_directory;
256        self
257    }
258
259    /// Modifies the instance of [`IconsDirectories`], by giving it the `relative_directory` field.
260    ///
261    /// # Parameters
262    ///
263    /// * `relative_directory` - The folder to use as a base for the base directory of icons.
264    pub fn with_relative_directory(mut self, relative_directory: BaseDirectory) -> Self {
265        self.relative_directory = Some(relative_directory);
266        self
267    }
268}
269
270/// The icon configuration for the `.gdextension` file generation.
271#[derive(Default, Debug)]
272pub struct IconsConfig {
273    /// The default icon to use when no specified icon was provided. Available with "find_icons" feature.
274    #[cfg(feature = "find_icons")]
275    pub default: DefaultNodeIcon,
276    /// The [`IconsCopyStrategy`] for the files needed for the icons to be displayed.
277    pub copy_strategy: IconsCopyStrategy,
278    /// The custom icons to use. It contains pairs of `ClassName: IconPath`, where IconPath is the path **relative** to the `custom_directory` specified in `directories`.
279    pub custom_icons: Option<HashMap<String, PathBuf>>,
280    /// The **relative** paths of the directories where the icons are stored.
281    pub directories: IconsDirectories,
282}
283
284impl IconsConfig {
285    /// Creates a new instance of [`IconsConfig`], by giving it all its fields.
286    ///
287    /// # Parameters
288    ///
289    /// * `default` - The default icon to use when no specified icon was provided. If none of the find_icons features are activated, it's not there, and `Godot`'s Node is assumed instead. Available with feature "find_icons".
290    /// * `copy_strategy` - The [`IconsCopyStrategy`] for the files needed for the icons to be displayed.
291    /// * `custom_icons` - The custom icons to use. It contains pairs of `ClassName: IconPath`, where IconPath is the path **relative** to the `custom_directory` specified in `directories`.
292    /// * `directories` - The **relative** paths of the directories where the icons are stored.
293    ///
294    /// # Returns
295    ///
296    /// The [`IconsConfig`] instancte with its fields initialized.
297    pub fn new(
298        #[cfg(feature = "find_icons")] default: DefaultNodeIcon,
299        copy_strategy: IconsCopyStrategy,
300        custom_icons: Option<HashMap<String, PathBuf>>,
301        directories: IconsDirectories,
302    ) -> Self {
303        Self {
304            #[cfg(feature = "find_icons")]
305            default,
306            copy_strategy,
307            custom_icons,
308            directories,
309        }
310    }
311}