trixy/macros/config/file_tree/mod.rs
1/*
2* Copyright (C) 2023 - 2024:
3* The Trinitrix Project <soispha@vhack.eu, antifallobst@systemausfall.org>
4* SPDX-License-Identifier: GPL-3.0-or-later
5*
6* This file is part of the Trixy crate for Trinitrix.
7*
8* Trixy is free software: you can redistribute it and/or modify
9* it under the terms of the GNU General Public License as
10* published by the Free Software Foundation, either version 3 of
11* the License, or (at your option) any later version.
12*
13* This program is distributed in the hope that it will be useful,
14* but WITHOUT ANY WARRANTY; without even the implied warranty of
15* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16* GNU General Public License for more details.
17*
18* You should have received a copy of the GNU General Public License
19* and the GNU General Public License along with this program.
20* If not, see <https://www.gnu.org/licenses/>.
21*/
22
23//! [`FileTree`]s are the fundamental data structure used by trixy to present generated data to
24//! you.
25
26use std::{
27 fs, io,
28 path::{Path, PathBuf},
29};
30
31use super::trixy::Language;
32
33pub mod markdown_representation;
34
35/// A file tree containing all files that were generated. These are separated into host and
36/// auxiliary files. See their respective descriptions about what differentiates them.
37#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
38pub struct FileTree {
39 /// Files, that are supposed to be included in the compiled crate.
40 pub host_files: Vec<GeneratedFile>,
41
42 /// Files, that should be shared with the consumer (e. g. c headers).
43 pub auxiliary_files: Vec<GeneratedFile>,
44}
45
46/// A generated files
47#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
48pub struct GeneratedFile {
49 /// The path this generated file would like to be placed at.
50 /// This path is relative to the crate root.
51 pub path: PathBuf,
52
53 /// The content of this file.
54 ///
55 /// This should already be formatted and ready to be used.
56 pub value: String,
57
58 /// The language this file is written in.
59 ///
60 /// # Note
61 /// This can also be a associated language,
62 /// like having this set to [`Language::C`] for a c header file.
63 pub language: Language,
64}
65
66impl GeneratedFile {
67 pub fn new(path: PathBuf, value: String, language: Language) -> Self {
68 Self {
69 path,
70 value,
71 language,
72 }
73 }
74 pub fn new_in_out_dir(name: String, value: String, language: Language, out_dir: &Path) -> Self {
75 let path = out_dir.join(name);
76 Self {
77 path,
78 value,
79 language,
80 }
81 }
82
83 pub fn materialize(self) -> io::Result<()> {
84 fs::create_dir_all(self.path.parent().expect("This path should have a parent"))?;
85 fs::write(self.path, self.value.as_bytes())?;
86 Ok(())
87 }
88}
89
90impl FileTree {
91 pub fn new() -> Self {
92 Self::default()
93 }
94
95 pub fn add_host_file(&mut self, file: GeneratedFile) {
96 self.host_files.push(file)
97 }
98
99 pub fn add_auxiliary_file(&mut self, file: GeneratedFile) {
100 self.auxiliary_files.push(file)
101 }
102
103 pub fn extend_host(&mut self, files: Vec<GeneratedFile>) {
104 files.into_iter().for_each(|file| self.add_host_file(file));
105 }
106
107 pub fn extend_auxiliary(&mut self, files: Vec<GeneratedFile>) {
108 files
109 .into_iter()
110 .for_each(|file| self.add_auxiliary_file(file));
111 }
112
113 pub fn materialize(self) -> io::Result<()> {
114 self.host_files
115 .into_iter()
116 .map(|file| -> io::Result<()> { file.materialize() })
117 .collect::<io::Result<()>>()?;
118 self.auxiliary_files
119 .into_iter()
120 .map(|file| -> io::Result<()> { file.materialize() })
121 .collect::<io::Result<()>>()?;
122 Ok(())
123 }
124}