From a0b52516490ab99f642cc217b2773e0ff945d03f Mon Sep 17 00:00:00 2001 From: glihm Date: Mon, 15 Jan 2024 22:03:19 -0600 Subject: [PATCH] feat: identify systems and use new cainome tokenized abi --- Cargo.lock | 45 +++++++++++++++++++++++++----- crates/dojo-bindgen/Cargo.toml | 2 +- crates/dojo-bindgen/src/lib.rs | 50 ++++++++++++++++++++++++---------- 3 files changed, 74 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a294c32aeb..cfe3de6b2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1111,10 +1111,25 @@ checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" [[package]] name = "cainome" version = "0.1.5" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.1.10#3f98ae4b8239bb976ab434b438775bcd3db5207a" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.1#decf850b8979f4fbcf9d89f8d605ee260c23954b" dependencies = [ - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.1.10)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.1.10)", + "anyhow", + "async-trait", + "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.1)", + "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.1)", + "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.1)", + "camino", + "clap", + "clap_complete", + "convert_case 0.6.0", + "serde", + "serde_json", + "starknet", + "thiserror", + "tokio", + "tracing", + "tracing-subscriber", + "url", ] [[package]] @@ -1124,13 +1139,13 @@ source = "git+https://github.com/cartridge-gg/cainome?rev=950e487#950e4871b735a1 dependencies = [ "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=950e487)", "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=950e487)", - "cainome-rs", + "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=950e487)", ] [[package]] name = "cainome-cairo-serde" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.1.10#3f98ae4b8239bb976ab434b438775bcd3db5207a" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.1#decf850b8979f4fbcf9d89f8d605ee260c23954b" dependencies = [ "starknet", "thiserror", @@ -1148,7 +1163,7 @@ dependencies = [ [[package]] name = "cainome-parser" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.1.10#3f98ae4b8239bb976ab434b438775bcd3db5207a" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.1#decf850b8979f4fbcf9d89f8d605ee260c23954b" dependencies = [ "quote", "serde_json", @@ -1169,6 +1184,22 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cainome-rs" +version = "0.1.0" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.1#decf850b8979f4fbcf9d89f8d605ee260c23954b" +dependencies = [ + "anyhow", + "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.1)", + "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.1)", + "proc-macro2", + "quote", + "serde_json", + "starknet", + "syn 2.0.41", + "thiserror", +] + [[package]] name = "cainome-rs" version = "0.1.0" @@ -2694,7 +2725,7 @@ name = "dojo-bindgen" version = "0.5.0" dependencies = [ "async-trait", - "cainome 0.1.5 (git+https://github.com/cartridge-gg/cainome?tag=v0.1.10)", + "cainome 0.1.5 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.1)", "camino", "convert_case 0.6.0", "serde", diff --git a/crates/dojo-bindgen/Cargo.toml b/crates/dojo-bindgen/Cargo.toml index 90f46283a6..ad3071dfde 100644 --- a/crates/dojo-bindgen/Cargo.toml +++ b/crates/dojo-bindgen/Cargo.toml @@ -15,4 +15,4 @@ serde.workspace = true serde_json.workspace = true thiserror.workspace = true -cainome = { git = "https://github.com/cartridge-gg/cainome", tag = "v0.1.10" } +cainome = { git = "https://github.com/cartridge-gg/cainome", tag = "v0.2.1" } diff --git a/crates/dojo-bindgen/src/lib.rs b/crates/dojo-bindgen/src/lib.rs index 79950a3256..5053e71519 100644 --- a/crates/dojo-bindgen/src/lib.rs +++ b/crates/dojo-bindgen/src/lib.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::fs; use cainome::parser::tokens::Token; -use cainome::parser::AbiParser; +use cainome::parser::{AbiParser, TokenizedAbi}; use camino::Utf8PathBuf; use convert_case::{Case, Casing}; @@ -17,20 +17,31 @@ pub use plugins::BuiltinPlugins; #[derive(Debug, PartialEq)] pub struct DojoModel { + /// PascalCase name of the model. pub name: String, + /// Fully qualified path of the model type in cairo code. pub qualified_path: String, - pub tokens: HashMap>, + /// List of tokens found in the model contract ABI. + /// Only structs and enums are currently used. + pub tokens: TokenizedAbi, } #[derive(Debug, PartialEq)] pub struct DojoContract { + /// Contract's name. pub contract_file_name: String, - pub tokens: HashMap>, + /// Full ABI of the contract in case the plugin wants to make extra checks, + /// or generated other functions than the systems. + pub tokens: TokenizedAbi, + /// Functions that are identified as systems. + pub systems: Vec, } #[derive(Debug)] pub struct DojoData { + /// All contracts found in the project. pub contracts: HashMap, + /// All the models contracts found in the project. pub models: HashMap, } @@ -92,11 +103,26 @@ fn gather_dojo_data(artifacts_path: &Utf8PathBuf) -> BindgenResult { { // Contract. if is_systems_contract(file_name, &file_content) { + // Identify the systems -> for now only take the functions from the + // interfaces. + let mut systems = vec![]; + let interface_blacklist = [ + "dojo::world::IWorldProvider", + "dojo::components::upgradeable::IUpgradeable", + ]; + + for (interface, funcs) in &tokens.interfaces { + if !interface_blacklist.contains(&interface.as_str()) { + systems.extend(funcs.clone()); + } + } + contracts.insert( file_name.to_string(), DojoContract { contract_file_name: file_name.to_string(), tokens: tokens.clone(), + systems, }, ); } @@ -151,7 +177,7 @@ fn is_systems_contract(file_name: &str, file_content: &str) -> bool { /// Filters the model ABI to keep relevant types /// to be generated for bindings. -fn filter_model_tokens(tokens: &HashMap>) -> HashMap> { +fn filter_model_tokens(tokens: &TokenizedAbi) -> TokenizedAbi { let mut structs = vec![]; let mut enums = vec![]; @@ -171,25 +197,19 @@ fn filter_model_tokens(tokens: &HashMap>) -> HashMap Option { /// /// * `file_name` - Name of the contract file. /// * `file_content` - Content of the contract artifact. -fn is_model_contract(tokens: &HashMap>) -> bool { +fn is_model_contract(tokens: &TokenizedAbi) -> bool { let expected_funcs = ["name", "layout", "packed_size", "unpacked_size", "schema"]; let mut funcs_counts = 0; // This hashmap is not that good at devex level.. one must check the // code to know the keys. - for f in &tokens["functions"] { + for f in &tokens.functions { if expected_funcs.contains(&f.to_function().expect("Function expected").name.as_str()) { funcs_counts += 1; }