Skip to content

Commit

Permalink
feat: change enum to CairoCustomEnum (#2907)
Browse files Browse the repository at this point in the history
  • Loading branch information
MartianGreed authored Jan 14, 2025
1 parent fde72d7 commit a295c22
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub const CAIRO_U256_STRUCT: &str = "U256";
pub const CAIRO_I128: &str = "i128";
pub const CAIRO_BOOL: &str = "bool";
pub const CAIRO_OPTION: &str = "Option";
pub const CAIRO_UNIT_TYPE: &str = "()";

pub(crate) const CAIRO_OPTION_DEFAULT_VALUE: &str = "new CairoOption(CairoOptionVariant.None)";

Expand Down
63 changes: 24 additions & 39 deletions crates/dojo/bindgen/src/plugins/typescript/generator/enum.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use cainome::parser::tokens::{Composite, CompositeType};

use super::constants::{CAIRO_ENUM_IMPORT, CAIRO_ENUM_TOKEN, SN_IMPORT_SEARCH};
use super::token_is_custom_enum;
use super::token_is_enum;
use crate::error::BindgenResult;
use crate::plugins::typescript::generator::JsPrimitiveType;
use crate::plugins::{BindgenModelGenerator, Buffer};
Expand All @@ -12,7 +12,7 @@ impl TsEnumGenerator {
fn check_import(&self, token: &Composite, buffer: &mut Buffer) {
// type is Enum with type variants, need to import CairoEnum
// if enum has at least one inner that is a composite type
if token_is_custom_enum(token) {
if token_is_enum(token) {
if !buffer.has(SN_IMPORT_SEARCH) {
buffer.push(CAIRO_ENUM_IMPORT.to_owned());
} else if !buffer.has(CAIRO_ENUM_TOKEN) {
Expand All @@ -29,43 +29,25 @@ impl BindgenModelGenerator for TsEnumGenerator {
return Ok(String::new());
}

let gen = if token_is_custom_enum(token) {
self.check_import(token, buffer);
format!(
"// Type definition for `{path}` enum
self.check_import(token, buffer);
let gen = format!(
"// Type definition for `{path}` enum
export type {name} = {{
{variants}
}}
export type {name}Enum = CairoCustomEnum;
",
path = token.type_path,
name = token.type_name(),
variants = token
.inners
.iter()
.map(|inner| {
format!("\t{}: {};", inner.name, JsPrimitiveType::from(&inner.token))
})
.collect::<Vec<String>>()
.join("\n")
)
} else {
format!(
"// Type definition for `{path}` enum
export enum {name} {{
{variants}
}}
",
path = token.type_path,
name = token.type_name(),
variants = token
.inners
.iter()
.map(|inner| format!("\t{},", inner.name))
.collect::<Vec<String>>()
.join("\n")
)
};
path = token.type_path,
name = token.type_name(),
variants = token
.inners
.iter()
.map(|inner| {
format!("\t{}: {};", inner.name, JsPrimitiveType::from(&inner.token))
})
.collect::<Vec<String>>()
.join("\n")
);

if buffer.has(&gen) {
return Ok(String::new());
Expand Down Expand Up @@ -125,8 +107,9 @@ mod tests {

assert_eq!(
result,
"// Type definition for `core::test::AvailableTheme` enum\nexport enum AvailableTheme \
{\n\tLight,\n\tDark,\n\tDojo,\n}\n"
"// Type definition for `core::test::AvailableTheme` enum\nexport type AvailableTheme \
= {\n\tLight: string;\n\tDark: string;\n\tDojo: string;\n}\nexport type \
AvailableThemeEnum = CairoCustomEnum;\n"
);
}

Expand All @@ -135,14 +118,16 @@ mod tests {
let mut buff = Buffer::new();
let writer = TsEnumGenerator;
buff.push(
"// Type definition for `core::test::AvailableTheme` enum\nexport enum AvailableTheme \
{\n\tLight,\n\tDark,\n\tDojo,\n}\n"
"// Type definition for `core::test::AvailableTheme` enum\nexport type AvailableTheme \
= {\n\tLight: string;\n\tDark: string;\n\tDojo: string;\n}\nexport type \
AvailableThemeEnum = CairoCustomEnum;\n"
.to_owned(),
);

let token_dup = create_available_theme_enum_token();
let result = writer.generate(&token_dup, &mut buff).unwrap();
assert_eq!(buff.len(), 1);
// Length is 2 because we add import of CairoCustomEnum
assert_eq!(buff.len(), 2);
assert!(result.is_empty())
}

Expand Down
80 changes: 68 additions & 12 deletions crates/dojo/bindgen/src/plugins/typescript/generator/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ use convert_case::{Case, Casing};
use dojo_world::contracts::naming;

use super::constants::JS_BIGNUMBERISH;
use super::{token_is_custom_enum, JsPrimitiveInputType};
use super::{token_is_enum, JsPrimitiveInputType};
use crate::error::BindgenResult;
use crate::plugins::{BindgenContractGenerator, Buffer};
use crate::DojoContract;

pub(crate) struct TsFunctionGenerator;
impl TsFunctionGenerator {
fn check_imports(&self, buffer: &mut Buffer) {
if !buffer.has("import { DojoProvider } from ") {
buffer.insert(0, "import { DojoProvider } from \"@dojoengine/core\";".to_owned());
if !buffer.has("import { DojoProvider, DojoCall } from ") {
buffer.insert(
0,
"import { DojoProvider, DojoCall } from \"@dojoengine/core\";".to_owned(),
);
buffer.insert(
1,
format!(
Expand Down Expand Up @@ -41,7 +44,7 @@ impl TsFunctionGenerator {
/// * token - &Function - cairo function token
fn build_function_calldata(&self, contract_name: &str, token: &Function) -> String {
format!(
"\tconst build_{contract_name}_{}_calldata = ({}) => {{
"\tconst build_{contract_name}_{}_calldata = ({}): DojoCall => {{
\t\treturn {{
\t\t\tcontractName: \"{contract_name}\",
\t\t\tentrypoint: \"{}\",
Expand Down Expand Up @@ -89,7 +92,7 @@ impl TsFunctionGenerator {
StateMutability::View => format!(
"\tconst {function_name} = async ({}) => {{
\t\ttry {{
\t\t\treturn await provider.call(\"{namespace}\", build_{function_name}_calldata({});
\t\t\treturn await provider.call(\"{namespace}\", build_{function_name}_calldata({}));
\t\t}} catch (error) {{
\t\t\tconsole.error(error);
\t\t\tthrow error;
Expand All @@ -106,7 +109,7 @@ impl TsFunctionGenerator {
token.inputs.iter().fold(Vec::new(), |mut acc, input| {
let prefix = match &input.1 {
Token::Composite(t) => {
if !token_is_custom_enum(t)
if !token_is_enum(t)
&& (t.r#type == CompositeType::Enum
|| (t.r#type == CompositeType::Struct
&& !t.type_path.starts_with("core"))
Expand Down Expand Up @@ -256,7 +259,7 @@ impl BindgenContractGenerator for TsFunctionGenerator {
mod tests {
use cainome::parser::tokens::{
Array, Composite, CompositeInner, CompositeInnerKind, CompositeType, CoreBasic, Function,
Token,
StateMutability, Token,
};
use cainome::parser::TokenizedAbi;
use dojo_world::contracts::naming;
Expand Down Expand Up @@ -291,7 +294,8 @@ mod tests {
fn test_generate_system_function() {
let generator = TsFunctionGenerator {};
let function = create_change_theme_function();
let expected = "\tconst build_actions_changeTheme_calldata = (value: BigNumberish) => {
let expected = "\tconst build_actions_changeTheme_calldata = (value: BigNumberish): \
DojoCall => {
\t\treturn {
\t\t\tcontractName: \"actions\",
\t\t\tentrypoint: \"change_theme\",
Expand Down Expand Up @@ -325,6 +329,40 @@ mod tests {
)
}

#[test]
fn test_generate_system_function_view() {
let generator = TsFunctionGenerator {};
let function = create_change_theme_view_function();
let expected = "\tconst build_actions_changeTheme_calldata = (value: BigNumberish): \
DojoCall => {
\t\treturn {
\t\t\tcontractName: \"actions\",
\t\t\tentrypoint: \"change_theme\",
\t\t\tcalldata: [value],
\t\t};
\t};
\tconst actions_changeTheme = async (value: BigNumberish) => {
\t\ttry {
\t\t\treturn await provider.call(\"onchain_dash\", build_actions_changeTheme_calldata(value));
\t\t} catch (error) {
\t\t\tconsole.error(error);
\t\t\tthrow error;
\t\t}
\t};
";

let contract = create_dojo_contract();
assert_eq!(
expected,
generator.generate_system_function(
naming::get_namespace_from_tag(&contract.tag).as_str(),
naming::get_name_from_tag(&contract.tag).as_str(),
&function
)
)
}

#[test]
fn test_format_function_inputs() {
let generator = TsFunctionGenerator {};
Expand Down Expand Up @@ -496,6 +534,18 @@ mod tests {
"value".to_owned(),
Token::CoreBasic(CoreBasic { type_path: "core::integer::u8".to_owned() }),
)],
StateMutability::External,
)
}

fn create_change_theme_view_function() -> Function {
create_test_function(
"change_theme",
vec![(
"value".to_owned(),
Token::CoreBasic(CoreBasic { type_path: "core::integer::u8".to_owned() }),
)],
StateMutability::View,
)
}

Expand All @@ -516,20 +566,26 @@ mod tests {
"value".to_owned(),
Token::CoreBasic(CoreBasic { type_path: "core::integer::u8".to_owned() }),
)],
StateMutability::External,
)
}

fn create_increate_global_counter_function() -> Function {
create_test_function("increase_global_counter", vec![])
create_test_function("increase_global_counter", vec![], StateMutability::External)
}

fn create_move_function() -> Function {
create_test_function("move", vec![])
create_test_function("move", vec![], StateMutability::External)
}

fn create_test_function(name: &str, inputs: Vec<(String, Token)>) -> Function {
fn create_test_function(
name: &str,
inputs: Vec<(String, Token)>,
state_mutability: StateMutability,
) -> Function {
Function {
name: name.to_owned(),
state_mutability: cainome::parser::tokens::StateMutability::External,
state_mutability,
inputs,
outputs: vec![],
named_outputs: vec![],
Expand Down
Loading

0 comments on commit a295c22

Please sign in to comment.