Skip to content

Commit

Permalink
feat(dojo-bindgen): support new layout types (dojoengine#1954)
Browse files Browse the repository at this point in the history
* feat: new types in unity bindgen

* feat: add types support to typescript codegen too

* feat: handle token directly to get type name

* chore: correct type names

* chore: update to correct tuple  types

* fmt

* Update mod.rs

* Update mod.rs

* Update mod.rs

* feat: add support for complex enums to unity bindgen

* feat: support generic args in typescript

* fmt

* feat: newer tuple type for c#

* feat: value type name in record field

* feat: generic rust like enum for unity bindgen

* refacotr: optional generic args for record

* feat: add suppport for generic enums for typescript v2

* feat: update test & disable typescript

* fix: update unity systsem bindgen to use new felt getter dojoengine#2008

* chore: clippy

* clean uop
  • Loading branch information
Larkooo authored May 29, 2024
1 parent 532ed95 commit 5af2bc6
Show file tree
Hide file tree
Showing 5 changed files with 317 additions and 177 deletions.
21 changes: 12 additions & 9 deletions bin/sozo/src/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ const CONTRACT_NAME_LABEL: &str = "Contract";

#[derive(Debug, Args)]
pub struct BuildArgs {
#[arg(long)]
#[arg(help = "Generate Typescript bindings.")]
pub typescript: bool,

// Should we deprecate typescript bindings codegen?
// Disabled due to lack of support in dojo.js
// #[arg(long)]
// #[arg(help = "Generate Typescript bindings.")]
// pub typescript: bool,
#[arg(long)]
#[arg(help = "Generate Typescript bindings.")]
pub typescript_v2: bool,
Expand Down Expand Up @@ -52,9 +53,11 @@ impl BuildArgs {
trace!(?compile_info, "Compiled workspace.");

let mut builtin_plugins = vec![];
if self.typescript {
builtin_plugins.push(BuiltinPlugins::Typescript);
}

// Disable typescript for now. Due to lack of support and maintenance in dojo.js
// if self.typescript {
// builtin_plugins.push(BuiltinPlugins::Typescript);
// }

if self.typescript_v2 {
builtin_plugins.push(BuiltinPlugins::TypeScriptV2);
Expand Down Expand Up @@ -177,9 +180,9 @@ mod tests {

let build_args = BuildArgs {
bindings_output: "generated".to_string(),
typescript: false,
// typescript: false,
unity: true,
typescript_v2: false,
typescript_v2: true,
stats: true,
};
let result = build_args.run(&config);
Expand Down
89 changes: 68 additions & 21 deletions crates/dojo-bindgen/src/plugins/typescript/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ impl TypescriptPlugin {
}

// Maps cairo types to C#/Unity SDK defined types
fn map_type(type_name: &str) -> String {
match type_name {
fn map_type(token: &Token, generic_args: &Vec<(String, Token)>) -> String {
match token.type_name().as_str() {
"bool" => "RecsType.Boolean".to_string(),
"u8" => "RecsType.Number".to_string(),
"u16" => "RecsType.Number".to_string(),
Expand All @@ -30,8 +30,44 @@ impl TypescriptPlugin {
"bytes31" => "RecsType.String".to_string(),
"ClassHash" => "RecsType.BigInt".to_string(),
"ContractAddress" => "RecsType.BigInt".to_string(),
"ByteArray" => "RecsType.String".to_string(),
"array" => {
if let Token::Array(array) = token {
format!("{}[]", TypescriptPlugin::map_type(&array.inner, generic_args))
} else {
panic!("Invalid array token: {:?}", token);
}
}
"tuple" => {
if let Token::Tuple(tuple) = token {
let inners = tuple
.inners
.iter()
.map(|inner| TypescriptPlugin::map_type(inner, generic_args))
.collect::<Vec<String>>()
.join(", ");

_ => type_name.to_string(),
format!("[{}]", inners)
} else {
panic!("Invalid tuple token: {:?}", token);
}
}
"generic_arg" => {
if let Token::GenericArg(arg) = &token {
let arg_type = generic_args
.iter()
.find(|(name, _)| name == arg)
.unwrap_or_else(|| panic!("Generic arg not found: {}", arg))
.1
.clone();

TypescriptPlugin::map_type(&arg_type, generic_args)
} else {
panic!("Invalid generic arg token: {:?}", token);
}
}

_ => token.type_name().to_string(),
}
}

Expand All @@ -50,7 +86,7 @@ impl TypescriptPlugin {
let mut fields = String::new();

for field in &token.inners {
let mapped = TypescriptPlugin::map_type(field.token.type_name().as_str());
let mapped = TypescriptPlugin::map_type(&field.token, &token.generic_args);
if mapped == field.token.type_name() {
let token = handled_tokens
.iter()
Expand Down Expand Up @@ -93,24 +129,35 @@ export const {name}Definition = {{
// This will be formatted into a C# enum
// Enum is mapped using index of cairo enum
fn format_enum(token: &Composite) -> String {
let fields = token
.inners
.iter()
.map(|field| format!("{},", field.name,))
.collect::<Vec<String>>()
.join("\n ");
let name = token.type_name();

format!(
let mut result = format!(
"
// Type definition for `{}` enum
export enum {} {{
{}
}}
",
token.type_path,
token.type_name(),
fields
)
type {} = ",
token.type_path, name
);

let mut variants = Vec::new();

for field in &token.inners {
let field_type =
TypescriptPlugin::map_type(&field.token, &token.generic_args).replace("()", "");

let variant_definition = if field_type.is_empty() {
// No associated data
format!("{{ type: '{}'; }}", field.name)
} else {
// With associated data
format!("{{ type: '{}'; data: {}; }}", field.name, field_type)
};

variants.push(variant_definition);
}

result += &variants.join(" | ");

result
}

// Token should be a model
Expand All @@ -123,7 +170,7 @@ export enum {} {{
.inners
.iter()
.map(|field| {
let mapped = TypescriptPlugin::map_type(field.token.type_name().as_str());
let mapped = TypescriptPlugin::map_type(&field.token, &model.generic_args);
if mapped == field.token.type_name() {
custom_types.push(format!("\"{}\"", field.token.type_name()));

Expand Down Expand Up @@ -258,7 +305,7 @@ export function defineContractComponents(world: World) {
fn format_system(system: &Function, handled_tokens: &[Composite]) -> String {
fn map_type(token: &Token) -> String {
match token {
Token::CoreBasic(t) => TypescriptPlugin::map_type(&t.type_name())
Token::CoreBasic(_) => TypescriptPlugin::map_type(token, &vec![])
.replace("RecsType.", "")
// types should be lowercased
.to_lowercase(),
Expand Down
Loading

0 comments on commit 5af2bc6

Please sign in to comment.