mirror of
https://github.com/project-gauntlet/gauntlet.git
synced 2025-12-23 10:35:53 +00:00
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
171 lines
7.4 KiB
Rust
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)),
|
|
}
|
|
}
|