gauntlet/rust/client/build.rs
Exidex d8f2ebcaea
Some checks failed
format / rust (push) Failing after 2s
format / nix (push) Failing after 1s
nix build / all (push) Failing after 3s
build / build-linux (push) Has been cancelled
build / build-macos (push) Has been cancelled
build / build-windows (push) Has been cancelled
not gonna comback to this
2025-10-02 18:54:36 +02:00

171 lines
7.4 KiB
Rust

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use convert_case::Case;
use convert_case::Casing;
use gauntlet_component_model::Component;
use gauntlet_component_model::ComponentName;
use gauntlet_component_model::OptionalKind;
use gauntlet_component_model::Property;
use gauntlet_component_model::PropertyType;
use gauntlet_component_model::create_component_model;
fn main() -> anyhow::Result<()> {
#[cfg(target_os = "macos")]
println!(
"cargo:rustc-link-search=framework={}",
"/System/Library/PrivateFrameworks"
);
let out_dir = env::var("OUT_DIR")?;
let dest_path = Path::new(&out_dir).join("components.rs");
let mut output = String::new();
let components = create_component_model();
for component in &components {
match component {
Component::Standard { name, props, .. } => {
for prop in props {
let PropertyType::Function { arguments } = &prop.property_type else {
continue;
};
output.push_str(&format!(
"fn create_{}_{}_event(\n",
name.to_string().to_case(Case::Snake),
prop.name.to_case(Case::Snake)
));
output.push_str(" widget_id: UiWidgetId,\n");
for arg in arguments {
output.push_str(&" #[allow(non_snake_case)]\n".to_string());
output.push_str(&format!(" {}: {}\n", arg.name, generate_type(&arg, name)));
}
output.push_str(") -> crate::model::UiViewEvent {\n");
output.push_str(" crate::model::UiViewEvent::View {\n");
output.push_str(" widget_id,\n");
output.push_str(&format!(" event_name: \"{}\".to_owned(),\n", prop.name));
output.push_str(" event_arguments: vec![\n");
for arg in arguments {
match arg.property_type {
PropertyType::String => {
match arg.optional {
OptionalKind::No => {
output.push_str(&format!(
" gauntlet_common::model::UiPropertyValue::String({}),\n",
arg.name
));
}
OptionalKind::Yes => {
output.push_str(&format!(" {}.map(|#[allow(non_snake_case)] {}| gauntlet_common::model::UiPropertyValue::String({})).unwrap_or_else(|| gauntlet_common::model::UiPropertyValue::Null),\n", arg.name, arg.name, arg.name));
}
OptionalKind::YesButComplicated => {
todo!()
}
}
}
PropertyType::Number => {
match arg.optional {
OptionalKind::No => {
output.push_str(&format!(
" gauntlet_common::model::UiPropertyValue::Number({}),\n",
arg.name
));
}
OptionalKind::Yes => {
output.push_str(&format!(" {}.map(|{}| gauntlet_common::model::UiPropertyValue::Number({})).unwrap_or_else(|| gauntlet_common::model::UiPropertyValue::Null),\n", arg.name, arg.name, arg.name));
}
OptionalKind::YesButComplicated => {
todo!()
}
}
}
PropertyType::Boolean => {
match arg.optional {
OptionalKind::No => {
output.push_str(&format!(
" gauntlet_common::model::UiPropertyValue::Bool({}),\n",
arg.name
));
}
OptionalKind::Yes => {
output.push_str(&format!(" {}.map(|{}| gauntlet_common::model::UiPropertyValue::Bool({})).unwrap_or_else(|| gauntlet_common::model::UiPropertyValue::Null),\n", arg.name, arg.name, arg.name));
}
OptionalKind::YesButComplicated => {
todo!()
}
}
}
_ => {
panic!("not yet supported")
}
}
}
output.push_str(" ]\n");
output.push_str(" }\n");
output.push_str("}\n");
output.push_str("\n");
}
}
_ => {}
}
}
generate_file(&dest_path, &output)?;
Ok(())
}
fn generate_file<P: AsRef<Path>>(path: P, text: &str) -> std::io::Result<()> {
let mut f = File::create(path)?;
f.write_all(text.as_bytes())
}
fn generate_type(property: &Property, name: &ComponentName) -> String {
match property.optional {
OptionalKind::No => {
generate_required_type(
&property.property_type,
Some(format!("{}{}", name, &property.name.to_case(Case::Pascal))),
)
}
OptionalKind::Yes => {
generate_optional_type(
&property.property_type,
format!("{}{}", name, &property.name.to_case(Case::Pascal)),
)
}
OptionalKind::YesButComplicated => {
todo!()
}
}
}
fn generate_optional_type(property_type: &PropertyType, union_name: String) -> String {
format!("Option<{}>", generate_required_type(property_type, Some(union_name)))
}
fn generate_required_type(property_type: &PropertyType, union_name: Option<String>) -> String {
match property_type {
PropertyType::String => "String".to_owned(),
PropertyType::Number => "f64".to_owned(),
PropertyType::Boolean => "bool".to_owned(),
PropertyType::Function { .. } => panic!("client doesn't know about functions in properties"),
PropertyType::Component { reference } => format!("{}Widget", reference.component_name.to_string()),
PropertyType::SharedTypeRef { name } => name.to_owned(),
PropertyType::Union { .. } => {
match union_name {
None => panic!("should not be used"),
Some(union_name) => union_name,
}
}
PropertyType::Array { item } => format!("Vec<{}>", generate_required_type(item, union_name)),
}
}