From ed44b4b8c197eeb88e045a7b30565e53d9bdf2a4 Mon Sep 17 00:00:00 2001 From: Valentin Dosimont Date: Fri, 20 Dec 2024 18:10:07 +0100 Subject: [PATCH] feat: bindgen enums improvements --- crates/dojo/bindgen/src/plugins/mod.rs | 9 --- .../src/plugins/typescript/generator/enum.rs | 10 +--- .../plugins/typescript/generator/function.rs | 18 +++--- .../src/plugins/typescript/generator/mod.rs | 59 ++++++++----------- .../bindgen/src/plugins/typescript/writer.rs | 3 - 5 files changed, 36 insertions(+), 63 deletions(-) diff --git a/crates/dojo/bindgen/src/plugins/mod.rs b/crates/dojo/bindgen/src/plugins/mod.rs index 4470028a65..3b1b481482 100644 --- a/crates/dojo/bindgen/src/plugins/mod.rs +++ b/crates/dojo/bindgen/src/plugins/mod.rs @@ -74,15 +74,6 @@ impl Buffer { } } - /// Inserts string at the specified index. - /// - /// * `s` - The string to insert. - /// * `pos` - The position to insert the string at. - /// * `idx` - The index of the string to insert at. - pub fn insert_at_index(&mut self, s: String, idx: usize) { - self.0.insert(idx, s); - } - /// Finds position of the given string in the inner vec. /// /// * `pos` - The string to search for. diff --git a/crates/dojo/bindgen/src/plugins/typescript/generator/enum.rs b/crates/dojo/bindgen/src/plugins/typescript/generator/enum.rs index f017b9d870..b72df23295 100644 --- a/crates/dojo/bindgen/src/plugins/typescript/generator/enum.rs +++ b/crates/dojo/bindgen/src/plugins/typescript/generator/enum.rs @@ -6,10 +6,6 @@ use crate::error::BindgenResult; use crate::plugins::typescript::generator::JsPrimitiveType; use crate::plugins::{BindgenModelGenerator, Buffer}; -const CAIRO_ENUM_TYPE_IMPL: &str = "export type TypedCairoEnum = CairoCustomEnum & \ - {\n\tvariant: { [K in keyof T]: T[K] | undefined \ - };\n\tunwrap(): T[keyof T];\n}\n"; - pub(crate) struct TsEnumGenerator; impl TsEnumGenerator { @@ -24,10 +20,6 @@ impl TsEnumGenerator { buffer.insert_after(format!(" {CAIRO_ENUM_TOKEN}"), SN_IMPORT_SEARCH, "{", 1); } } - if !buffer.has(CAIRO_ENUM_TYPE_IMPL) { - let pos = buffer.pos(SN_IMPORT_SEARCH).unwrap(); - buffer.insert_at_index(CAIRO_ENUM_TYPE_IMPL.to_owned(), pos + 1); - } } } @@ -44,7 +36,7 @@ impl BindgenModelGenerator for TsEnumGenerator { export type {name} = {{ {variants} }} -export type {name}Enum = TypedCairoEnum<{name}>; +export type {name}Enum = CairoCustomEnum; ", path = token.type_path, name = token.type_name(), diff --git a/crates/dojo/bindgen/src/plugins/typescript/generator/function.rs b/crates/dojo/bindgen/src/plugins/typescript/generator/function.rs index 12e4f88fd5..28c9a6988a 100644 --- a/crates/dojo/bindgen/src/plugins/typescript/generator/function.rs +++ b/crates/dojo/bindgen/src/plugins/typescript/generator/function.rs @@ -3,7 +3,7 @@ use convert_case::{Case, Casing}; use dojo_world::contracts::naming; use super::constants::JS_BIGNUMBERISH; -use super::JsPrimitiveInputType; +use super::{token_is_custom_enum, JsPrimitiveInputType}; use crate::error::BindgenResult; use crate::plugins::{BindgenContractGenerator, Buffer}; use crate::DojoContract; @@ -16,8 +16,8 @@ impl TsFunctionGenerator { buffer.insert( 1, format!( - "import {{ Account, AccountInterface, {}, CairoOption, CairoCustomEnum, ByteArray }} \ - from \"starknet\";", + "import {{ Account, AccountInterface, {}, CairoOption, CairoCustomEnum, \ + ByteArray }} from \"starknet\";", JS_BIGNUMBERISH ), ); @@ -26,7 +26,7 @@ impl TsFunctionGenerator { } fn setup_function_wrapper_start(&self, buffer: &mut Buffer) -> usize { - let fn_wrapper = "export async function setupWorld(provider: DojoProvider) {\n"; + let fn_wrapper = "export function setupWorld(provider: DojoProvider) {\n"; if !buffer.has(fn_wrapper) { buffer.push(fn_wrapper.to_owned()); @@ -84,7 +84,6 @@ impl TsFunctionGenerator { } fn format_function_inputs(&self, token: &Function) -> String { - println!("{:#?}", token); let inputs = match token.state_mutability { StateMutability::External => vec!["snAccount: Account | AccountInterface".to_owned()], StateMutability::View => Vec::new(), @@ -95,10 +94,11 @@ impl TsFunctionGenerator { .fold(inputs, |mut acc, input| { let prefix = match &input.1 { Token::Composite(t) => { - if t.r#type == CompositeType::Enum - || (t.r#type == CompositeType::Struct - && !t.type_path.starts_with("core")) - || t.r#type == CompositeType::Unknown + if !token_is_custom_enum(t) + && (t.r#type == CompositeType::Enum + || (t.r#type == CompositeType::Struct + && !t.type_path.starts_with("core")) + || t.r#type == CompositeType::Unknown) { "models." } else { diff --git a/crates/dojo/bindgen/src/plugins/typescript/generator/mod.rs b/crates/dojo/bindgen/src/plugins/typescript/generator/mod.rs index 41895ca877..6e7dff6f67 100644 --- a/crates/dojo/bindgen/src/plugins/typescript/generator/mod.rs +++ b/crates/dojo/bindgen/src/plugins/typescript/generator/mod.rs @@ -1,4 +1,4 @@ -use cainome::parser::tokens::{Composite, CompositeType, Token}; +use cainome::parser::tokens::{Composite, CompositeInner, CompositeType, Token}; use constants::{ CAIRO_BOOL, CAIRO_BYTE_ARRAY, CAIRO_CONTRACT_ADDRESS, CAIRO_FELT252, CAIRO_I128, CAIRO_OPTION, CAIRO_OPTION_DEFAULT_VALUE, CAIRO_U128, CAIRO_U16, CAIRO_U256, CAIRO_U256_STRUCT, CAIRO_U32, @@ -37,21 +37,7 @@ pub(crate) fn generate_type_init(token: &Composite) -> String { token .inners .iter() - .map(|i| { - match i.token.to_composite() { - Ok(c) => { - format!("\t\t\t{}: {},", i.name, JsPrimitiveDefaultValue::from(c)) - } - Err(_) => { - // this will fail on core types as - // `core::starknet::contract_address::ContractAddress` - // `core::felt252` - // `core::integer::u64` - // and so son - format!("\t\t\t{}: {},", i.name, JsPrimitiveDefaultValue::from(&i.token)) - } - } - }) + .map(build_composite_inner_primitive_default_value) .collect::>() .join("\n") ) @@ -214,8 +200,8 @@ impl From<&Token> for JsPrimitiveInputType { ); } if token_is_custom_enum(c) { - // we defined a type wrapper with Enum suffix let's use it there - return JsPrimitiveInputType::from(format!("{}Enum", c.type_name()).as_str()); + // Use CairoCustomEnum type from starknetjs + return JsPrimitiveInputType::from("CairoCustomEnum"); } return JsPrimitiveInputType::from(value.type_name().as_str()); } @@ -274,24 +260,31 @@ impl From<&Composite> for JsPrimitiveDefaultValue { /// * token - The enum token to build the default value for fn build_default_enum_variant(token: &Composite) -> String { let default_value = token.inners.iter().take(1).fold(String::new(), |_acc, i| { - format!( - "\n\t\t\t\t{}: {}", - i.name, - match &i.token { - Token::CoreBasic(core_basic) => - JsPrimitiveDefaultValue::from(core_basic.type_name().as_str()).0, - Token::Array(_) => "[]".to_owned(), - Token::Tuple(_) => "()".to_owned(), - Token::Composite(composite) => generate_type_init(composite), - _ => "".to_string(), - } - ) + format!("\n\t\t{}", build_composite_inner_primitive_default_value(i)) }); let undefined = token.inners.iter().skip(1).fold(String::new(), |acc, i| { format!("{acc}\n\t\t\t\t{}: undefined,", i.name.to_case(Case::Camel)) }); - default_value + "," + &undefined + default_value + &undefined +} + +/// Builds JsPrimitiveDefaultValue from CompositeInne token +/// * inner - CompositeInner +fn build_composite_inner_primitive_default_value(inner: &CompositeInner) -> String { + match inner.token.to_composite() { + Ok(c) => { + format!("\t\t{}: {},", inner.name, JsPrimitiveDefaultValue::from(c)) + } + Err(_) => { + // this will fail on core types as + // `core::starknet::contract_address::ContractAddress` + // `core::felt252` + // `core::integer::u64` + // and so son + format!("\t\t\t{}: {},", inner.name, JsPrimitiveDefaultValue::from(&inner.token)) + } + } } /// Builds the default value for an enum variant @@ -595,8 +588,8 @@ mod tests { #[test] fn test_cairo_custom_enum_default_value() { assert_eq!( - "new CairoCustomEnum({ \n\t\t\t\titem: {\n\t\t\tfieldOrder: ['id', 'xp'],\n\t\t\tid: \ - 0,\n\t\t\txp: 0,\n\t\t},\n\t\t\t\taddress: undefined, })", + "new CairoCustomEnum({ \n\t\t\t\titem: { fieldOrder: ['id', 'xp'], id: 0, xp: 0, \ + },\n\t\t\t\taddress: undefined, })", JsPrimitiveDefaultValue::from(&Token::Composite(Composite { type_path: "dojo_starter::Direction".to_owned(), inners: vec![ diff --git a/crates/dojo/bindgen/src/plugins/typescript/writer.rs b/crates/dojo/bindgen/src/plugins/typescript/writer.rs index ec9a4fd1b2..b97febcadc 100644 --- a/crates/dojo/bindgen/src/plugins/typescript/writer.rs +++ b/crates/dojo/bindgen/src/plugins/typescript/writer.rs @@ -53,9 +53,6 @@ impl BindgenWriter for TsFileWriter { .iter() .fold(Buffer::new(), |mut acc, g| { composites.iter().for_each(|c| { - // println!("Generating code for model {}", c.type_path); - // println!("{:#?}", c); - // println!("====================="); match g.generate(c, &mut acc) { Ok(code) => { if !code.is_empty() {