rngpui_craby_codegen/
codegen.rs

1use 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}