use fs_err as fs;
use regex::Regex;
use spacetimedb_codegen::{csharp, generate};
use spacetimedb_lib::{RawModuleDef, RawModuleDefV8};
use spacetimedb_schema::def::ModuleDef;
use std::path::Path;
use std::sync::OnceLock;
macro_rules! regex_replace {
($value:expr, $re:expr, $replace:expr) => {{
static RE: OnceLock<Regex> = OnceLock::new();
RE.get_or_init(|| Regex::new($re).unwrap())
.replace_all($value, $replace)
}};
}
fn main() -> anyhow::Result<()> {
let module = RawModuleDefV8::with_builder(|module| {
module.add_type::<RawModuleDef>();
});
let dir = &Path::new(concat!(
env!("CARGO_MANIFEST_DIR"),
"/../bindings-csharp/Runtime/Internal/Autogen"
))
.canonicalize()?;
fs::remove_dir_all(dir)?;
fs::create_dir(dir)?;
let module: ModuleDef = module.try_into()?;
generate(
&module,
&csharp::Csharp {
namespace: "SpacetimeDB.Internal",
},
)
.into_iter()
.try_for_each(|(filename, code)| {
let Some(filename) = filename.strip_prefix("Types/") else {
return Ok(());
};
if filename == "AlgebraicType.g.cs" || filename.starts_with("SumType") || filename.starts_with("ProductType") {
return Ok(());
}
let code = regex_replace!(&code, r"\bAlgebraicType\b", "SpacetimeDB.BSATN.$0");
let code = regex_replace!(
&code,
r"\b(ProductTypeElement|SumTypeVariant)\b",
"SpacetimeDB.BSATN.AggregateElement"
);
let code = regex_replace!(
&code,
r"\b(Product|Sum)Type\b",
"List<SpacetimeDB.BSATN.AggregateElement>"
);
fs::write(dir.join(filename), code.as_ref())
})?;
Ok(())
}