devalang_core/core/builder/
mod.rs

1use crate::core::audio::engine::render_audio_with_modules;
2use crate::core::parser::statement::Statement;
3use crate::core::store::global::GlobalStore;
4use devalang_utils::logger::Logger;
5use std::io::Write;
6use std::{collections::HashMap, fs::create_dir_all};
7
8pub struct Builder {}
9
10impl Default for Builder {
11    fn default() -> Self {
12        Self::new()
13    }
14}
15
16impl Builder {
17    pub fn new() -> Self {
18        Builder {}
19    }
20
21    pub fn build_ast(
22        &self,
23        modules: &HashMap<String, Vec<Statement>>,
24        out_dir: &str,
25        compress: bool,
26    ) {
27        for (name, statements) in modules {
28            let formatted_name = name.split("/").last().unwrap_or(name);
29            let formatted_name = formatted_name.replace(".deva", "");
30
31            create_dir_all(format!("{}/ast", out_dir)).expect("Failed to create AST directory");
32
33            let file_path = format!("{}/ast/{}.json", out_dir, formatted_name);
34            let mut file = std::fs::File::create(file_path).expect("Failed to create AST file");
35            let content = if compress {
36                serde_json::to_string(&statements).expect("Failed to serialize AST")
37            } else {
38                serde_json::to_string_pretty(&statements).expect("Failed to serialize AST")
39            };
40
41            file.write_all(content.as_bytes())
42                .expect("Failed to write AST to file");
43        }
44    }
45
46    pub fn build_audio(
47        &self,
48        modules: &HashMap<String, Vec<Statement>>,
49        normalized_output_dir: &str,
50        global_store: &mut GlobalStore,
51        audio_format: Option<String>,
52        sample_rate: Option<u32>,
53    ) {
54        let logger = Logger::new();
55
56        let audio_engines =
57            render_audio_with_modules(modules.clone(), normalized_output_dir, global_store);
58
59        create_dir_all(format!("{}/audio", normalized_output_dir))
60            .expect("Failed to create audio directory");
61
62        for (module_name, mut audio_engine) in audio_engines {
63            let formatted_module_name = module_name
64                .split('/')
65                .next_back()
66                .unwrap_or(&module_name)
67                .replace(".deva", "");
68
69            let output_path = format!(
70                "{}/audio/{}.wav",
71                normalized_output_dir, formatted_module_name
72            );
73
74            match audio_engine.generate_wav_file(&output_path, audio_format.clone(), sample_rate) {
75                Ok(_) => {}
76                Err(msg) => {
77                    logger.log_error_with_stacktrace(
78                        &format!(
79                            "Unable to generate WAV file for module '{}': {}",
80                            formatted_module_name, msg
81                        ),
82                        &module_name,
83                    );
84                }
85            }
86        }
87    }
88
89    pub fn build_midi(
90        &self,
91        modules: &HashMap<String, Vec<Statement>>,
92        normalized_output_dir: &str,
93        global_store: &mut GlobalStore,
94    ) {
95        let logger = Logger::new();
96
97        let audio_engines =
98            render_audio_with_modules(modules.clone(), normalized_output_dir, global_store);
99
100        create_dir_all(format!("{}/midi", normalized_output_dir))
101            .expect("Failed to create MIDI directory");
102
103        for (module_name, mut audio_engine) in audio_engines {
104            let formatted_module_name = module_name
105                .split('/')
106                .next_back()
107                .unwrap_or(&module_name)
108                .replace(".deva", "");
109
110            let output_path = format!(
111                "{}/midi/{}.mid",
112                normalized_output_dir, formatted_module_name
113            );
114
115            match audio_engine.generate_midi_file(&output_path, None, None) {
116                Ok(_) => {}
117                Err(msg) => {
118                    logger.log_error_with_stacktrace(
119                        &format!(
120                            "Unable to generate MIDI file for module '{}': {}",
121                            formatted_module_name, msg
122                        ),
123                        &module_name,
124                    );
125                }
126            }
127        }
128    }
129}