rngpui_craby_codegen/
codegen.rs1use std::{fs, path::PathBuf};
2
3use rngpui_craby_common::{constants::SPEC_FILE_PREFIX, utils::fs::collect_files};
4use log::debug;
5
6use crate::{
7 parser::{
8 native_spec_parser::try_parse_schema,
9 types::ParseError,
10 utils::{render_report, RenderReportOptions},
11 },
12 types::Schema,
13};
14
15pub struct CodegenOptions<'a> {
16 pub project_root: &'a PathBuf,
17 pub source_dir: &'a PathBuf,
18}
19
20pub fn codegen<'a>(opts: CodegenOptions<'a>) -> Result<Vec<Schema>, anyhow::Error> {
21 let srcs = collect_files(opts.source_dir, &|path: &PathBuf| {
22 path.extension().unwrap_or_default() == "ts"
23 && path
24 .file_name()
25 .unwrap()
26 .to_string_lossy()
27 .starts_with(SPEC_FILE_PREFIX)
28 })?;
29 debug!("{} source file(s) found", srcs.len());
30
31 if srcs.is_empty() {
32 anyhow::bail!("No native module specification files found.");
33 }
34
35 let collected_schemas = srcs
36 .iter()
37 .map(|path| {
38 let src = fs::read_to_string(path)?;
39 let src = src.as_str();
40
41 match try_parse_schema(src) {
42 Ok(schemas) => Ok(schemas),
43 Err(ParseError::Oxc { diagnostics }) => {
44 render_report(
45 diagnostics,
46 RenderReportOptions {
47 project_root: opts.project_root,
48 path,
49 src,
50 },
51 );
52 anyhow::bail!("Failed to parse schema");
53 }
54 Err(ParseError::General(e)) => {
55 anyhow::bail!(e);
56 }
57 }
58 })
59 .collect::<Result<Vec<Vec<Schema>>, anyhow::Error>>()?;
60
61 let mut schemas = collected_schemas.into_iter().flatten().collect::<Vec<_>>();
62 schemas.sort_by_key(|v| v.module_name.to_lowercase());
63
64 debug!("Collected schemas: {:?}", schemas);
65
66 Ok(schemas)
67}