use specta::ts::{export, BigIntExportBehavior, ExportConfiguration}; fn header(struct_path: &str) -> String { format!("// File generated by specta. Do not edit!\n//\n/// lib/{struct_path}\n\n") } struct TypescriptBinding { output_path: std::path::PathBuf, } impl TypescriptBinding { fn new(output_path: std::path::PathBuf) -> Self { Self { output_path } } fn write(&self, struct_path: &str, bindings_filename: &str, imports: Option, x: &str) { match std::fs::write( self.output_path .join(bindings_filename) .as_os_str() .to_str() .unwrap_or_default(), format!( "{}\n{}\n{}", header(struct_path), imports.unwrap_or_default(), &x ), ) { Err(e) => { eprintln!("{e:?}"); eprintln!("Failed to write bindings for {struct_path} to {bindings_filename}"); } Ok(()) => { println!("Wrote bindings for {struct_path} to {bindings_filename}"); } } } } #[test] #[allow(clippy::too_many_lines)] fn generate_ts_bindings() { // get our current working directory let cwd = std::env::current_dir().unwrap(); // set lib/bindings/AllBindings.d.ts as the output file let output_dir = cwd.join("bindings"); // make sure output dir exists std::fs::create_dir_all(&output_dir).unwrap(); eprintln!("Output dir: {:?}", &output_dir); let ts_bindings = TypescriptBinding::new(output_dir); let config = ExportConfiguration::default() .export_by_default(Some(true)) .bigint(BigIntExportBehavior::String); let bindings: Vec = vec![ match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export biome::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export creature::Creature"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export creature::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export creature_caste::Gait"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export creature_caste::GaitType"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export creature_caste::GaitModifier"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export creature_caste::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export creature_caste::Caste"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export creature_effect::PropertyToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export creature_effect::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export creature_variation::CreatureVariation"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export creature_variation::Rule"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export creature_variation::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export entity::Entity"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export entity::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export graphics::Graphic"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export graphics::SpriteGraphic"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export graphics::SpriteLayer"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export graphics::TilePage"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export graphics::ColorModificationToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export graphics::ConditionToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export graphics::GraphicTypeToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export graphics::GrowthToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export graphics::PlantGraphicTemplateToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export graphics::TilePageToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export inorganic::Inorganic"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export inorganic::EnvironmentClassToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export inorganic::InclusionTypeToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export inorganic::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export material::Material"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export material::FuelTypeToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export material::PropertyToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export material::StateToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export material::TypeToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export material::UsageToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export material_template::MaterialTemplate"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export plant::Plant"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export plant::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export plant_growth::PlantGrowth"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export plant_growth::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export plant_growth::TypeTokenn"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export plant_growth::PlantPartToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export position::Position"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export position::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export seed_material::SeedMaterial"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export select_creature::SelectCreature"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export select_creature::SelectRules"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export shrub::Shru"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export shrub::SeasonToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export shrub::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export syndrome::Syndrome"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export syndrome::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export tree::Tree"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export tree::Token"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export tree::TwigPlacementToken"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export unprocessed_raw::UnprocessedRaw"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export unprocessed_raw::Modification"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::MaterialMechanics"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::RawMetadata"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::ModuleInfoFile"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::SteamData"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::StateName"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::MechanicalProperties"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::Name"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::SingPlurName"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::ObjectType"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::RawModuleLocation"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::BodySize"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::Color"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::Milkable"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::Temperatures"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::Tile"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::graphics::Dimensions"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::graphics::CustomGraphicExtension"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::graphics::CustomGraphicExtension"); eprintln!("{e:?}"); String::new() } }, ]; let missed = bindings.iter().filter(|x| x.is_empty()).collect::>(); // change missed into the number of missed bindings let missed = missed.len(); // if there are missed bindings, print a warning if missed > 0 { eprintln!("Missed {missed} bindings"); } // write the bindings to the output file ts_bindings.write( "dfraw_json_parser library", "DFRawJson.d.ts", None, &bindings.join("\n\n"), ); } #[cfg(feature = "tauri")] #[test] fn export_tauri_ts_bindings() { // get our current working directory let cwd = std::env::current_dir().unwrap(); // set lib/bindings/AllBindings.d.ts as the output file let output_dir = cwd.join("bindings"); // make sure output dir exists std::fs::create_dir_all(&output_dir).unwrap(); eprintln!("Output dir: {:?}", &output_dir); let ts_bindings = TypescriptBinding::new(output_dir); let config = ExportConfiguration::default() .export_by_default(Some(true)) .bigint(BigIntExportBehavior::String); let bindings: Vec = vec![ match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export progress::details::ProgressDetails"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export progress::tasks::ProgressTask"); eprintln!("{e:?}"); String::new() } }, match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export progress::payload::ProgressPayload"); eprintln!("{e:?}"); String::new() } }, // add the needed type RawModuleLocation match export::(&config) { Ok(x) => x, Err(e) => { eprintln!("Failed to export parser::RawModuleLocation"); eprintln!("{e:?}"); String::new() } }, ]; let missed = bindings.iter().filter(|x| x.is_empty()).collect::>(); // change missed into the number of missed bindings let missed = missed.len(); // if there are missed bindings, print a warning if missed > 0 { eprintln!("Missed {missed} bindings"); } // write the bindings to the output file ts_bindings.write( "tauri_lib library", "DFRawJson-Tauri.d.ts", None, &bindings.join("\n\n"), ); }