From 792898152d2664e69ab56a056a5ef56ac6a1b9d6 Mon Sep 17 00:00:00 2001 From: "remy.baranx@gmail.com" Date: Fri, 4 Oct 2024 15:48:52 +0200 Subject: [PATCH 01/11] feat: generate contracts for Dojo events --- crates/compiler/src/aux_data.rs | 48 + crates/compiler/src/compiler/compiler.rs | 33 +- crates/compiler/src/compiler/manifest.rs | 206 +- crates/compiler/src/lib.rs | 1 + .../src/plugin/attribute_macros/element.rs | 320 +++ .../src/plugin/attribute_macros/event.rs | 434 ++-- .../src/plugin/attribute_macros/mod.rs | 4 +- .../src/plugin/attribute_macros/model.rs | 360 +-- .../src/plugin/attribute_macros/patches.rs | 222 +- .../plugin/derive_macros/introspect/layout.rs | 30 +- .../plugin/derive_macros/introspect/mod.rs | 12 +- .../plugin/derive_macros/introspect/size.rs | 2 +- .../src/plugin/derive_macros/introspect/ty.rs | 20 +- .../compiler/src/plugin/inline_macros/emit.rs | 30 +- crates/compiler/src/plugin/plugin.rs | 11 +- crates/compiler/src/plugin/plugin_test.rs | 1 + .../src/plugin/plugin_test_data/event | 1621 ++++++++++++ .../src/plugin/plugin_test_data/introspect | 1240 ++++----- .../src/plugin/plugin_test_data/model | 2300 +++++++++-------- crates/contracts/src/event/event.cairo | 48 + crates/contracts/src/lib.cairo | 14 +- .../src/{model => meta}/introspect.cairo | 6 +- .../src/{model => meta}/layout.cairo | 0 crates/contracts/src/model/metadata.cairo | 25 +- crates/contracts/src/model/model.cairo | 6 +- crates/contracts/src/storage/layout.cairo | 2 +- crates/contracts/src/tests/benchmarks.cairo | 5 +- .../src/tests/expanded/selector_attack.cairo | 8 +- .../tests/{model => meta}/introspect.cairo | 4 +- crates/contracts/src/tests/model/model.cairo | 6 +- .../contracts/src/tests/world/entities.cairo | 5 +- crates/contracts/src/tests/world/world.cairo | 28 +- crates/contracts/src/utils/utils.cairo | 2 +- crates/contracts/src/world/errors.cairo | 8 + .../contracts/src/world/world_contract.cairo | 194 +- examples/dojo_simple/src/lib.cairo | 22 +- scripts/clippy.sh | 0 scripts/tests.sh | 1 + 38 files changed, 4923 insertions(+), 2356 deletions(-) create mode 100644 crates/compiler/src/plugin/attribute_macros/element.rs create mode 100644 crates/compiler/src/plugin/plugin_test_data/event create mode 100644 crates/contracts/src/event/event.cairo rename crates/contracts/src/{model => meta}/introspect.cairo (97%) rename crates/contracts/src/{model => meta}/layout.cairo (100%) rename crates/contracts/src/tests/{model => meta}/introspect.cairo (98%) mode change 100644 => 100755 scripts/clippy.sh mode change 100644 => 100755 scripts/tests.sh diff --git a/crates/compiler/src/aux_data.rs b/crates/compiler/src/aux_data.rs index 2aae6ed..859171f 100644 --- a/crates/compiler/src/aux_data.rs +++ b/crates/compiler/src/aux_data.rs @@ -38,6 +38,27 @@ impl GeneratedFileAuxData for ModelAuxData { } } +#[derive(Clone, Debug, PartialEq)] +pub struct EventAuxData { + pub name: String, + pub namespace: String, + pub members: Vec, +} + +impl GeneratedFileAuxData for EventAuxData { + fn as_any(&self) -> &dyn std::any::Any { + self + } + + fn eq(&self, other: &dyn GeneratedFileAuxData) -> bool { + if let Some(other) = other.as_any().downcast_ref::() { + self == other + } else { + false + } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ContractAuxData { pub name: SmolStr, @@ -66,6 +87,8 @@ impl GeneratedFileAuxData for ContractAuxData { /// as keys. #[derive(Debug, Default, PartialEq)] pub struct DojoAuxData { + /// A list of events that were processed by the plugin. + pub events: HashMap, /// A list of models that were processed by the plugin. pub models: HashMap, /// A list of contracts that were processed by the plugin. @@ -146,6 +169,31 @@ impl DojoAuxData { continue; } + if let Some(event_aux_data) = aux_data.downcast_ref::() { + // As events are defined from a struct (usually Pascal case), we have converted + // the underlying starknet contract name to snake case in the `#[dojo::event]` attribute + // macro processing. + // Same thing as for contracts, we need to add the event name to the module path + // to get the fully qualified path of the contract. + let event_contract_path = format!( + "{}{}{}", + module_path, + CAIRO_PATH_SEPARATOR, + event_aux_data.name.to_case(Case::Snake) + ); + + trace!( + event_contract_path, + ?event_aux_data, + "Adding dojo event to aux data." + ); + + dojo_aux_data + .events + .insert(event_contract_path, event_aux_data.clone()); + continue; + } + // As every contracts and models are starknet contracts under the hood, // we need to filter already processed Starknet contracts. // Also important to note that, the module id for a starknet contract is diff --git a/crates/compiler/src/compiler/compiler.rs b/crates/compiler/src/compiler/compiler.rs index ffae98d..c50fc46 100644 --- a/crates/compiler/src/compiler/compiler.rs +++ b/crates/compiler/src/compiler/compiler.rs @@ -28,7 +28,7 @@ use tracing::{trace, trace_span}; use crate::aux_data::DojoAuxData; use crate::compiler::manifest::{ - AbstractBaseManifest, ContractManifest, ModelManifest, StarknetContractManifest, + AbstractBaseManifest, ContractManifest, EventManifest, ModelManifest, StarknetContractManifest, }; use crate::scarb_extensions::{ProfileSpec, WorkspaceExt}; use crate::{ @@ -199,6 +199,7 @@ impl Compiler for DojoCompiler { // to create the manifests. let contracts = write_dojo_contracts_artifacts(&artifact_manager, &aux_data)?; let models = write_dojo_models_artifacts(&artifact_manager, &aux_data)?; + let events = write_dojo_events_artifacts(&artifact_manager, &aux_data)?; let (world, base, sn_contracts) = write_sn_contract_artifacts(&artifact_manager, &aux_data)?; @@ -206,6 +207,7 @@ impl Compiler for DojoCompiler { base_manifest.base = base; base_manifest.contracts.extend(contracts); base_manifest.models.extend(models); + base_manifest.events.extend(events); base_manifest.sn_contracts.extend(sn_contracts); base_manifest.write()?; @@ -473,6 +475,35 @@ fn write_dojo_models_artifacts( Ok(models) } +/// Writes the dojo event artifacts to the target directory and returns the event manifests. +fn write_dojo_events_artifacts( + artifact_manager: &ArtifactManager, + aux_data: &DojoAuxData, +) -> Result> { + let mut events = Vec::new(); + + for (qualified_path, event_aux_data) in aux_data.events.iter() { + let tag = naming::get_tag(&event_aux_data.namespace, &event_aux_data.name); + let filename = naming::get_filename_from_tag(&tag); + + let target_dir = artifact_manager + .workspace() + .target_dir_profile() + .child(MODELS_DIR); + + artifact_manager.write_sierra_class(qualified_path, &target_dir, &filename)?; + + events.push(EventManifest { + class_hash: artifact_manager.get_class_hash(qualified_path)?, + qualified_path: qualified_path.to_string(), + tag, + members: event_aux_data.members.clone(), + }); + } + + Ok(events) +} + /// Writes the starknet contracts artifacts to the target directory and returns the starknet contract manifests. /// /// Returns a tuple with the world contract manifest, the base contract manifest and the other starknet contract manifests. diff --git a/crates/compiler/src/compiler/manifest.rs b/crates/compiler/src/compiler/manifest.rs index 40c8819..d752067 100644 --- a/crates/compiler/src/compiler/manifest.rs +++ b/crates/compiler/src/compiler/manifest.rs @@ -8,7 +8,7 @@ use std::io::{Read, Write}; use anyhow::Result; use dojo_types::naming; -use scarb::core::Workspace; +use scarb::core::{Config, Workspace}; use serde::{Deserialize, Serialize}; use serde_with::serde_as; use starknet::core::serde::unsigned_field_element::UfeHex; @@ -16,7 +16,8 @@ use starknet::core::types::Felt; use crate::scarb_extensions::{FilesystemExt, WorkspaceExt}; use crate::{ - BASE_CONTRACT_TAG, CAIRO_PATH_SEPARATOR, CONTRACTS_DIR, MODELS_DIR, WORLD_CONTRACT_TAG, + BASE_CONTRACT_TAG, CAIRO_PATH_SEPARATOR, CONTRACTS_DIR, EVENTS_DIR, MODELS_DIR, + WORLD_CONTRACT_TAG, }; const TOML_EXTENSION: &str = "toml"; @@ -33,6 +34,13 @@ pub struct Member { pub key: bool, } +pub trait ManifestMethods { + fn type_name(&self) -> String; + fn tag(&self) -> String; + fn qualified_path(&self) -> String; + fn to_toml_string(&self) -> Result; +} + /// Represents the contract of a dojo contract. #[serde_as] #[derive(Clone, Default, Debug, Serialize, Deserialize)] @@ -46,6 +54,22 @@ pub struct ContractManifest { pub systems: Vec, } +impl ManifestMethods for ContractManifest { + fn type_name(&self) -> String { + "contract".to_string() + } + + fn tag(&self) -> String { + self.tag.clone() + } + fn qualified_path(&self) -> String { + self.qualified_path.clone() + } + fn to_toml_string(&self) -> Result { + toml::to_string(self) + } +} + /// Represents the contract of a dojo model. #[serde_as] #[derive(Clone, Default, Debug, Serialize, Deserialize)] @@ -59,6 +83,51 @@ pub struct ModelManifest { pub members: Vec, } +impl ManifestMethods for ModelManifest { + fn type_name(&self) -> String { + "model".to_string() + } + + fn tag(&self) -> String { + self.tag.clone() + } + fn qualified_path(&self) -> String { + self.qualified_path.clone() + } + fn to_toml_string(&self) -> Result { + toml::to_string(self) + } +} + +/// Represents the contract of a dojo event. +#[serde_as] +#[derive(Clone, Default, Debug, Serialize, Deserialize)] +#[cfg_attr(test, derive(PartialEq))] +#[serde(tag = "kind", rename = "DojoEvent")] +pub struct EventManifest { + #[serde_as(as = "UfeHex")] + pub class_hash: Felt, + pub qualified_path: String, + pub tag: String, + pub members: Vec, +} + +impl ManifestMethods for EventManifest { + fn type_name(&self) -> String { + "event".to_string() + } + + fn tag(&self) -> String { + self.tag.clone() + } + fn qualified_path(&self) -> String { + self.qualified_path.clone() + } + fn to_toml_string(&self) -> Result { + toml::to_string(self) + } +} + /// Represents a starknet contract. #[serde_as] #[derive(Clone, Default, Debug, Serialize, Deserialize)] @@ -83,6 +152,7 @@ pub struct AbstractBaseManifest<'w> { pub base: StarknetContractManifest, pub contracts: Vec, pub models: Vec, + pub events: Vec, pub sn_contracts: Vec, } @@ -95,36 +165,55 @@ impl<'w> AbstractBaseManifest<'w> { base: StarknetContractManifest::default(), contracts: vec![], models: vec![], + events: vec![], sn_contracts: vec![], } } pub fn read(&mut self) -> Result<()> { - let base_dir = self.workspace.dojo_base_manfiests_dir_profile(); + fn read_elements( + config: &Config, + name: &str, + dir: scarb::flock::Filesystem, + vec: &mut Vec, + ) -> Result<()> + where + T: serde::de::DeserializeOwned, + { + for file_name in dir.list_files()? { + let mut file = dir.open_ro( + &file_name, + &format!("{name} manifest for `{}`", &file_name), + config, + )?; + let mut s = String::new(); + file.read_to_string(&mut s)?; + vec.push(toml::from_str(&s)?); + } - let contracts_dir = base_dir.child(CONTRACTS_DIR); - for file_name in contracts_dir.list_files()? { - let mut file = contracts_dir.open_ro( - &file_name, - &format!("contract manifest for `{}`", &file_name), - self.workspace.config(), - )?; - let mut contract_str = String::new(); - file.read_to_string(&mut contract_str)?; - self.contracts.push(toml::from_str(&contract_str)?); + Ok(()) } - let models_dir = base_dir.child(MODELS_DIR); - for file_name in models_dir.list_files()? { - let mut file = models_dir.open_ro( - &file_name, - &format!("model manifest for `{}`", &file_name), - self.workspace.config(), - )?; - let mut model_str = String::new(); - file.read_to_string(&mut model_str)?; - self.models.push(toml::from_str(&model_str)?); - } + let base_dir = self.workspace.dojo_base_manfiests_dir_profile(); + + read_elements( + self.workspace.config(), + "contract", + base_dir.child(CONTRACTS_DIR), + &mut self.contracts, + )?; + read_elements( + self.workspace.config(), + "model", + base_dir.child(MODELS_DIR), + &mut self.models, + )?; + read_elements( + self.workspace.config(), + "event", + base_dir.child(EVENTS_DIR), + &mut self.events, + )?; for file_name in base_dir.list_files()? { let mut file = base_dir.open_ro( @@ -155,6 +244,37 @@ impl<'w> AbstractBaseManifest<'w> { /// /// * `path` - The path to write the manifest files to. pub fn write(&self) -> Result<()> { + fn write_element( + config: &Config, + dir: scarb::flock::Filesystem, + elements: &Vec, + ) -> Result<()> + where + T: ManifestMethods, + { + for element in elements { + let name = format!( + "{}.{}", + naming::get_filename_from_tag(&element.tag()), + TOML_EXTENSION + ); + + let mut file = dir.open_rw( + name, + &format!( + "{} manifest for `{}`", + element.type_name(), + element.qualified_path() + ), + config, + )?; + + file.write(element.to_toml_string()?.as_bytes())?; + } + + Ok(()) + } + let base_dir = self.workspace.dojo_base_manfiests_dir_profile(); let world = toml::to_string(&self.world)?; @@ -177,40 +297,10 @@ impl<'w> AbstractBaseManifest<'w> { file.write(base.as_bytes())?; - let contracts_dir = base_dir.child(CONTRACTS_DIR); - let models_dir = base_dir.child(MODELS_DIR); - - for contract in &self.contracts { - let name = format!( - "{}.{}", - naming::get_filename_from_tag(&contract.tag), - TOML_EXTENSION - ); - - let mut file = contracts_dir.open_rw( - name, - &format!("contract manifest for `{}`", contract.qualified_path), - self.workspace.config(), - )?; - - file.write(toml::to_string(contract)?.as_bytes())?; - } - - for model in &self.models { - let name = format!( - "{}.{}", - naming::get_filename_from_tag(&model.tag), - TOML_EXTENSION - ); - - let mut file = models_dir.open_rw( - name, - &format!("model manifest for `{}`", model.qualified_path), - self.workspace.config(), - )?; - - file.write(toml::to_string(model)?.as_bytes())?; - } + let config = self.workspace.config(); + write_element(config, base_dir.child(CONTRACTS_DIR), &self.contracts)?; + write_element(config, base_dir.child(MODELS_DIR), &self.models)?; + write_element(config, base_dir.child(EVENTS_DIR), &self.events)?; for sn_contract in &self.sn_contracts { let name = format!( diff --git a/crates/compiler/src/lib.rs b/crates/compiler/src/lib.rs index d244aed..0c72de3 100644 --- a/crates/compiler/src/lib.rs +++ b/crates/compiler/src/lib.rs @@ -16,5 +16,6 @@ pub const BASE_CONTRACT_TAG: &str = "dojo-base"; pub const RESOURCE_METADATA_QUALIFIED_PATH: &str = "dojo::model::metadata::resource_metadata"; pub const CONTRACTS_DIR: &str = "contracts"; pub const MODELS_DIR: &str = "models"; +pub const EVENTS_DIR: &str = "events"; pub const MANIFESTS_DIR: &str = "manifests"; pub const MANIFESTS_BASE_DIR: &str = "base"; diff --git a/crates/compiler/src/plugin/attribute_macros/element.rs b/crates/compiler/src/plugin/attribute_macros/element.rs new file mode 100644 index 0000000..3d60f3f --- /dev/null +++ b/crates/compiler/src/plugin/attribute_macros/element.rs @@ -0,0 +1,320 @@ +use std::collections::HashMap; + +use crate::compiler::manifest::Member; +use crate::namespace_config::NamespaceConfig; +use cairo_lang_defs::patcher::RewriteNode; +use cairo_lang_defs::plugin::PluginDiagnostic; +use cairo_lang_diagnostics::Severity; +use cairo_lang_syntax::node::ast::{ + ArgClause, ArgClauseNamed, Expr, ItemStruct, Member as MemberAst, OptionArgListParenthesized, +}; +use cairo_lang_syntax::node::db::SyntaxGroup; +use cairo_lang_syntax::node::helpers::QueryAttrs; +use cairo_lang_syntax::node::{Terminal, TypedStablePtr, TypedSyntaxNode}; +use dojo_types::naming; + +pub const DEFAULT_VERSION: u8 = 1; + +pub const PARAMETER_VERSION_NAME: &str = "version"; +pub const PARAMETER_NAMESPACE: &str = "namespace"; +pub const PARAMETER_NOMAPPING: &str = "nomapping"; + +/// `StructParameterParser` provides a general `from_struct` function to parse +/// the parameters of a struct attribute like dojo::model or dojo::event. +/// Processing of specific parameters can then be implemented through the `process_named_parameters` +/// function. +pub trait StructParameterParser { + fn from_struct( + &mut self, + db: &dyn SyntaxGroup, + attribute_name: &String, + struct_ast: ItemStruct, + diagnostics: &mut Vec, + ) { + let mut processed_args: HashMap = HashMap::new(); + + if let OptionArgListParenthesized::ArgListParenthesized(arguments) = struct_ast + .attributes(db) + .query_attr(db, attribute_name) + .first() + .unwrap() + .arguments(db) + { + arguments + .arguments(db) + .elements(db) + .iter() + .for_each(|a| match a.arg_clause(db) { + ArgClause::Named(x) => { + let arg_name = x.name(db).text(db).to_string(); + + if processed_args.contains_key(&arg_name) { + diagnostics.push(PluginDiagnostic { + message: format!( + "Too many '{}' attributes for {attribute_name}", + arg_name + ), + stable_ptr: struct_ast.stable_ptr().untyped(), + severity: Severity::Error, + }); + } else { + processed_args.insert(arg_name.clone(), true); + self.process_named_parameters(db, attribute_name, x, diagnostics); + } + } + ArgClause::Unnamed(x) => { + diagnostics.push(PluginDiagnostic { + message: format!( + "Unexpected argument '{}' for {attribute_name}", + x.as_syntax_node().get_text(db) + ), + stable_ptr: x.stable_ptr().untyped(), + severity: Severity::Warning, + }); + } + ArgClause::FieldInitShorthand(x) => { + diagnostics.push(PluginDiagnostic { + message: format!( + "Unexpected argument '{}' for {attribute_name}", + x.name(db).name(db).text(db).to_string() + ), + stable_ptr: x.stable_ptr().untyped(), + severity: Severity::Warning, + }); + } + }) + } + } + + fn process_named_parameters( + &mut self, + db: &dyn SyntaxGroup, + attribute_name: &String, + arg: ArgClauseNamed, + diagnostics: &mut Vec, + ); +} + +#[derive(Debug)] +pub struct CommonStructParameters { + pub version: u8, + pub namespace: Option, + pub nomapping: bool, +} + +impl Default for CommonStructParameters { + fn default() -> CommonStructParameters { + CommonStructParameters { + version: DEFAULT_VERSION, + namespace: Option::None, + nomapping: false, + } + } +} + +impl StructParameterParser for CommonStructParameters { + fn process_named_parameters( + &mut self, + db: &dyn SyntaxGroup, + attribute_name: &String, + arg: ArgClauseNamed, + diagnostics: &mut Vec, + ) { + let arg_name = arg.name(db).text(db).to_string(); + let arg_value = arg.value(db); + + match arg_name.as_str() { + PARAMETER_VERSION_NAME => { + self.version = get_version(db, attribute_name, arg_value, diagnostics); + } + PARAMETER_NAMESPACE => { + self.namespace = get_namespace(db, attribute_name, arg_value, diagnostics); + } + PARAMETER_NOMAPPING => { + self.nomapping = true; + } + _ => { + diagnostics.push(PluginDiagnostic { + message: format!("Unexpected argument '{}' for {attribute_name}", arg_name), + stable_ptr: arg.stable_ptr().untyped(), + severity: Severity::Warning, + }); + } + } + } +} + +pub fn compute_namespace( + element_name: &str, + parameters: &CommonStructParameters, + namespace_config: &NamespaceConfig, +) -> String { + let unmapped_namespace = parameters + .namespace + .clone() + .unwrap_or(namespace_config.default.clone()); + + if parameters.nomapping { + unmapped_namespace + } else { + // Maps namespace from the tag to ensure higher precision on matching namespace mappings. + namespace_config.get_mapping(&naming::get_tag(&unmapped_namespace, element_name)) + } +} + +pub fn parse_members( + db: &dyn SyntaxGroup, + members: &[MemberAst], + diagnostics: &mut Vec, +) -> Vec { + members + .iter() + .filter_map(|member_ast| { + let member = Member { + name: member_ast.name(db).text(db).to_string(), + ty: member_ast + .type_clause(db) + .ty(db) + .as_syntax_node() + .get_text(db) + .trim() + .to_string(), + key: member_ast.has_attr(db, "key"), + }; + + // validate key member + if member.key && member.ty == "u256" { + diagnostics.push(PluginDiagnostic { + message: "Key is only supported for core types that are 1 felt long once \ + serialized. `u256` is a struct of 2 u128, hence not supported." + .into(), + stable_ptr: member_ast.name(db).stable_ptr().untyped(), + severity: Severity::Error, + }); + None + } else { + Some(member) + } + }) + .collect::>() +} + +pub fn serialize_keys_and_values( + members: &[Member], + serialized_keys: &mut Vec, + serialized_values: &mut Vec, +) { + members.iter().for_each(|member| { + if member.key { + serialized_keys.push(serialize_member_ty(member, true)); + } else { + serialized_values.push(serialize_member_ty(member, true)); + } + }); +} + +pub fn deserialize_keys_and_values( + members: &[Member], + keys_input_name: &str, + deserialized_keys: &mut Vec, + values_input_name: &str, + deserialized_values: &mut Vec, +) { + members.iter().for_each(|member| { + if member.key { + deserialized_keys.push(deserialize_member_ty(member, keys_input_name)); + } else { + deserialized_values.push(deserialize_member_ty(member, values_input_name)); + } + }); +} + +/// Creates a [`RewriteNode`] for the member type serialization. +/// +/// # Arguments +/// +/// * member: The member to serialize. +pub fn serialize_member_ty(member: &Member, with_self: bool) -> RewriteNode { + RewriteNode::Text(format!( + "core::serde::Serde::serialize({}{}, ref serialized);\n", + if with_self { "self." } else { "@" }, + member.name + )) +} + +pub fn deserialize_member_ty(member: &Member, input_name: &str) -> RewriteNode { + RewriteNode::Text(format!( + "let {} = core::serde::Serde::<{}>::deserialize(ref {input_name})?;\n", + member.name, member.ty + )) +} + +/// Get the version from the `Expr` parameter. +fn get_version( + db: &dyn SyntaxGroup, + attribute_name: &String, + arg_value: Expr, + diagnostics: &mut Vec, +) -> u8 { + match arg_value { + Expr::Literal(ref value) => { + if let Ok(value) = value.text(db).parse::() { + if value <= DEFAULT_VERSION { + value + } else { + diagnostics.push(PluginDiagnostic { + message: format!("{attribute_name} version {} not supported", value), + stable_ptr: arg_value.stable_ptr().untyped(), + severity: Severity::Error, + }); + DEFAULT_VERSION + } + } else { + diagnostics.push(PluginDiagnostic { + message: format!( + "The argument '{}' of {attribute_name} must be an integer", + PARAMETER_VERSION_NAME + ), + stable_ptr: arg_value.stable_ptr().untyped(), + severity: Severity::Error, + }); + DEFAULT_VERSION + } + } + _ => { + diagnostics.push(PluginDiagnostic { + message: format!( + "The argument '{}' of {attribute_name} must be an integer", + PARAMETER_VERSION_NAME + ), + stable_ptr: arg_value.stable_ptr().untyped(), + severity: Severity::Error, + }); + DEFAULT_VERSION + } + } +} + +/// Get the namespace from the `Expr` parameter. +fn get_namespace( + db: &dyn SyntaxGroup, + attribute_name: &String, + arg_value: Expr, + diagnostics: &mut Vec, +) -> Option { + match arg_value { + Expr::ShortString(ss) => Some(ss.string_value(db).unwrap()), + Expr::String(s) => Some(s.string_value(db).unwrap()), + _ => { + diagnostics.push(PluginDiagnostic { + message: format!( + "The argument '{}' of {attribute_name} must be a string", + PARAMETER_NAMESPACE + ), + stable_ptr: arg_value.stable_ptr().untyped(), + severity: Severity::Error, + }); + Option::None + } + } +} diff --git a/crates/compiler/src/plugin/attribute_macros/event.rs b/crates/compiler/src/plugin/attribute_macros/event.rs index a498a40..36381bc 100644 --- a/crates/compiler/src/plugin/attribute_macros/event.rs +++ b/crates/compiler/src/plugin/attribute_macros/event.rs @@ -1,202 +1,292 @@ //! A custom implementation of the starknet::Event derivation path. -//! +//! //! We append the event selector directly within the append_keys_and_data function. //! Without the need of the enum for all event variants. //! //! https://github.com/starkware-libs/cairo/blob/main/crates/cairo-lang-starknet/src/plugin/derive/event.rs -use cairo_lang_defs::patcher::{ModifiedNode, RewriteNode}; -use cairo_lang_defs::plugin::PluginDiagnostic; -use cairo_lang_starknet::plugin::aux_data::StarkNetEventAuxData; -use cairo_lang_starknet::plugin::consts::{ - EVENT_TRAIT, EVENT_TYPE_NAME, KEY_ATTR, NESTED_ATTR, SERDE_ATTR, +use cairo_lang_defs::patcher::{PatchBuilder, RewriteNode}; +use cairo_lang_defs::plugin::{ + DynGeneratedFileAuxData, PluginDiagnostic, PluginGeneratedFile, PluginResult, +}; +use cairo_lang_diagnostics::Severity; +use cairo_lang_syntax::node::{ + ast, ast::ArgClauseNamed, ast::Expr, ast::ModuleItem, db::SyntaxGroup, helpers::QueryAttrs, + Terminal, TypedStablePtr, TypedSyntaxNode, +}; +use cairo_lang_utils::unordered_hash_map::UnorderedHashMap; + +use convert_case::{Case, Casing}; +use dojo_types::naming; + +use crate::aux_data::EventAuxData; +use crate::namespace_config::NamespaceConfig; +use crate::plugin::derive_macros::{ + extract_derive_attr_names, handle_derive_attrs, DOJO_INTROSPECT_DERIVE, DOJO_PACKED_DERIVE, }; -use cairo_lang_starknet::plugin::events::EventData; -use cairo_lang_starknet_classes::abi::EventFieldKind; -use cairo_lang_syntax::node::db::SyntaxGroup; -use cairo_lang_syntax::node::helpers::QueryAttrs; -use cairo_lang_syntax::node::{ast, Terminal, TypedStablePtr, TypedSyntaxNode}; -use indoc::formatdoc; -use crate::aux_data::DojoAuxData; +use super::element::{ + compute_namespace, parse_members, serialize_keys_and_values, CommonStructParameters, + StructParameterParser, +}; + +use super::patches::EVENT_PATCH; +use super::DOJO_EVENT_ATTR; + +pub const PARAMETER_HISTORICAL: &str = "historical"; +pub const DEFAULT_HISTORICAL_VALUE: bool = true; + +#[derive(Debug)] +struct EventParameters { + common: CommonStructParameters, + historical: bool, +} + +impl Default for EventParameters { + fn default() -> EventParameters { + EventParameters { + common: CommonStructParameters::default(), + historical: DEFAULT_HISTORICAL_VALUE, + } + } +} + +impl StructParameterParser for EventParameters { + fn process_named_parameters( + &mut self, + db: &dyn SyntaxGroup, + attribute_name: &String, + arg: ArgClauseNamed, + diagnostics: &mut Vec, + ) { + match arg.name(db).text(db).as_str() { + PARAMETER_HISTORICAL => { + self.historical = get_historical(attribute_name, arg.value(db), diagnostics); + } + _ => { + self.common + .process_named_parameters(db, attribute_name, arg, diagnostics); + } + } + } +} #[derive(Debug, Clone, Default)] pub struct DojoEvent {} impl DojoEvent { + /// A handler for Dojo code that modifies an event struct. + /// Parameters: + /// * db: The semantic database. + /// * struct_ast: The AST of the event struct. + /// + /// Returns: + /// * A RewriteNode containing the generated code. pub fn from_struct( db: &dyn SyntaxGroup, - aux_data: &mut DojoAuxData, struct_ast: ast::ItemStruct, - ) -> (RewriteNode, Vec) { + namespace_config: &NamespaceConfig, + ) -> PluginResult { let mut diagnostics = vec![]; + let mut parameters = EventParameters::default(); - let generic_params = struct_ast.generic_params(db); - match generic_params { - ast::OptionWrappedGenericParamList::Empty(_) => {} - _ => { - diagnostics.push(PluginDiagnostic::error( - generic_params.stable_ptr().untyped(), - format!("{EVENT_TYPE_NAME} structs with generic arguments are unsupported"), - )); + parameters.from_struct( + db, + &DOJO_EVENT_ATTR.to_string(), + struct_ast.clone(), + &mut diagnostics, + ); + + let event_name = struct_ast + .name(db) + .as_syntax_node() + .get_text(db) + .trim() + .to_string(); + let event_namespace = compute_namespace(&event_name, ¶meters.common, namespace_config); + + for (id, value) in [("name", &event_name), ("namespace", &event_namespace)] { + if !NamespaceConfig::is_name_valid(value) { + return PluginResult { + code: None, + diagnostics: vec![PluginDiagnostic { + stable_ptr: struct_ast.stable_ptr().0, + message: format!( + "The event {id} '{value}' can only contain characters (a-z/A-Z), \ + digits (0-9) and underscore (_)." + ), + severity: Severity::Error, + }], + remove_original_item: false, + }; } } - // Generate append_keys_and_data() code. - let mut append_members = vec![]; - let mut deserialize_members = vec![]; - let mut ctor = vec![]; - let mut members = vec![]; - for member in struct_ast.members(db).elements(db) { - let member_name = RewriteNode::new_trimmed(member.name(db).as_syntax_node()); - let member_kind = - get_field_kind_for_member(db, &mut diagnostics, &member, EventFieldKind::DataSerde); - members.push((member.name(db).text(db), member_kind)); - - let member_for_append = RewriteNode::interpolate_patched( - "self.$member_name$", - &[("member_name".to_string(), member_name.clone())].into(), - ); - let append_member = append_field(member_kind, member_for_append); - let deserialize_member = deserialize_field(member_kind, member_name.clone()); - append_members.push(append_member); - deserialize_members.push(deserialize_member); - ctor.push(RewriteNode::interpolate_patched( - "$member_name$, ", - &[("member_name".to_string(), member_name)].into(), - )); + let event_tag = naming::get_tag(&event_namespace, &event_name); + let event_name_hash = naming::compute_bytearray_hash(&event_name); + let event_namespace_hash = naming::compute_bytearray_hash(&event_namespace); + + let event_version = parameters.common.version.to_string(); + let event_historical = parameters.historical.to_string(); + let event_selector = + naming::compute_selector_from_hashes(event_namespace_hash, event_name_hash).to_string(); + + let members = parse_members(db, &struct_ast.members(db).elements(db), &mut diagnostics); + + let mut serialized_keys: Vec = vec![]; + let mut serialized_values: Vec = vec![]; + + serialize_keys_and_values(&members, &mut serialized_keys, &mut serialized_values); + + if serialized_keys.is_empty() { + diagnostics.push(PluginDiagnostic { + message: "Event must define at least one #[key] attribute".into(), + stable_ptr: struct_ast.name(db).stable_ptr().untyped(), + severity: Severity::Error, + }); + } + + if serialized_values.is_empty() { + diagnostics.push(PluginDiagnostic { + message: "Event must define at least one member that is not a key".into(), + stable_ptr: struct_ast.name(db).stable_ptr().untyped(), + severity: Severity::Error, + }); } - let event_data = EventData::Struct { members }; - //aux_data.events.push(StarkNetEventAuxData { event_data }); - - let append_members = RewriteNode::Modified(ModifiedNode { - children: Some(append_members), - }); - let deserialize_members = RewriteNode::Modified(ModifiedNode { - children: Some(deserialize_members), - }); - let ctor = RewriteNode::Modified(ModifiedNode { - children: Some(ctor), - }); - - // Add an implementation for `Event`. - let struct_name = RewriteNode::new_trimmed(struct_ast.name(db).as_syntax_node()); - ( - // Append the event selector using the struct_name for the selector - // and then append the members. - RewriteNode::interpolate_patched( - &formatdoc!( - " - impl $struct_name$IsEvent of {EVENT_TRAIT}<$struct_name$> {{ - fn append_keys_and_data( - self: @$struct_name$, ref keys: Array, ref data: Array - ) {{ - core::array::ArrayTrait::append(ref keys, \ - dojo::model::Model::<$struct_name$>::selector()); - $append_members$ - }} - fn deserialize( - ref keys: Span, ref data: Span, - ) -> Option<$struct_name$> {{$deserialize_members$ - Option::Some($struct_name$ {{$ctor$}}) - }} - }} - " + + let member_names = members + .iter() + .map(|member| RewriteNode::Text(format!("{},\n", member.name.clone()))) + .collect::>(); + + let mut derive_attr_names = extract_derive_attr_names( + db, + &mut diagnostics, + struct_ast.attributes(db).query_attr(db, "derive"), + ); + + // Ensures events always derive Introspect if not already derived, + // and do not derive IntrospectPacked. + if derive_attr_names.contains(&DOJO_PACKED_DERIVE.to_string()) { + diagnostics.push(PluginDiagnostic { + message: format!( + "Event should derive {DOJO_INTROSPECT_DERIVE} instead of {DOJO_PACKED_DERIVE}." ), - &[ - ("struct_name".to_string(), struct_name), - ("append_members".to_string(), append_members), - ("deserialize_members".to_string(), deserialize_members), - ("ctor".to_string(), ctor), - ] - .into(), - ), - diagnostics, - ) - } -} + stable_ptr: struct_ast.name(db).stable_ptr().untyped(), + severity: Severity::Error, + }); + } -/// Generates code to emit an event for a field -fn append_field(member_kind: EventFieldKind, field: RewriteNode) -> RewriteNode { - match member_kind { - EventFieldKind::Nested | EventFieldKind::Flat => RewriteNode::interpolate_patched( - &format!( - " - {EVENT_TRAIT}::append_keys_and_data( - $field$, ref keys, ref data - );" - ), - &[("field".to_string(), field)].into(), - ), - EventFieldKind::KeySerde => RewriteNode::interpolate_patched( - " - core::serde::Serde::serialize($field$, ref keys);", - &[("field".to_string(), field)].into(), - ), - EventFieldKind::DataSerde => RewriteNode::interpolate_patched( - " - core::serde::Serde::serialize($field$, ref data);", - &[("field".to_string(), field)].into(), - ), - } -} + if !derive_attr_names.contains(&DOJO_INTROSPECT_DERIVE.to_string()) { + derive_attr_names.push(DOJO_INTROSPECT_DERIVE.to_string()); + } -fn deserialize_field(member_kind: EventFieldKind, member_name: RewriteNode) -> RewriteNode { - RewriteNode::interpolate_patched( - match member_kind { - EventFieldKind::Nested | EventFieldKind::Flat => { - " - let $member_name$ = starknet::Event::deserialize( - ref keys, ref data - )?;" - } - EventFieldKind::KeySerde => { - " - let $member_name$ = core::serde::Serde::deserialize( - ref keys - )?;" - } - EventFieldKind::DataSerde => { - " - let $member_name$ = core::serde::Serde::deserialize( - ref data - )?;" - } - }, - &[("member_name".to_string(), member_name)].into(), - ) -} + let (derive_nodes, derive_diagnostics) = handle_derive_attrs( + db, + &derive_attr_names, + &ModuleItem::Struct(struct_ast.clone()), + ); -/// Retrieves the field kind for a given enum variant, -/// indicating how the field should be serialized. -/// See [EventFieldKind]. -fn get_field_kind_for_member( - db: &dyn SyntaxGroup, - diagnostics: &mut Vec, - member: &ast::Member, - default: EventFieldKind, -) -> EventFieldKind { - let is_nested = member.has_attr(db, NESTED_ATTR); - let is_key = member.has_attr(db, KEY_ATTR); - let is_serde = member.has_attr(db, SERDE_ATTR); - - // Currently, nested fields are unsupported. - if is_nested { - diagnostics.push(PluginDiagnostic::error( - member.stable_ptr().untyped(), - "Nested event fields are currently unsupported".to_string(), - )); - } - // Currently, serde fields are unsupported. - if is_serde { - diagnostics.push(PluginDiagnostic::error( - member.stable_ptr().untyped(), - "Serde event fields are currently unsupported".to_string(), - )); + diagnostics.extend(derive_diagnostics); + + let node = RewriteNode::interpolate_patched( + EVENT_PATCH, + &UnorderedHashMap::from([ + ( + "contract_name".to_string(), + RewriteNode::Text(event_name.to_case(Case::Snake)), + ), + ( + "type_name".to_string(), + RewriteNode::Text(event_name.clone()), + ), + ( + "member_names".to_string(), + RewriteNode::new_modified(member_names), + ), + ( + "serialized_keys".to_string(), + RewriteNode::new_modified(serialized_keys), + ), + ( + "serialized_values".to_string(), + RewriteNode::new_modified(serialized_values), + ), + ("event_tag".to_string(), RewriteNode::Text(event_tag)), + ( + "event_version".to_string(), + RewriteNode::Text(event_version), + ), + ( + "event_historical".to_string(), + RewriteNode::Text(event_historical), + ), + ( + "event_selector".to_string(), + RewriteNode::Text(event_selector), + ), + ( + "event_namespace".to_string(), + RewriteNode::Text(event_namespace.clone()), + ), + ( + "event_name_hash".to_string(), + RewriteNode::Text(event_name_hash.to_string()), + ), + ( + "event_namespace_hash".to_string(), + RewriteNode::Text(event_namespace_hash.to_string()), + ), + ]), + ); + + let mut builder = PatchBuilder::new(db, &struct_ast); + + for node in derive_nodes { + builder.add_modified(node); + } + + builder.add_modified(node); + + let (code, code_mappings) = builder.build(); + + let aux_data = EventAuxData { + name: event_name.clone(), + namespace: event_namespace.clone(), + members, + }; + + PluginResult { + code: Some(PluginGeneratedFile { + name: event_name.into(), + content: code, + aux_data: Some(DynGeneratedFileAuxData::new(aux_data)), + code_mappings, + }), + diagnostics, + remove_original_item: false, + } } +} - if is_key { - return EventFieldKind::KeySerde; +/// Get the historical boolean parameter from the `Expr` parameter. +fn get_historical( + attribute_name: &String, + arg_value: Expr, + diagnostics: &mut Vec, +) -> bool { + match arg_value { + Expr::True(_) => true, + Expr::False(_) => false, + _ => { + diagnostics.push(PluginDiagnostic { + message: format!( + "The argument '{PARAMETER_HISTORICAL}' of {attribute_name} must be a boolean", + ), + stable_ptr: arg_value.stable_ptr().untyped(), + severity: Severity::Error, + }); + DEFAULT_HISTORICAL_VALUE + } } - default } diff --git a/crates/compiler/src/plugin/attribute_macros/mod.rs b/crates/compiler/src/plugin/attribute_macros/mod.rs index b46aab4..e667419 100644 --- a/crates/compiler/src/plugin/attribute_macros/mod.rs +++ b/crates/compiler/src/plugin/attribute_macros/mod.rs @@ -3,12 +3,14 @@ //! An attribute macros is a macro that is used to generate code generally for a struct, enum, module or trait. pub mod contract; -// pub mod event; +pub mod element; +pub mod event; pub mod interface; pub mod model; pub mod patches; pub use contract::DojoContract; +pub use event::DojoEvent; pub use interface::DojoInterface; pub use model::DojoModel; diff --git a/crates/compiler/src/plugin/attribute_macros/model.rs b/crates/compiler/src/plugin/attribute_macros/model.rs index 1e4be32..fb046fc 100644 --- a/crates/compiler/src/plugin/attribute_macros/model.rs +++ b/crates/compiler/src/plugin/attribute_macros/model.rs @@ -1,18 +1,14 @@ //! Handle the `dojo::model` attribute macro. -use std::collections::HashMap; - use cairo_lang_defs::patcher::{PatchBuilder, RewriteNode}; use cairo_lang_defs::plugin::{ DynGeneratedFileAuxData, PluginDiagnostic, PluginGeneratedFile, PluginResult, }; use cairo_lang_diagnostics::Severity; -use cairo_lang_syntax::node::ast::{ - ArgClause, Expr, ItemStruct, Member as MemberAst, ModuleItem, OptionArgListParenthesized, -}; +use cairo_lang_syntax::node::ast::{ItemStruct, ModuleItem}; use cairo_lang_syntax::node::db::SyntaxGroup; use cairo_lang_syntax::node::helpers::QueryAttrs; -use cairo_lang_syntax::node::{Terminal, TypedStablePtr, TypedSyntaxNode}; +use cairo_lang_syntax::node::{TypedStablePtr, TypedSyntaxNode}; use cairo_lang_utils::unordered_hash_map::UnorderedHashMap; use convert_case::{Case, Casing}; use dojo_types::naming; @@ -25,197 +21,18 @@ use crate::plugin::derive_macros::{ extract_derive_attr_names, handle_derive_attrs, DOJO_INTROSPECT_DERIVE, DOJO_PACKED_DERIVE, }; +use super::element::{ + compute_namespace, deserialize_keys_and_values, parse_members, serialize_keys_and_values, + serialize_member_ty, CommonStructParameters, StructParameterParser, DEFAULT_VERSION, +}; use super::patches::MODEL_PATCH; use super::DOJO_MODEL_ATTR; -const DEFAULT_MODEL_VERSION: u8 = 1; - -const MODEL_VERSION_NAME: &str = "version"; -const MODEL_NAMESPACE: &str = "namespace"; -const MODEL_NOMAPPING: &str = "nomapping"; +type ModelParameters = CommonStructParameters; #[derive(Debug, Clone, Default)] pub struct DojoModel {} -struct ModelParameters { - version: u8, - namespace: Option, - nomapping: bool, -} - -impl Default for ModelParameters { - fn default() -> ModelParameters { - ModelParameters { - version: DEFAULT_MODEL_VERSION, - namespace: Option::None, - nomapping: false, - } - } -} - -/// Get the model version from the `Expr` parameter. -fn get_model_version( - db: &dyn SyntaxGroup, - arg_value: Expr, - diagnostics: &mut Vec, -) -> u8 { - match arg_value { - Expr::Literal(ref value) => { - if let Ok(value) = value.text(db).parse::() { - if value <= DEFAULT_MODEL_VERSION { - value - } else { - diagnostics.push(PluginDiagnostic { - message: format!("dojo::model version {} not supported", value), - stable_ptr: arg_value.stable_ptr().untyped(), - severity: Severity::Error, - }); - DEFAULT_MODEL_VERSION - } - } else { - diagnostics.push(PluginDiagnostic { - message: format!( - "The argument '{}' of dojo::model must be an integer", - MODEL_VERSION_NAME - ), - stable_ptr: arg_value.stable_ptr().untyped(), - severity: Severity::Error, - }); - DEFAULT_MODEL_VERSION - } - } - _ => { - diagnostics.push(PluginDiagnostic { - message: format!( - "The argument '{}' of dojo::model must be an integer", - MODEL_VERSION_NAME - ), - stable_ptr: arg_value.stable_ptr().untyped(), - severity: Severity::Error, - }); - DEFAULT_MODEL_VERSION - } - } -} - -/// Get the model namespace from the `Expr` parameter. -fn get_model_namespace( - db: &dyn SyntaxGroup, - arg_value: Expr, - diagnostics: &mut Vec, -) -> Option { - match arg_value { - Expr::ShortString(ss) => Some(ss.string_value(db).unwrap()), - Expr::String(s) => Some(s.string_value(db).unwrap()), - _ => { - diagnostics.push(PluginDiagnostic { - message: format!( - "The argument '{}' of dojo::model must be a string", - MODEL_NAMESPACE - ), - stable_ptr: arg_value.stable_ptr().untyped(), - severity: Severity::Error, - }); - Option::None - } - } -} - -/// Get parameters of the dojo::model attribute. -/// -/// Note: dojo::model attribute has already been checked so there is one and only one attribute. -/// -/// Parameters: -/// * db: The semantic database. -/// * struct_ast: The AST of the model struct. -/// * diagnostics: vector of compiler diagnostics. -/// -/// Returns: -/// * A [`ModelParameters`] object containing all the dojo::model parameters with their default -/// values if not set in the code. -fn get_model_parameters( - db: &dyn SyntaxGroup, - struct_ast: ItemStruct, - diagnostics: &mut Vec, -) -> ModelParameters { - let mut parameters = ModelParameters::default(); - let mut processed_args: HashMap = HashMap::new(); - - if let OptionArgListParenthesized::ArgListParenthesized(arguments) = struct_ast - .attributes(db) - .query_attr(db, DOJO_MODEL_ATTR) - .first() - .unwrap() - .arguments(db) - { - arguments - .arguments(db) - .elements(db) - .iter() - .for_each(|a| match a.arg_clause(db) { - ArgClause::Named(x) => { - let arg_name = x.name(db).text(db).to_string(); - let arg_value = x.value(db); - - if processed_args.contains_key(&arg_name) { - diagnostics.push(PluginDiagnostic { - message: format!("Too many '{}' attributes for dojo::model", arg_name), - stable_ptr: struct_ast.stable_ptr().untyped(), - severity: Severity::Error, - }); - } else { - processed_args.insert(arg_name.clone(), true); - - match arg_name.as_str() { - MODEL_VERSION_NAME => { - parameters.version = get_model_version(db, arg_value, diagnostics); - } - MODEL_NAMESPACE => { - parameters.namespace = - get_model_namespace(db, arg_value, diagnostics); - } - MODEL_NOMAPPING => { - parameters.nomapping = true; - } - _ => { - diagnostics.push(PluginDiagnostic { - message: format!( - "Unexpected argument '{}' for dojo::model", - arg_name - ), - stable_ptr: x.stable_ptr().untyped(), - severity: Severity::Warning, - }); - } - } - } - } - ArgClause::Unnamed(x) => { - diagnostics.push(PluginDiagnostic { - message: format!( - "Unexpected argument '{}' for dojo::model", - x.as_syntax_node().get_text(db) - ), - stable_ptr: x.stable_ptr().untyped(), - severity: Severity::Warning, - }); - } - ArgClause::FieldInitShorthand(x) => { - diagnostics.push(PluginDiagnostic { - message: format!( - "Unexpected argument '{}' for dojo::model", - x.name(db).name(db).text(db).to_string() - ), - stable_ptr: x.stable_ptr().untyped(), - severity: Severity::Warning, - }); - } - }) - } - - parameters -} - impl DojoModel { /// A handler for Dojo code that modifies a model struct. /// Parameters: @@ -230,8 +47,14 @@ impl DojoModel { namespace_config: &NamespaceConfig, ) -> PluginResult { let mut diagnostics = vec![]; + let mut parameters = ModelParameters::default(); - let parameters = get_model_parameters(db, struct_ast.clone(), &mut diagnostics); + parameters.from_struct( + db, + &DOJO_MODEL_ATTR.to_string(), + struct_ast.clone(), + &mut diagnostics, + ); let model_name = struct_ast .name(db) @@ -240,16 +63,7 @@ impl DojoModel { .trim() .to_string(); - let unmapped_namespace = parameters - .namespace - .unwrap_or(namespace_config.default.clone()); - - let model_namespace = if parameters.nomapping { - unmapped_namespace - } else { - // Maps namespace from the tag to ensure higher precision on matching namespace mappings. - namespace_config.get_mapping(&naming::get_tag(&unmapped_namespace, &model_name)) - }; + let model_namespace = compute_namespace(&model_name, ¶meters, namespace_config); for (id, value) in [("name", &model_name), ("namespace", &model_namespace)] { if !NamespaceConfig::is_name_valid(value) { @@ -278,7 +92,7 @@ impl DojoModel { RewriteNode::Text(format!("\"{model_name}\"")), ), _ => ( - RewriteNode::Text(DEFAULT_MODEL_VERSION.to_string()), + RewriteNode::Text(DEFAULT_VERSION.to_string()), RewriteNode::Text( naming::compute_selector_from_hashes(model_namespace_hash, model_name_hash) .to_string(), @@ -286,46 +100,64 @@ impl DojoModel { ), }; - let mut members: Vec = vec![]; + let members = parse_members(db, &struct_ast.members(db).elements(db), &mut diagnostics); + let mut serialized_keys: Vec = vec![]; + let mut serialized_values: Vec = vec![]; + + serialize_keys_and_values(&members, &mut serialized_keys, &mut serialized_values); + + if serialized_keys.is_empty() { + diagnostics.push(PluginDiagnostic { + message: "Model must define at least one #[key] attribute".into(), + stable_ptr: struct_ast.name(db).stable_ptr().untyped(), + severity: Severity::Error, + }); + } + + if serialized_values.is_empty() { + diagnostics.push(PluginDiagnostic { + message: "Model must define at least one member that is not a key".into(), + stable_ptr: struct_ast.name(db).stable_ptr().untyped(), + severity: Severity::Error, + }); + } + + let mut deserialized_keys: Vec = vec![]; + let mut deserialized_values: Vec = vec![]; + + deserialize_keys_and_values( + &members, + "keys", + &mut deserialized_keys, + "values", + &mut deserialized_values, + ); + + let mut member_key_names: Vec = vec![]; + let mut member_value_names: Vec = vec![]; let mut members_values: Vec = vec![]; let mut param_keys: Vec = vec![]; - let mut serialized_keys: Vec = vec![]; let mut serialized_param_keys: Vec = vec![]; - let mut serialized_values: Vec = vec![]; - let mut field_accessors: Vec = vec![]; - let mut entity_field_accessors: Vec = vec![]; - let elements = struct_ast.members(db).elements(db); - - elements.iter().for_each(|member_ast| { - let member = Member { - name: member_ast.name(db).text(db).to_string(), - ty: member_ast - .type_clause(db) - .ty(db) - .as_syntax_node() - .get_text(db) - .trim() - .to_string(), - key: member_ast.has_attr(db, "key"), - }; + members.iter().for_each(|member| { if member.key { - validate_key_member(&member, db, member_ast, &mut diagnostics); - serialized_keys.push(serialize_member_ty(&member, true)); - serialized_param_keys.push(serialize_member_ty(&member, false)); param_keys.push(format!("{}: {}", member.name, member.ty)); + serialized_param_keys.push(serialize_member_ty(member, false)); + member_key_names.push(RewriteNode::Text(format!("{},\n", member.name.clone()))); } else { - serialized_values.push(serialize_member_ty(&member, true)); members_values.push(RewriteNode::Text(format!( "pub {}: {},\n", member.name, member.ty ))); + member_value_names.push(RewriteNode::Text(format!("{},\n", member.name.clone()))); } - - members.push(member); }); + let param_keys = param_keys.join(", "); + let mut field_accessors: Vec = vec![]; + let mut entity_field_accessors: Vec = vec![]; + members.iter().filter(|m| !m.key).for_each(|member| { field_accessors.push(generate_field_accessors( model_name.clone(), @@ -337,22 +169,6 @@ impl DojoModel { .push(generate_entity_field_accessors(model_name.clone(), member)); }); - if serialized_keys.is_empty() { - diagnostics.push(PluginDiagnostic { - message: "Model must define at least one #[key] attribute".into(), - stable_ptr: struct_ast.name(db).stable_ptr().untyped(), - severity: Severity::Error, - }); - } - - if serialized_values.is_empty() { - diagnostics.push(PluginDiagnostic { - message: "Model must define at least one member that is not a key".into(), - stable_ptr: struct_ast.name(db).stable_ptr().untyped(), - severity: Severity::Error, - }); - } - let mut derive_attr_names = extract_derive_attr_names( db, &mut diagnostics, @@ -387,8 +203,12 @@ impl DojoModel { RewriteNode::Text(model_name.clone()), ), ( - "namespace".to_string(), - RewriteNode::Text("namespace".to_string()), + "member_key_names".to_string(), + RewriteNode::new_modified(member_key_names), + ), + ( + "member_value_names".to_string(), + RewriteNode::new_modified(member_value_names), ), ( "serialized_keys".to_string(), @@ -398,6 +218,14 @@ impl DojoModel { "serialized_values".to_string(), RewriteNode::new_modified(serialized_values), ), + ( + "deserialized_keys".to_string(), + RewriteNode::new_modified(deserialized_keys), + ), + ( + "deserialized_values".to_string(), + RewriteNode::new_modified(deserialized_values), + ), ("model_version".to_string(), model_version), ("model_selector".to_string(), model_selector), ( @@ -465,48 +293,6 @@ impl DojoModel { } } -/// Validates that the key member is valid. -/// # Arguments -/// -/// * member: The member to validate. -/// * diagnostics: The diagnostics to push to, if the member is an invalid key. -fn validate_key_member( - member: &Member, - db: &dyn SyntaxGroup, - member_ast: &MemberAst, - diagnostics: &mut Vec, -) { - if member.ty == "u256" { - diagnostics.push(PluginDiagnostic { - message: "Key is only supported for core types that are 1 felt long once serialized. \ - `u256` is a struct of 2 u128, hence not supported." - .into(), - stable_ptr: member_ast.name(db).stable_ptr().untyped(), - severity: Severity::Error, - }); - } -} - -/// Creates a [`RewriteNode`] for the member type serialization. -/// -/// # Arguments -/// -/// * member: The member to serialize. -fn serialize_member_ty(member: &Member, with_self: bool) -> RewriteNode { - match member.ty.as_str() { - "felt252" => RewriteNode::Text(format!( - "core::array::ArrayTrait::append(ref serialized, {}{});\n", - if with_self { "*self." } else { "" }, - member.name - )), - _ => RewriteNode::Text(format!( - "core::serde::Serde::serialize({}{}, ref serialized);\n", - if with_self { "self." } else { "@" }, - member.name - )), - } -} - /// Generates field accessors (`get_[field_name]` and `set_[field_name]`) for every /// fields of a model. /// diff --git a/crates/compiler/src/plugin/attribute_macros/patches.rs b/crates/compiler/src/plugin/attribute_macros/patches.rs index 3370d43..15b31d4 100644 --- a/crates/compiler/src/plugin/attribute_macros/patches.rs +++ b/crates/compiler/src/plugin/attribute_macros/patches.rs @@ -109,22 +109,16 @@ pub impl $type_name$StoreImpl of $type_name$Store { core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> $type_name$ { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); - - let entity = core::serde::Serde::<$type_name$>::deserialize(ref serialized); - - if core::option::OptionTrait::<$type_name$>::is_none(@entity) { - panic!( - \"Model `$type_name$`: deserialization failed. Ensure the length of the keys tuple \ - is matching the number of #[key] fields in the model struct.\" - ); - } + fn from_values(ref keys: Span, ref values: Span) -> Option<$type_name$> { + $deserialized_keys$ + $deserialized_values$ - core::option::OptionTrait::<$type_name$>::unwrap(entity) + Option::Some( + $type_name$ { + $member_key_names$ + $member_value_names$ + } + ) } fn get(world: dojo::world::IWorldDispatcher, $param_keys$) -> $type_name$ { @@ -156,18 +150,15 @@ pub impl $type_name$ModelEntityImpl of dojo::model::ModelEntity<$type_name$Entit core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> $type_name$Entity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option<$type_name$Entity> { + $deserialized_values$ - let entity_values = core::serde::Serde::<$type_name$Entity>::deserialize(ref serialized); - if core::option::OptionTrait::<$type_name$Entity>::is_none(@entity_values) { - panic!( - \"ModelEntity `$type_name$Entity`: deserialization failed.\" - ); - } - core::option::OptionTrait::<$type_name$Entity>::unwrap(entity_values) + Option::Some( + $type_name$Entity { + __id: entity_id, + $member_value_names$ + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> $type_name$Entity { @@ -177,7 +168,12 @@ pub impl $type_name$ModelEntityImpl of dojo::model::ModelEntity<$type_name$Entit dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::<$type_name$>::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!(\"ModelEntity `$type_name$Entity`: deserialization failed.\") + } + } } fn update_entity(self: @$type_name$Entity, world: dojo::world::IWorldDispatcher) { @@ -278,7 +274,12 @@ pub impl $type_name$ModelImpl of dojo::model::Model<$type_name$> { ); let mut _keys = keys; - $type_name$Store::from_values(ref _keys, ref values) + match $type_name$Store::from_values(ref _keys, ref values) { + Option::Some(x) => x, + Option::None => { + panic!(\"Model `$type_name$`: deserialization failed.\") + } + } } fn set_model( @@ -405,18 +406,18 @@ pub impl $type_name$ModelImpl of dojo::model::Model<$type_name$> { } #[inline(always)] - fn layout() -> dojo::model::Layout { - dojo::model::introspect::Introspect::<$type_name$>::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::<$type_name$>::layout() } #[inline(always)] - fn instance_layout(self: @$type_name$) -> dojo::model::Layout { + fn instance_layout(self: @$type_name$) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -498,19 +499,19 @@ pub mod $contract_name$ { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::<$type_name$>::size() + dojo::meta::introspect::Introspect::<$type_name$>::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::<$type_name$>::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::<$type_name$>::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::<$type_name$>::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::<$type_name$>::ty() } } @@ -521,3 +522,152 @@ pub mod $contract_name$ { } } "; + +pub const EVENT_PATCH: &str = " +pub impl $type_name$EventImpl of dojo::event::Event<$type_name$> { + + fn emit(self: @$type_name$, world: dojo::world::IWorldDispatcher) { + dojo::world::IWorldDispatcherTrait::emit( + world, + Self::selector(), + Self::keys(self), + Self::values(self), + Self::historical() + ); + } + + #[inline(always)] + fn name() -> ByteArray { + \"$type_name$\" + } + + #[inline(always)] + fn namespace() -> ByteArray { + \"$event_namespace$\" + } + + #[inline(always)] + fn tag() -> ByteArray { + \"$event_tag$\" + } + + #[inline(always)] + fn version() -> u8 { + $event_version$ + } + + #[inline(always)] + fn selector() -> felt252 { + $event_selector$ + } + + #[inline(always)] + fn instance_selector(self: @$type_name$) -> felt252 { + Self::selector() + } + + #[inline(always)] + fn name_hash() -> felt252 { + $event_name_hash$ + } + + #[inline(always)] + fn namespace_hash() -> felt252 { + $event_namespace_hash$ + } + + #[inline(always)] + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::<$type_name$>::layout() + } + + #[inline(always)] + fn packed_size() -> Option { + dojo::meta::layout::compute_packed_size(Self::layout()) + } + + #[inline(always)] + fn unpacked_size() -> Option { + dojo::meta::introspect::Introspect::<$type_name$>::size() + } + + #[inline(always)] + fn schema(self: @$type_name$) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::<$type_name$>::ty() + } + + #[inline(always)] + fn historical() -> bool { + $event_historical$ + } + + #[inline(always)] + fn keys(self: @$type_name$) -> Span { + let mut serialized = core::array::ArrayTrait::new(); + $serialized_keys$ + core::array::ArrayTrait::span(@serialized) + } + + #[inline(always)] + fn values(self: @$type_name$) -> Span { + let mut serialized = core::array::ArrayTrait::new(); + $serialized_values$ + core::array::ArrayTrait::span(@serialized) + } +} + +#[starknet::contract] +pub mod $contract_name$ { + use super::$type_name$; + + #[storage] + struct Storage {} + + #[abi(embed_v0)] + impl DojoEventImpl of dojo::event::IEvent{ + fn name(self: @ContractState) -> ByteArray { + \"$type_name$\" + } + + fn namespace(self: @ContractState) -> ByteArray { + \"$event_namespace$\" + } + + fn tag(self: @ContractState) -> ByteArray { + \"$event_tag$\" + } + + fn version(self: @ContractState) -> u8 { + $event_version$ + } + + fn selector(self: @ContractState) -> felt252 { + $event_selector$ + } + + fn name_hash(self: @ContractState) -> felt252 { + $event_name_hash$ + } + + fn namespace_hash(self: @ContractState) -> felt252 { + $event_namespace_hash$ + } + + fn unpacked_size(self: @ContractState) -> Option { + dojo::meta::introspect::Introspect::<$type_name$>::size() + } + + fn packed_size(self: @ContractState) -> Option { + dojo::event::Event::<$type_name$>::packed_size() + } + + fn layout(self: @ContractState) -> dojo::meta::Layout { + dojo::event::Event::<$type_name$>::layout() + } + + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::<$type_name$>::ty() + } + } +} +"; diff --git a/crates/compiler/src/plugin/derive_macros/introspect/layout.rs b/crates/compiler/src/plugin/derive_macros/introspect/layout.rs index d9238e4..de6623a 100644 --- a/crates/compiler/src/plugin/derive_macros/introspect/layout.rs +++ b/crates/compiler/src/plugin/derive_macros/introspect/layout.rs @@ -30,7 +30,7 @@ pub fn build_field_layouts( let field_selector = get_selector_from_name(&field_name.to_string()).unwrap(); let field_layout = get_layout_from_type_clause(db, diagnostics, &m.type_clause(db)); Some(format!( - "dojo::model::FieldLayout {{ + "dojo::meta::FieldLayout {{ selector: {field_selector}, layout: {field_layout} }}" @@ -57,7 +57,7 @@ pub fn build_variant_layouts( let variant_layout = match v.type_clause(db) { OptionTypeClause::Empty(_) => { - "dojo::model::Layout::Fixed(array![].span())".to_string() + "dojo::meta::Layout::Fixed(array![].span())".to_string() } OptionTypeClause::TypeClause(type_clause) => { get_layout_from_type_clause(db, diagnostics, &type_clause) @@ -65,7 +65,7 @@ pub fn build_variant_layouts( }; format!( - "dojo::model::FieldLayout {{ + "dojo::meta::FieldLayout {{ selector: {selector}, layout: {variant_layout} }}" @@ -112,7 +112,7 @@ pub fn build_array_layout_from_type( if is_tuple(&array_item_type) { format!( - "dojo::model::Layout::Array( + "dojo::meta::Layout::Array( array![ {} ].span() @@ -121,7 +121,7 @@ pub fn build_array_layout_from_type( ) } else if is_array(&array_item_type) { format!( - "dojo::model::Layout::Array( + "dojo::meta::Layout::Array( array![ {} ].span() @@ -130,7 +130,7 @@ pub fn build_array_layout_from_type( ) } else { format!( - "dojo::model::introspect::Introspect::<{}>::layout()", + "dojo::meta::introspect::Introspect::<{}>::layout()", item_type ) } @@ -149,7 +149,7 @@ pub fn build_tuple_layout_from_type( .collect::>() .join(",\n"); format!( - "dojo::model::Layout::Tuple( + "dojo::meta::Layout::Tuple( array![ {} ].span() @@ -180,14 +180,14 @@ pub fn build_item_layout_from_type( } format!( - "dojo::model::introspect::Introspect::<{}>::layout()", + "dojo::meta::introspect::Introspect::<{}>::layout()", item_type ) } } pub fn is_custom_layout(layout: &str) -> bool { - layout.starts_with("dojo::model::introspect::Introspect::") + layout.starts_with("dojo::meta::introspect::Introspect::") } pub fn build_packed_struct_layout( @@ -217,7 +217,7 @@ pub fn build_packed_struct_layout( generate_cairo_code_for_fixed_layout_with_custom_types(&layouts) } else { format!( - "dojo::model::Layout::Fixed( + "dojo::meta::Layout::Fixed( array![ {} ].span() @@ -234,7 +234,7 @@ pub fn generate_cairo_code_for_fixed_layout_with_custom_types(layouts: &[String] if is_custom_layout(l) { l.to_string() } else { - format!("dojo::model::Layout::Fixed(array![{l}].span())") + format!("dojo::meta::Layout::Fixed(array![{l}].span())") } }) .collect::>() @@ -250,7 +250,7 @@ pub fn generate_cairo_code_for_fixed_layout_with_custom_types(layouts: &[String] match ArrayTrait::pop_front(ref layouts) {{ Option::Some(mut layout) => {{ match layout {{ - dojo::model::Layout::Fixed(mut l) => {{ + dojo::meta::Layout::Fixed(mut l) => {{ loop {{ match SpanTrait::pop_front(ref l) {{ Option::Some(x) => merged_layout.append(*x), @@ -265,7 +265,7 @@ pub fn generate_cairo_code_for_fixed_layout_with_custom_types(layouts: &[String] }}; }}; - dojo::model::Layout::Fixed(merged_layout.span()) + dojo::meta::Layout::Fixed(merged_layout.span()) ", ) } @@ -298,7 +298,7 @@ pub fn build_packed_enum_layout( generate_cairo_code_for_fixed_layout_with_custom_types(&variant_layout) } else { format!( - "dojo::model::Layout::Fixed( + "dojo::meta::Layout::Fixed( array![ {} ].span() @@ -368,7 +368,7 @@ pub fn get_packed_item_layout_from_type( // we suppose it is and let the user verify this. // If it's not the case, the Dojo model layout function will panic. vec![format!( - "dojo::model::introspect::Introspect::<{}>::layout()", + "dojo::meta::introspect::Introspect::<{}>::layout()", item_type )] } diff --git a/crates/compiler/src/plugin/derive_macros/introspect/mod.rs b/crates/compiler/src/plugin/derive_macros/introspect/mod.rs index f18e04e..cc58c7e 100644 --- a/crates/compiler/src/plugin/derive_macros/introspect/mod.rs +++ b/crates/compiler/src/plugin/derive_macros/introspect/mod.rs @@ -28,7 +28,7 @@ pub fn handle_introspect_struct( layout::build_packed_struct_layout(db, diagnostics, &struct_ast) } else { format!( - "dojo::model::Layout::Struct( + "dojo::meta::Layout::Struct( array![ {} ].span() @@ -73,7 +73,7 @@ pub fn handle_introspect_enum( } } else { format!( - "dojo::model::Layout::Enum( + "dojo::meta::Layout::Enum( array![ {} ].span() @@ -101,19 +101,19 @@ fn generate_introspect( ) -> RewriteNode { RewriteNode::interpolate_patched( " -impl $name$Introspect<$generics$> of dojo::model::introspect::Introspect<$name$<$generics_types$>> \ +impl $name$Introspect<$generics$> of dojo::meta::introspect::Introspect<$name$<$generics_types$>> \ { #[inline(always)] fn size() -> Option { $size$ } - fn layout() -> dojo::model::Layout { + fn layout() -> dojo::meta::Layout { $layout$ } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { + fn ty() -> dojo::meta::introspect::Ty { $ty$ } } @@ -158,7 +158,7 @@ fn build_generic_types_and_impls( let generic_impls = generic_types .iter() - .map(|g| format!("{g}, impl {g}Introspect: dojo::model::introspect::Introspect<{g}>")) + .map(|g| format!("{g}, impl {g}Introspect: dojo::meta::introspect::Introspect<{g}>")) .collect::>() .join(", "); diff --git a/crates/compiler/src/plugin/derive_macros/introspect/size.rs b/crates/compiler/src/plugin/derive_macros/introspect/size.rs index 3fe9c5c..8091ed7 100644 --- a/crates/compiler/src/plugin/derive_macros/introspect/size.rs +++ b/crates/compiler/src/plugin/derive_macros/introspect/size.rs @@ -189,7 +189,7 @@ pub fn compute_item_size_from_type(item_type: &String) -> Vec { vec![p.0.to_string()] } else { vec![format!( - "dojo::model::introspect::Introspect::<{}>::size()", + "dojo::meta::introspect::Introspect::<{}>::size()", item_type )] } diff --git a/crates/compiler/src/plugin/derive_macros/introspect/ty.rs b/crates/compiler/src/plugin/derive_macros/introspect/ty.rs index adefa6d..73ddbd8 100644 --- a/crates/compiler/src/plugin/derive_macros/introspect/ty.rs +++ b/crates/compiler/src/plugin/derive_macros/introspect/ty.rs @@ -16,8 +16,8 @@ pub fn build_struct_ty(db: &dyn SyntaxGroup, name: &String, struct_ast: &ItemStr .collect::>(); format!( - "dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct {{ + "dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct {{ name: '{name}', attrs: array![].span(), children: array![ @@ -43,8 +43,8 @@ pub fn build_enum_ty(db: &dyn SyntaxGroup, name: &String, enum_ast: &ItemEnum) - }; format!( - "dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum {{ + "dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum {{ name: '{name}', attrs: array![].span(), children: array![ @@ -64,7 +64,7 @@ pub fn build_member_ty(db: &dyn SyntaxGroup, member: &Member) -> String { }; format!( - "dojo::model::introspect::Member {{ + "dojo::meta::introspect::Member {{ name: '{name}', attrs: array![{}].span(), ty: {} @@ -79,7 +79,7 @@ pub fn build_variant_ty(db: &dyn SyntaxGroup, variant: &Variant) -> String { match variant.type_clause(db) { OptionTypeClause::Empty(_) => { // use an empty tuple if the variant has no data - format!("('{name}', dojo::model::introspect::Ty::Tuple(array![].span()))") + format!("('{name}', dojo::meta::introspect::Ty::Tuple(array![].span()))") } OptionTypeClause::TypeClause(type_clause) => { format!( @@ -111,7 +111,7 @@ pub fn build_item_ty_from_type(item_type: &String) -> String { if is_array(item_type) { let array_item_type = get_array_item_type(item_type); format!( - "dojo::model::introspect::Ty::Array( + "dojo::meta::introspect::Ty::Array( array![ {} ].span() @@ -119,11 +119,11 @@ pub fn build_item_ty_from_type(item_type: &String) -> String { build_item_ty_from_type(&array_item_type) ) } else if is_byte_array(item_type) { - "dojo::model::introspect::Ty::ByteArray".to_string() + "dojo::meta::introspect::Ty::ByteArray".to_string() } else if is_tuple(item_type) { build_tuple_ty_from_type(item_type) } else { - format!("dojo::model::introspect::Introspect::<{}>::ty()", item_type) + format!("dojo::meta::introspect::Introspect::<{}>::ty()", item_type) } } @@ -134,7 +134,7 @@ pub fn build_tuple_ty_from_type(item_type: &str) -> String { .collect::>() .join(",\n"); format!( - "dojo::model::introspect::Ty::Tuple( + "dojo::meta::introspect::Ty::Tuple( array![ {} ].span() diff --git a/crates/compiler/src/plugin/inline_macros/emit.rs b/crates/compiler/src/plugin/inline_macros/emit.rs index 630f7ee..dee85f0 100644 --- a/crates/compiler/src/plugin/inline_macros/emit.rs +++ b/crates/compiler/src/plugin/inline_macros/emit.rs @@ -5,7 +5,6 @@ use cairo_lang_defs::plugin::{ }; use cairo_lang_defs::plugin_utils::unsupported_bracket_diagnostic; use cairo_lang_diagnostics::Severity; -use cairo_lang_starknet::plugin::consts::EVENT_TRAIT; use cairo_lang_syntax::node::{ast, TypedStablePtr, TypedSyntaxNode}; use super::unsupported_arg_diagnostic; @@ -54,7 +53,7 @@ impl InlineMacroExprPlugin for EmitMacro { match models.value(db) { ast::Expr::Parenthesized(parens) => { let syntax_node = parens.expr(db).as_syntax_node(); - bundle.push((syntax_node.get_text(db), syntax_node)); + bundle.push(syntax_node.get_text(db)); } ast::Expr::Tuple(list) => { list.expressions(db) @@ -62,12 +61,12 @@ impl InlineMacroExprPlugin for EmitMacro { .into_iter() .for_each(|expr| { let syntax_node = expr.as_syntax_node(); - bundle.push((syntax_node.get_text(db), syntax_node)); + bundle.push(syntax_node.get_text(db)); }) } ast::Expr::StructCtorCall(ctor) => { let syntax_node = ctor.as_syntax_node(); - bundle.push((syntax_node.get_text(db), syntax_node)); + bundle.push(syntax_node.get_text(db)); } _ => { return InlinePluginResult { @@ -92,26 +91,15 @@ impl InlineMacroExprPlugin for EmitMacro { }; } - for (event, _) in bundle { - builder.add_str("{"); - - builder.add_str( - " - let mut keys = Default::::default(); - let mut data = Default::::default();", - ); - + for event in bundle { builder.add_str(&format!( " - {EVENT_TRAIT}::append_keys_and_data(@{event}, ref keys, ref data);", - event = event + let __event_instance__ = {}; + dojo::event::Event::emit(@__event_instance__, {}); + ", + event, + world.as_syntax_node().get_text(db), )); - - builder.add_str("\n "); - builder.add_node(world.as_syntax_node()); - builder.add_str(".emit(keys, data.span());"); - - builder.add_str("}"); } builder.add_str("}"); diff --git a/crates/compiler/src/plugin/plugin.rs b/crates/compiler/src/plugin/plugin.rs index 7f8ee9d..f0e3ad1 100644 --- a/crates/compiler/src/plugin/plugin.rs +++ b/crates/compiler/src/plugin/plugin.rs @@ -15,7 +15,7 @@ use semver::Version; use url::Url; use super::attribute_macros::{ - DojoContract, DojoInterface, DojoModel, DOJO_CONTRACT_ATTR, DOJO_EVENT_ATTR, + DojoContract, DojoEvent, DojoInterface, DojoModel, DOJO_CONTRACT_ATTR, DOJO_EVENT_ATTR, DOJO_INTERFACE_ATTR, DOJO_MODEL_ATTR, }; use super::derive_macros::{dojo_derive_all, DOJO_INTROSPECT_DERIVE, DOJO_PACKED_DERIVE}; @@ -141,14 +141,7 @@ impl MacroPlugin for BuiltinDojoPlugin { } else if n_model_attrs == 1 { return DojoModel::from_struct(db, struct_ast.clone(), &namespace_config); } else if n_event_attrs == 1 { - // TODO: when event will be separated from model, we need to check for conflicts. - // The same struct can't be used for both `#[dojo::model]` and `#[dojo::event]`. - // - // Events will be reworked to be similar to models, and emitted via a World's event - // instead of using the syscall. - // - // `#[dojo::event]` for now does nothing. - return PluginResult::default(); + return DojoEvent::from_struct(db, struct_ast.clone(), &namespace_config); } // Not a model or event, but has derives. diff --git a/crates/compiler/src/plugin/plugin_test.rs b/crates/compiler/src/plugin/plugin_test.rs index e9cf528..28d049d 100644 --- a/crates/compiler/src/plugin/plugin_test.rs +++ b/crates/compiler/src/plugin/plugin_test.rs @@ -28,6 +28,7 @@ cairo_lang_test_utils::test_file_test!( "src/plugin/plugin_test_data", { model: "model", + event: "event", print: "print", introspect: "introspect", system: "system", diff --git a/crates/compiler/src/plugin/plugin_test_data/event b/crates/compiler/src/plugin/plugin_test_data/event new file mode 100644 index 0000000..2b08abd --- /dev/null +++ b/crates/compiler/src/plugin/plugin_test_data/event @@ -0,0 +1,1621 @@ +//! > Test expansion of the dojo::event. + +//! > test_runner_name +test_expand_plugin + +//! > test_id +event + +//! > cairo_code +#[derive(Drop, Serde)] +#[dojo::event] +pub struct Message { + #[key] + pub identity: ContractAddress, + #[key] + pub channel: felt252, + pub message: ByteArray, + #[key] + pub salt: felt252 +} + +#[dojo::event(namespace: 'my_namespace')] +struct MyEventWithNamespace { + #[key] + id: felt252, + name: ByteArray, +} + +#[dojo::event(historical: false)] +struct MyEventNoHistorical { + #[key] + id: felt252, + name: ByteArray, +} + +//! > expanded_cairo_code +#[derive(Drop, Serde)] +#[dojo::event] +pub struct Message { + #[key] + pub identity: ContractAddress, + #[key] + pub channel: felt252, + pub message: ByteArray, + #[key] + pub salt: felt252 +} + +#[dojo::event(namespace: 'my_namespace')] +struct MyEventWithNamespace { + #[key] + id: felt252, + name: ByteArray, +} + +#[dojo::event(historical: false)] +struct MyEventNoHistorical { + #[key] + id: felt252, + name: ByteArray, +}impl MessageDrop of core::traits::Drop::; +impl MessageSerde of core::serde::Serde:: { + fn serialize(self: @Message, ref output: core::array::Array) { + core::serde::Serde::serialize(self.identity, ref output); + core::serde::Serde::serialize(self.channel, ref output); + core::serde::Serde::serialize(self.message, ref output); + core::serde::Serde::serialize(self.salt, ref output) + } + fn deserialize(ref serialized: core::array::Span) -> core::option::Option { + core::option::Option::Some(Message { + identity: core::serde::Serde::deserialize(ref serialized)?, + channel: core::serde::Serde::deserialize(ref serialized)?, + message: core::serde::Serde::deserialize(ref serialized)?, + salt: core::serde::Serde::deserialize(ref serialized)?, + }) + } +} + +impl MessageIntrospect<> of dojo::meta::introspect::Introspect> { + #[inline(always)] + fn size() -> Option { + Option::None + } + + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( + array![ + dojo::meta::FieldLayout { + selector: 1234962429638067342109111948666382589302318509162806680039978245403372666376, + layout: dojo::meta::introspect::Introspect::::layout() + } + ].span() + ) + } + + #[inline(always)] + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { + name: 'Message', + attrs: array![].span(), + children: array![ + dojo::meta::introspect::Member { + name: 'identity', + attrs: array!['key'].span(), + ty: dojo::meta::introspect::Introspect::::ty() + }, +dojo::meta::introspect::Member { + name: 'channel', + attrs: array!['key'].span(), + ty: dojo::meta::introspect::Introspect::::ty() + }, +dojo::meta::introspect::Member { + name: 'message', + attrs: array![].span(), + ty: dojo::meta::introspect::Ty::ByteArray + }, +dojo::meta::introspect::Member { + name: 'salt', + attrs: array!['key'].span(), + ty: dojo::meta::introspect::Introspect::::ty() + } + + ].span() + } + ) + } +} + +pub impl MessageEventImpl of dojo::event::Event { + + fn emit(self: @Message, world: dojo::world::IWorldDispatcher) { + dojo::world::IWorldDispatcherTrait::emit( + world, + Self::selector(), + Self::keys(self), + Self::values(self), + Self::historical() + ); + } + + #[inline(always)] + fn name() -> ByteArray { + "Message" + } + + #[inline(always)] + fn namespace() -> ByteArray { + "dojo_test" + } + + #[inline(always)] + fn tag() -> ByteArray { + "dojo_test-Message" + } + + #[inline(always)] + fn version() -> u8 { + 1 + } + + #[inline(always)] + fn selector() -> felt252 { + 1906185680711303922822303398414928927091284519615502535643957313578662707163 + } + + #[inline(always)] + fn instance_selector(self: @Message) -> felt252 { + Self::selector() + } + + #[inline(always)] + fn name_hash() -> felt252 { + 1218932985479400212550774377351312162398071867364919833219536439613388630232 + } + + #[inline(always)] + fn namespace_hash() -> felt252 { + 1452123528942907587532668415362544424816022573043154497385993678618948064048 + } + + #[inline(always)] + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() + } + + #[inline(always)] + fn packed_size() -> Option { + dojo::meta::layout::compute_packed_size(Self::layout()) + } + + #[inline(always)] + fn unpacked_size() -> Option { + dojo::meta::introspect::Introspect::::size() + } + + #[inline(always)] + fn schema(self: @Message) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() + } + + #[inline(always)] + fn historical() -> bool { + true + } + + #[inline(always)] + fn keys(self: @Message) -> Span { + let mut serialized = core::array::ArrayTrait::new(); + core::serde::Serde::serialize(self.identity, ref serialized); +core::serde::Serde::serialize(self.channel, ref serialized); +core::serde::Serde::serialize(self.salt, ref serialized); + + core::array::ArrayTrait::span(@serialized) + } + + #[inline(always)] + fn values(self: @Message) -> Span { + let mut serialized = core::array::ArrayTrait::new(); + core::serde::Serde::serialize(self.message, ref serialized); + + core::array::ArrayTrait::span(@serialized) + } +} + +#[starknet::contract] +pub mod message { + use super::Message; + + #[abi(embed_v0)] + impl DojoEventImpl of dojo::event::IEvent{ + fn name(self: @ContractState) -> ByteArray { + "Message" + } + + fn namespace(self: @ContractState) -> ByteArray { + "dojo_test" + } + + fn tag(self: @ContractState) -> ByteArray { + "dojo_test-Message" + } + + fn version(self: @ContractState) -> u8 { + 1 + } + + fn selector(self: @ContractState) -> felt252 { + 1906185680711303922822303398414928927091284519615502535643957313578662707163 + } + + fn name_hash(self: @ContractState) -> felt252 { + 1218932985479400212550774377351312162398071867364919833219536439613388630232 + } + + fn namespace_hash(self: @ContractState) -> felt252 { + 1452123528942907587532668415362544424816022573043154497385993678618948064048 + } + + fn unpacked_size(self: @ContractState) -> Option { + dojo::meta::introspect::Introspect::::size() + } + + fn packed_size(self: @ContractState) -> Option { + dojo::event::Event::::packed_size() + } + + fn layout(self: @ContractState) -> dojo::meta::Layout { + dojo::event::Event::::layout() + } + + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() + } + } +#[event] +#[derive(Drop, starknet::Event)] +pub enum Event {} + + +#[phantom] +pub struct Storage { +} + +#[derive(Drop, Copy)] +pub struct StorageStorageBase { +} +impl StorageStorageImpl of starknet::storage::StorageTrait { + type BaseType = StorageStorageBase; + fn storage(self: starknet::storage::FlattenedStorage) -> StorageStorageBase { + StorageStorageBase { + } + } +} +#[derive(Drop, Copy)] +pub struct StorageStorageBaseMut { +} +impl StorageStorageMutImpl of starknet::storage::StorageTraitMut { + type BaseType = StorageStorageBaseMut; + fn storage_mut(self: starknet::storage::FlattenedStorage>) -> StorageStorageBaseMut { + StorageStorageBaseMut { + } + } +} + +pub struct ContractState { +} + +impl ContractStateDrop of Drop {} + +impl ContractStateDeref of core::ops::SnapshotDeref { + type Target = starknet::storage::FlattenedStorage; + fn snapshot_deref(self: @ContractState) -> starknet::storage::FlattenedStorage { + starknet::storage::FlattenedStorage {} + } +} +impl ContractStateDerefMut of core::ops::DerefMut { + type Target = starknet::storage::FlattenedStorage> ; + fn deref_mut(ref self: ContractState) -> starknet::storage::FlattenedStorage> { + starknet::storage::FlattenedStorage {} + } +} +pub fn unsafe_new_contract_state() -> ContractState { + ContractState { + } +} + +// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one. +#[deprecated( + feature: "deprecated_legacy_map", + note: "Use `starknet::storage::Map` instead." +)] +use starknet::storage::Map as LegacyMap; + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__name(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::name(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__namespace(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::namespace(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__tag(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::tag(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__version(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::version(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__selector(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::selector(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__name_hash(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::name_hash(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__namespace_hash(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::namespace_hash(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__unpacked_size(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::unpacked_size(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::>::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__packed_size(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::packed_size(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::>::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__layout(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::layout(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__schema(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::schema(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + + +pub mod __external { + pub use super::__wrapper__DojoEventImpl__name as name; + pub use super::__wrapper__DojoEventImpl__namespace as namespace; + pub use super::__wrapper__DojoEventImpl__tag as tag; + pub use super::__wrapper__DojoEventImpl__version as version; + pub use super::__wrapper__DojoEventImpl__selector as selector; + pub use super::__wrapper__DojoEventImpl__name_hash as name_hash; + pub use super::__wrapper__DojoEventImpl__namespace_hash as namespace_hash; + pub use super::__wrapper__DojoEventImpl__unpacked_size as unpacked_size; + pub use super::__wrapper__DojoEventImpl__packed_size as packed_size; + pub use super::__wrapper__DojoEventImpl__layout as layout; + pub use super::__wrapper__DojoEventImpl__schema as schema; +} +pub mod __l1_handler { +} +pub mod __constructor { +} + impl ContractStateEventEmitter of starknet::event::EventEmitter< + ContractState, Event + > { + fn emit>( + ref self: ContractState, event: S + ) { + let event: Event = core::traits::Into::into(event); + let mut keys = Default::::default(); + let mut data = Default::::default(); + starknet::Event::append_keys_and_data(@event, ref keys, ref data); + starknet::SyscallResultTrait::unwrap_syscall( + starknet::syscalls::emit_event_syscall( + core::array::ArrayTrait::span(@keys), + core::array::ArrayTrait::span(@data), + ) + ) + } + } +impl EventDrop of core::traits::Drop::; +impl EventIsEvent of starknet::Event { + fn append_keys_and_data( + self: @Event, ref keys: Array, ref data: Array + ) { + match self { + } + } + fn deserialize( + ref keys: Span, ref data: Span, + ) -> Option { + let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?; + Option::None + } +} +impl StorageStorageBaseDrop of core::traits::Drop::; +impl StorageStorageBaseCopy of core::traits::Copy::; +impl StorageStorageBaseMutDrop of core::traits::Drop::; +impl StorageStorageBaseMutCopy of core::traits::Copy::; +} + +impl MyEventWithNamespaceIntrospect<> of dojo::meta::introspect::Introspect> { + #[inline(always)] + fn size() -> Option { + Option::None + } + + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( + array![ + dojo::meta::FieldLayout { + selector: 1528802474226268325865027367859591458315299653151958663884057507666229546336, + layout: dojo::meta::introspect::Introspect::::layout() + } + ].span() + ) + } + + #[inline(always)] + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { + name: 'MyEventWithNamespace', + attrs: array![].span(), + children: array![ + dojo::meta::introspect::Member { + name: 'id', + attrs: array!['key'].span(), + ty: dojo::meta::introspect::Introspect::::ty() + }, +dojo::meta::introspect::Member { + name: 'name', + attrs: array![].span(), + ty: dojo::meta::introspect::Ty::ByteArray + } + + ].span() + } + ) + } +} + +pub impl MyEventWithNamespaceEventImpl of dojo::event::Event { + + fn emit(self: @MyEventWithNamespace, world: dojo::world::IWorldDispatcher) { + dojo::world::IWorldDispatcherTrait::emit( + world, + Self::selector(), + Self::keys(self), + Self::values(self), + Self::historical() + ); + } + + #[inline(always)] + fn name() -> ByteArray { + "MyEventWithNamespace" + } + + #[inline(always)] + fn namespace() -> ByteArray { + "dojo_test" + } + + #[inline(always)] + fn tag() -> ByteArray { + "dojo_test-MyEventWithNamespace" + } + + #[inline(always)] + fn version() -> u8 { + 1 + } + + #[inline(always)] + fn selector() -> felt252 { + 2657911819624041908110491051081365977193385901634711445959602441678296212168 + } + + #[inline(always)] + fn instance_selector(self: @MyEventWithNamespace) -> felt252 { + Self::selector() + } + + #[inline(always)] + fn name_hash() -> felt252 { + 2098606738830025182570698512150760386142000891530754603737354272913658631235 + } + + #[inline(always)] + fn namespace_hash() -> felt252 { + 1452123528942907587532668415362544424816022573043154497385993678618948064048 + } + + #[inline(always)] + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() + } + + #[inline(always)] + fn packed_size() -> Option { + dojo::meta::layout::compute_packed_size(Self::layout()) + } + + #[inline(always)] + fn unpacked_size() -> Option { + dojo::meta::introspect::Introspect::::size() + } + + #[inline(always)] + fn schema(self: @MyEventWithNamespace) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() + } + + #[inline(always)] + fn historical() -> bool { + true + } + + #[inline(always)] + fn keys(self: @MyEventWithNamespace) -> Span { + let mut serialized = core::array::ArrayTrait::new(); + core::serde::Serde::serialize(self.id, ref serialized); + + core::array::ArrayTrait::span(@serialized) + } + + #[inline(always)] + fn values(self: @MyEventWithNamespace) -> Span { + let mut serialized = core::array::ArrayTrait::new(); + core::serde::Serde::serialize(self.name, ref serialized); + + core::array::ArrayTrait::span(@serialized) + } +} + +#[starknet::contract] +pub mod my_event_with_namespace { + use super::MyEventWithNamespace; + + #[abi(embed_v0)] + impl DojoEventImpl of dojo::event::IEvent{ + fn name(self: @ContractState) -> ByteArray { + "MyEventWithNamespace" + } + + fn namespace(self: @ContractState) -> ByteArray { + "dojo_test" + } + + fn tag(self: @ContractState) -> ByteArray { + "dojo_test-MyEventWithNamespace" + } + + fn version(self: @ContractState) -> u8 { + 1 + } + + fn selector(self: @ContractState) -> felt252 { + 2657911819624041908110491051081365977193385901634711445959602441678296212168 + } + + fn name_hash(self: @ContractState) -> felt252 { + 2098606738830025182570698512150760386142000891530754603737354272913658631235 + } + + fn namespace_hash(self: @ContractState) -> felt252 { + 1452123528942907587532668415362544424816022573043154497385993678618948064048 + } + + fn unpacked_size(self: @ContractState) -> Option { + dojo::meta::introspect::Introspect::::size() + } + + fn packed_size(self: @ContractState) -> Option { + dojo::event::Event::::packed_size() + } + + fn layout(self: @ContractState) -> dojo::meta::Layout { + dojo::event::Event::::layout() + } + + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() + } + } +#[event] +#[derive(Drop, starknet::Event)] +pub enum Event {} + + +#[phantom] +pub struct Storage { +} + +#[derive(Drop, Copy)] +pub struct StorageStorageBase { +} +impl StorageStorageImpl of starknet::storage::StorageTrait { + type BaseType = StorageStorageBase; + fn storage(self: starknet::storage::FlattenedStorage) -> StorageStorageBase { + StorageStorageBase { + } + } +} +#[derive(Drop, Copy)] +pub struct StorageStorageBaseMut { +} +impl StorageStorageMutImpl of starknet::storage::StorageTraitMut { + type BaseType = StorageStorageBaseMut; + fn storage_mut(self: starknet::storage::FlattenedStorage>) -> StorageStorageBaseMut { + StorageStorageBaseMut { + } + } +} + +pub struct ContractState { +} + +impl ContractStateDrop of Drop {} + +impl ContractStateDeref of core::ops::SnapshotDeref { + type Target = starknet::storage::FlattenedStorage; + fn snapshot_deref(self: @ContractState) -> starknet::storage::FlattenedStorage { + starknet::storage::FlattenedStorage {} + } +} +impl ContractStateDerefMut of core::ops::DerefMut { + type Target = starknet::storage::FlattenedStorage> ; + fn deref_mut(ref self: ContractState) -> starknet::storage::FlattenedStorage> { + starknet::storage::FlattenedStorage {} + } +} +pub fn unsafe_new_contract_state() -> ContractState { + ContractState { + } +} + +// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one. +#[deprecated( + feature: "deprecated_legacy_map", + note: "Use `starknet::storage::Map` instead." +)] +use starknet::storage::Map as LegacyMap; + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__name(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::name(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__namespace(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::namespace(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__tag(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::tag(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__version(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::version(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__selector(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::selector(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__name_hash(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::name_hash(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__namespace_hash(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::namespace_hash(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__unpacked_size(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::unpacked_size(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::>::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__packed_size(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::packed_size(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::>::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__layout(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::layout(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__schema(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::schema(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + + +pub mod __external { + pub use super::__wrapper__DojoEventImpl__name as name; + pub use super::__wrapper__DojoEventImpl__namespace as namespace; + pub use super::__wrapper__DojoEventImpl__tag as tag; + pub use super::__wrapper__DojoEventImpl__version as version; + pub use super::__wrapper__DojoEventImpl__selector as selector; + pub use super::__wrapper__DojoEventImpl__name_hash as name_hash; + pub use super::__wrapper__DojoEventImpl__namespace_hash as namespace_hash; + pub use super::__wrapper__DojoEventImpl__unpacked_size as unpacked_size; + pub use super::__wrapper__DojoEventImpl__packed_size as packed_size; + pub use super::__wrapper__DojoEventImpl__layout as layout; + pub use super::__wrapper__DojoEventImpl__schema as schema; +} +pub mod __l1_handler { +} +pub mod __constructor { +} + impl ContractStateEventEmitter of starknet::event::EventEmitter< + ContractState, Event + > { + fn emit>( + ref self: ContractState, event: S + ) { + let event: Event = core::traits::Into::into(event); + let mut keys = Default::::default(); + let mut data = Default::::default(); + starknet::Event::append_keys_and_data(@event, ref keys, ref data); + starknet::SyscallResultTrait::unwrap_syscall( + starknet::syscalls::emit_event_syscall( + core::array::ArrayTrait::span(@keys), + core::array::ArrayTrait::span(@data), + ) + ) + } + } +impl EventDrop of core::traits::Drop::; +impl EventIsEvent of starknet::Event { + fn append_keys_and_data( + self: @Event, ref keys: Array, ref data: Array + ) { + match self { + } + } + fn deserialize( + ref keys: Span, ref data: Span, + ) -> Option { + let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?; + Option::None + } +} +impl StorageStorageBaseDrop of core::traits::Drop::; +impl StorageStorageBaseCopy of core::traits::Copy::; +impl StorageStorageBaseMutDrop of core::traits::Drop::; +impl StorageStorageBaseMutCopy of core::traits::Copy::; +} + +impl MyEventNoHistoricalIntrospect<> of dojo::meta::introspect::Introspect> { + #[inline(always)] + fn size() -> Option { + Option::None + } + + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( + array![ + dojo::meta::FieldLayout { + selector: 1528802474226268325865027367859591458315299653151958663884057507666229546336, + layout: dojo::meta::introspect::Introspect::::layout() + } + ].span() + ) + } + + #[inline(always)] + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { + name: 'MyEventNoHistorical', + attrs: array![].span(), + children: array![ + dojo::meta::introspect::Member { + name: 'id', + attrs: array!['key'].span(), + ty: dojo::meta::introspect::Introspect::::ty() + }, +dojo::meta::introspect::Member { + name: 'name', + attrs: array![].span(), + ty: dojo::meta::introspect::Ty::ByteArray + } + + ].span() + } + ) + } +} + +pub impl MyEventNoHistoricalEventImpl of dojo::event::Event { + + fn emit(self: @MyEventNoHistorical, world: dojo::world::IWorldDispatcher) { + dojo::world::IWorldDispatcherTrait::emit( + world, + Self::selector(), + Self::keys(self), + Self::values(self), + Self::historical() + ); + } + + #[inline(always)] + fn name() -> ByteArray { + "MyEventNoHistorical" + } + + #[inline(always)] + fn namespace() -> ByteArray { + "dojo_test" + } + + #[inline(always)] + fn tag() -> ByteArray { + "dojo_test-MyEventNoHistorical" + } + + #[inline(always)] + fn version() -> u8 { + 1 + } + + #[inline(always)] + fn selector() -> felt252 { + 1337059065882820731687976087854228588833382671052971042794952278702302659992 + } + + #[inline(always)] + fn instance_selector(self: @MyEventNoHistorical) -> felt252 { + Self::selector() + } + + #[inline(always)] + fn name_hash() -> felt252 { + 900791686958237697199683333646433800101626975808368629569299817255472139882 + } + + #[inline(always)] + fn namespace_hash() -> felt252 { + 1452123528942907587532668415362544424816022573043154497385993678618948064048 + } + + #[inline(always)] + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() + } + + #[inline(always)] + fn packed_size() -> Option { + dojo::meta::layout::compute_packed_size(Self::layout()) + } + + #[inline(always)] + fn unpacked_size() -> Option { + dojo::meta::introspect::Introspect::::size() + } + + #[inline(always)] + fn schema(self: @MyEventNoHistorical) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() + } + + #[inline(always)] + fn historical() -> bool { + false + } + + #[inline(always)] + fn keys(self: @MyEventNoHistorical) -> Span { + let mut serialized = core::array::ArrayTrait::new(); + core::serde::Serde::serialize(self.id, ref serialized); + + core::array::ArrayTrait::span(@serialized) + } + + #[inline(always)] + fn values(self: @MyEventNoHistorical) -> Span { + let mut serialized = core::array::ArrayTrait::new(); + core::serde::Serde::serialize(self.name, ref serialized); + + core::array::ArrayTrait::span(@serialized) + } +} + +#[starknet::contract] +pub mod my_event_no_historical { + use super::MyEventNoHistorical; + + #[abi(embed_v0)] + impl DojoEventImpl of dojo::event::IEvent{ + fn name(self: @ContractState) -> ByteArray { + "MyEventNoHistorical" + } + + fn namespace(self: @ContractState) -> ByteArray { + "dojo_test" + } + + fn tag(self: @ContractState) -> ByteArray { + "dojo_test-MyEventNoHistorical" + } + + fn version(self: @ContractState) -> u8 { + 1 + } + + fn selector(self: @ContractState) -> felt252 { + 1337059065882820731687976087854228588833382671052971042794952278702302659992 + } + + fn name_hash(self: @ContractState) -> felt252 { + 900791686958237697199683333646433800101626975808368629569299817255472139882 + } + + fn namespace_hash(self: @ContractState) -> felt252 { + 1452123528942907587532668415362544424816022573043154497385993678618948064048 + } + + fn unpacked_size(self: @ContractState) -> Option { + dojo::meta::introspect::Introspect::::size() + } + + fn packed_size(self: @ContractState) -> Option { + dojo::event::Event::::packed_size() + } + + fn layout(self: @ContractState) -> dojo::meta::Layout { + dojo::event::Event::::layout() + } + + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() + } + } +#[event] +#[derive(Drop, starknet::Event)] +pub enum Event {} + + +#[phantom] +pub struct Storage { +} + +#[derive(Drop, Copy)] +pub struct StorageStorageBase { +} +impl StorageStorageImpl of starknet::storage::StorageTrait { + type BaseType = StorageStorageBase; + fn storage(self: starknet::storage::FlattenedStorage) -> StorageStorageBase { + StorageStorageBase { + } + } +} +#[derive(Drop, Copy)] +pub struct StorageStorageBaseMut { +} +impl StorageStorageMutImpl of starknet::storage::StorageTraitMut { + type BaseType = StorageStorageBaseMut; + fn storage_mut(self: starknet::storage::FlattenedStorage>) -> StorageStorageBaseMut { + StorageStorageBaseMut { + } + } +} + +pub struct ContractState { +} + +impl ContractStateDrop of Drop {} + +impl ContractStateDeref of core::ops::SnapshotDeref { + type Target = starknet::storage::FlattenedStorage; + fn snapshot_deref(self: @ContractState) -> starknet::storage::FlattenedStorage { + starknet::storage::FlattenedStorage {} + } +} +impl ContractStateDerefMut of core::ops::DerefMut { + type Target = starknet::storage::FlattenedStorage> ; + fn deref_mut(ref self: ContractState) -> starknet::storage::FlattenedStorage> { + starknet::storage::FlattenedStorage {} + } +} +pub fn unsafe_new_contract_state() -> ContractState { + ContractState { + } +} + +// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one. +#[deprecated( + feature: "deprecated_legacy_map", + note: "Use `starknet::storage::Map` instead." +)] +use starknet::storage::Map as LegacyMap; + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__name(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::name(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__namespace(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::namespace(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__tag(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::tag(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__version(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::version(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__selector(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::selector(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__name_hash(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::name_hash(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__namespace_hash(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::namespace_hash(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__unpacked_size(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::unpacked_size(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::>::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__packed_size(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::packed_size(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::>::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__layout(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::layout(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + +#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] +fn __wrapper__DojoEventImpl__schema(mut data: Span::) -> Span:: { + core::internal::require_implicit::(); + core::internal::revoke_ap_tracking(); + core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); + + assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); + core::option::OptionTraitImpl::expect( + core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', + ); + let mut contract_state = unsafe_new_contract_state(); + let res = DojoEventImpl::schema(@contract_state, ); + let mut arr = ArrayTrait::new(); + // References. + // Result. + core::serde::Serde::::serialize(@res, ref arr); + core::array::ArrayTrait::span(@arr) +} + + +pub mod __external { + pub use super::__wrapper__DojoEventImpl__name as name; + pub use super::__wrapper__DojoEventImpl__namespace as namespace; + pub use super::__wrapper__DojoEventImpl__tag as tag; + pub use super::__wrapper__DojoEventImpl__version as version; + pub use super::__wrapper__DojoEventImpl__selector as selector; + pub use super::__wrapper__DojoEventImpl__name_hash as name_hash; + pub use super::__wrapper__DojoEventImpl__namespace_hash as namespace_hash; + pub use super::__wrapper__DojoEventImpl__unpacked_size as unpacked_size; + pub use super::__wrapper__DojoEventImpl__packed_size as packed_size; + pub use super::__wrapper__DojoEventImpl__layout as layout; + pub use super::__wrapper__DojoEventImpl__schema as schema; +} +pub mod __l1_handler { +} +pub mod __constructor { +} + impl ContractStateEventEmitter of starknet::event::EventEmitter< + ContractState, Event + > { + fn emit>( + ref self: ContractState, event: S + ) { + let event: Event = core::traits::Into::into(event); + let mut keys = Default::::default(); + let mut data = Default::::default(); + starknet::Event::append_keys_and_data(@event, ref keys, ref data); + starknet::SyscallResultTrait::unwrap_syscall( + starknet::syscalls::emit_event_syscall( + core::array::ArrayTrait::span(@keys), + core::array::ArrayTrait::span(@data), + ) + ) + } + } +impl EventDrop of core::traits::Drop::; +impl EventIsEvent of starknet::Event { + fn append_keys_and_data( + self: @Event, ref keys: Array, ref data: Array + ) { + match self { + } + } + fn deserialize( + ref keys: Span, ref data: Span, + ) -> Option { + let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?; + Option::None + } +} +impl StorageStorageBaseDrop of core::traits::Drop::; +impl StorageStorageBaseCopy of core::traits::Copy::; +impl StorageStorageBaseMutDrop of core::traits::Drop::; +impl StorageStorageBaseMutCopy of core::traits::Copy::; +} + +//! > expected_diagnostics diff --git a/crates/compiler/src/plugin/plugin_test_data/introspect b/crates/compiler/src/plugin/plugin_test_data/introspect index fa24bcd..bdbc672 100644 --- a/crates/compiler/src/plugin/plugin_test_data/introspect +++ b/crates/compiler/src/plugin/plugin_test_data/introspect @@ -529,22 +529,22 @@ impl Vec2Serde of core::serde::Serde:: { } } -impl Vec2Introspect<> of dojo::model::introspect::Introspect> { +impl Vec2Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(2) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 512066735765477566404754172672287371265995314501343422459174036873487219331, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1591024729085637502504777720563487898377940395575083379770417352976841400819, - layout: dojo::model::introspect::Introspect::::layout() } ].span() @@ -552,21 +552,21 @@ dojo::model::FieldLayout { } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'Vec2', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'x', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'y', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -595,36 +595,36 @@ impl PlainEnumSerde of core::serde::Serde:: { impl PlainEnumCopy of core::traits::Copy::; impl PlainEnumDrop of core::traits::Drop::; -impl PlainEnumIntrospect<> of dojo::model::introspect::Introspect> { +impl PlainEnumIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(1) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 0, - layout: dojo::model::Layout::Fixed(array![].span()) + layout: dojo::meta::Layout::Fixed(array![].span()) }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1, - layout: dojo::model::Layout::Fixed(array![].span()) + layout: dojo::meta::Layout::Fixed(array![].span()) } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'PlainEnum', attrs: array![].span(), children: array![ - ('Left', dojo::model::introspect::Ty::Tuple(array![].span())), -('Right', dojo::model::introspect::Ty::Tuple(array![].span())) + ('Left', dojo::meta::introspect::Ty::Tuple(array![].span())), +('Right', dojo::meta::introspect::Ty::Tuple(array![].span())) ].span() } @@ -652,36 +652,36 @@ impl EnumWithPrimitiveSerde of core::serde::Serde:: { impl EnumWithPrimitiveCopy of core::traits::Copy::; impl EnumWithPrimitiveDrop of core::traits::Drop::; -impl EnumWithPrimitiveIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumWithPrimitiveIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(2) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 0, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumWithPrimitive', attrs: array![].span(), children: array![ - ('Left', dojo::model::introspect::Introspect::::ty()), -('Right', dojo::model::introspect::Introspect::::ty()) + ('Left', dojo::meta::introspect::Introspect::::ty()), +('Right', dojo::meta::introspect::Introspect::::ty()) ].span() } @@ -709,11 +709,11 @@ impl EnumWithStructSerde of core::serde::Serde:: { impl EnumWithStructCopy of core::traits::Copy::; impl EnumWithStructDrop of core::traits::Drop::; -impl EnumWithStructIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumWithStructIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { let sizes : Array> = array![ - dojo::model::introspect::Introspect::::size(), + dojo::meta::introspect::Introspect::::size(), Option::Some(1) ]; @@ -724,30 +724,30 @@ Option::Some(1) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 0, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumWithStruct', attrs: array![].span(), children: array![ - ('Left', dojo::model::introspect::Introspect::::ty()), -('Right', dojo::model::introspect::Introspect::::ty()) + ('Left', dojo::meta::introspect::Introspect::::ty()), +('Right', dojo::meta::introspect::Introspect::::ty()) ].span() } @@ -775,42 +775,42 @@ impl EnumWithSimpleArraySerde of core::serde::Serde:: { impl EnumWithSimpleArrayCopy of core::traits::Copy::; impl EnumWithSimpleArrayDrop of core::traits::Drop::; -impl EnumWithSimpleArrayIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumWithSimpleArrayIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 0, - layout: dojo::model::introspect::Introspect::>::layout() + layout: dojo::meta::introspect::Introspect::>::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1, - layout: dojo::model::introspect::Introspect::>::layout() + layout: dojo::meta::introspect::Introspect::>::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumWithSimpleArray', attrs: array![].span(), children: array![ - ('Left', dojo::model::introspect::Ty::Array( + ('Left', dojo::meta::introspect::Ty::Array( array![ - dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty() ].span() )), -('Right', dojo::model::introspect::Ty::Array( +('Right', dojo::meta::introspect::Ty::Array( array![ - dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty() ].span() )) @@ -840,36 +840,36 @@ impl EnumWithByteArraySerde of core::serde::Serde:: { impl EnumWithByteArrayCopy of core::traits::Copy::; impl EnumWithByteArrayDrop of core::traits::Drop::; -impl EnumWithByteArrayIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumWithByteArrayIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 0, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumWithByteArray', attrs: array![].span(), children: array![ - ('Left', dojo::model::introspect::Ty::ByteArray), -('Right', dojo::model::introspect::Ty::ByteArray) + ('Left', dojo::meta::introspect::Ty::ByteArray), +('Right', dojo::meta::introspect::Ty::ByteArray) ].span() } @@ -897,30 +897,30 @@ impl EnumWithSimpleTupleSerde of core::serde::Serde:: { impl EnumWithSimpleTupleCopy of core::traits::Copy::; impl EnumWithSimpleTupleDrop of core::traits::Drop::; -impl EnumWithSimpleTupleIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumWithSimpleTupleIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(4) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 0, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) } @@ -929,22 +929,22 @@ dojo::model::introspect::Introspect::::layout() } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumWithSimpleTuple', attrs: array![].span(), children: array![ - ('Left', dojo::model::introspect::Ty::Tuple( + ('Left', dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() )), -('Right', dojo::model::introspect::Ty::Tuple( +('Right', dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() )) @@ -974,11 +974,11 @@ impl EnumWithComplexTupleSerde of core::serde::Serde:: { impl EnumWithComplexTupleCopy of core::traits::Copy::; impl EnumWithComplexTupleDrop of core::traits::Drop::; -impl EnumWithComplexTupleIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumWithComplexTupleIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { let sizes : Array> = array![ - dojo::model::introspect::Introspect::::size(), + dojo::meta::introspect::Introspect::::size(), Option::Some(2) ]; @@ -989,24 +989,24 @@ Option::Some(2) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 0, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) } @@ -1015,22 +1015,22 @@ dojo::model::introspect::Introspect::::layout() } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumWithComplexTuple', attrs: array![].span(), children: array![ - ('Left', dojo::model::introspect::Ty::Tuple( + ('Left', dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() )), -('Right', dojo::model::introspect::Ty::Tuple( +('Right', dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() )) @@ -1060,36 +1060,36 @@ impl EnumWithPrimitiveSerde of core::serde::Serde:: { impl EnumWithPrimitiveCopy of core::traits::Copy::; impl EnumWithPrimitiveDrop of core::traits::Drop::; -impl EnumWithPrimitiveIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumWithPrimitiveIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(2) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 0, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumWithPrimitive', attrs: array![].span(), children: array![ - ('Left', dojo::model::introspect::Introspect::::ty()), -('Right', dojo::model::introspect::Introspect::::ty()) + ('Left', dojo::meta::introspect::Introspect::::ty()), +('Right', dojo::meta::introspect::Introspect::::ty()) ].span() } @@ -1117,11 +1117,11 @@ impl EnumCustomSerde of core::serde::Serde:: { impl EnumCustomCopy of core::traits::Copy::; impl EnumCustomDrop of core::traits::Drop::; -impl EnumCustomIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumCustomIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { let sizes : Array> = array![ - dojo::model::introspect::Introspect::::size(), + dojo::meta::introspect::Introspect::::size(), Option::Some(1) ]; @@ -1132,30 +1132,30 @@ Option::Some(1) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 0, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumCustom', attrs: array![].span(), children: array![ - ('Left', dojo::model::introspect::Introspect::::ty()), -('Right', dojo::model::introspect::Introspect::::ty()) + ('Left', dojo::meta::introspect::Introspect::::ty()), +('Right', dojo::meta::introspect::Introspect::::ty()) ].span() } @@ -1183,12 +1183,12 @@ impl EnumTupleMixSerde of core::serde::Serde:: { impl EnumTupleMixCopy of core::traits::Copy::; impl EnumTupleMixDrop of core::traits::Drop::; -impl EnumTupleMixIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumTupleMixIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { let sizes : Array> = array![ - dojo::model::introspect::Introspect::::size(), -dojo::model::introspect::Introspect::::size(), + dojo::meta::introspect::Introspect::::size(), +dojo::meta::introspect::Introspect::::size(), Option::Some(2) ]; @@ -1199,26 +1199,26 @@ Option::Some(2) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 0, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) } @@ -1227,24 +1227,24 @@ dojo::model::introspect::Introspect::::layout() } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumTupleMix', attrs: array![].span(), children: array![ - ('Left', dojo::model::introspect::Ty::Tuple( + ('Left', dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() )), -('Right', dojo::model::introspect::Ty::Tuple( +('Right', dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() )) @@ -1276,29 +1276,29 @@ impl EnumWithDifferentVariantDataSerde of core::serde::Serde::; impl EnumWithDifferentVariantDataDrop of core::traits::Drop::; -impl EnumWithDifferentVariantDataIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumWithDifferentVariantDataIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 0, - layout: dojo::model::Layout::Fixed(array![].span()) + layout: dojo::meta::Layout::Fixed(array![].span()) }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 2, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) } @@ -1307,18 +1307,18 @@ dojo::model::introspect::Introspect::::layout() } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumWithDifferentVariantData', attrs: array![].span(), children: array![ - ('One', dojo::model::introspect::Ty::Tuple(array![].span())), -('Two', dojo::model::introspect::Introspect::::ty()), -('Three', dojo::model::introspect::Ty::Tuple( + ('One', dojo::meta::introspect::Ty::Tuple(array![].span())), +('Two', dojo::meta::introspect::Introspect::::ty()), +('Three', dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() )) @@ -1330,48 +1330,48 @@ dojo::model::introspect::Introspect::::ty() impl StructWithPrimitivesCopy of core::traits::Copy::; impl StructWithPrimitivesDrop of core::traits::Drop::; -impl StructWithPrimitivesIntrospect<> of dojo::model::introspect::Introspect> { +impl StructWithPrimitivesIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(2) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 387461982739864353524563589639770327077359184971688375275386807599796929637, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 564613130574576288414461160574656432422962213642984413874723251824844509768, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructWithPrimitives', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'before', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'after', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -1382,11 +1382,11 @@ dojo::model::introspect::Member { impl StructWithStructCopy of core::traits::Copy::; impl StructWithStructDrop of core::traits::Drop::; -impl StructWithStructIntrospect<> of dojo::model::introspect::Introspect> { +impl StructWithStructIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { let sizes : Array> = array![ - dojo::model::introspect::Introspect::::size(), + dojo::meta::introspect::Introspect::::size(), Option::Some(1) ]; @@ -1397,42 +1397,42 @@ Option::Some(1) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 387461982739864353524563589639770327077359184971688375275386807599796929637, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 564613130574576288414461160574656432422962213642984413874723251824844509768, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructWithStruct', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'before', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'after', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -1443,50 +1443,50 @@ dojo::model::introspect::Member { impl StructWithSimpleArrayCopy of core::traits::Copy::; impl StructWithSimpleArrayDrop of core::traits::Drop::; -impl StructWithSimpleArrayIntrospect<> of dojo::model::introspect::Introspect> { +impl StructWithSimpleArrayIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 387461982739864353524563589639770327077359184971688375275386807599796929637, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 564613130574576288414461160574656432422962213642984413874723251824844509768, - layout: dojo::model::introspect::Introspect::>::layout() + layout: dojo::meta::introspect::Introspect::>::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructWithSimpleArray', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'before', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'after', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Array( + ty: dojo::meta::introspect::Ty::Array( array![ - dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty() ].span() ) } @@ -1499,48 +1499,48 @@ dojo::model::introspect::Member { impl StructWithByteArrayCopy of core::traits::Copy::; impl StructWithByteArrayDrop of core::traits::Drop::; -impl StructWithByteArrayIntrospect<> of dojo::model::introspect::Introspect> { +impl StructWithByteArrayIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 387461982739864353524563589639770327077359184971688375275386807599796929637, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 564613130574576288414461160574656432422962213642984413874723251824844509768, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructWithByteArray', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'before', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'after', attrs: array![].span(), - ty: dojo::model::introspect::Ty::ByteArray + ty: dojo::meta::introspect::Ty::ByteArray } ].span() @@ -1551,50 +1551,50 @@ dojo::model::introspect::Member { impl StructWithComplexArrayCopy of core::traits::Copy::; impl StructWithComplexArrayDrop of core::traits::Drop::; -impl StructWithComplexArrayIntrospect<> of dojo::model::introspect::Introspect> { +impl StructWithComplexArrayIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 387461982739864353524563589639770327077359184971688375275386807599796929637, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 564613130574576288414461160574656432422962213642984413874723251824844509768, - layout: dojo::model::introspect::Introspect::>::layout() + layout: dojo::meta::introspect::Introspect::>::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructWithComplexArray', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'before', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'after', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Array( + ty: dojo::meta::introspect::Ty::Array( array![ - dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty() ].span() ) } @@ -1607,25 +1607,25 @@ dojo::model::introspect::Member { impl StructWithSimpleTupleCopy of core::traits::Copy::; impl StructWithSimpleTupleDrop of core::traits::Drop::; -impl StructWithSimpleTupleIntrospect<> of dojo::model::introspect::Introspect> { +impl StructWithSimpleTupleIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(4) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 387461982739864353524563589639770327077359184971688375275386807599796929637, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 564613130574576288414461160574656432422962213642984413874723251824844509768, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) } @@ -1634,29 +1634,29 @@ dojo::model::introspect::Introspect::::layout() } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructWithSimpleTuple', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'before', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'after', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Tuple( + ty: dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() ) } @@ -1669,12 +1669,12 @@ dojo::model::introspect::Introspect::::ty() impl StructWithComplexTupleCopy of core::traits::Copy::; impl StructWithComplexTupleDrop of core::traits::Drop::; -impl StructWithComplexTupleIntrospect<> of dojo::model::introspect::Introspect> { +impl StructWithComplexTupleIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { let sizes : Array> = array![ - dojo::model::introspect::Introspect::::size(), -dojo::model::introspect::Introspect::::size(), + dojo::meta::introspect::Introspect::::size(), +dojo::meta::introspect::Introspect::::size(), Option::Some(2) ]; @@ -1685,20 +1685,20 @@ Option::Some(2) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 387461982739864353524563589639770327077359184971688375275386807599796929637, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 564613130574576288414461160574656432422962213642984413874723251824844509768, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) } @@ -1707,30 +1707,30 @@ dojo::model::introspect::Introspect::::layout() } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructWithComplexTuple', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'before', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'after', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Tuple( + ty: dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() ) } @@ -1743,26 +1743,26 @@ dojo::model::introspect::Introspect::::ty() impl StructWithNestedArraysCopy of core::traits::Copy::; impl StructWithNestedArraysDrop of core::traits::Drop::; -impl StructWithNestedArraysIntrospect<> of dojo::model::introspect::Introspect> { +impl StructWithNestedArraysIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 387461982739864353524563589639770327077359184971688375275386807599796929637, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 564613130574576288414461160574656432422962213642984413874723251824844509768, - layout: dojo::model::Layout::Array( + layout: dojo::meta::Layout::Array( array![ - dojo::model::Layout::Array( + dojo::meta::Layout::Array( array![ - dojo::model::introspect::Introspect::>::layout() + dojo::meta::introspect::Introspect::>::layout() ].span() ) ].span() @@ -1773,32 +1773,32 @@ dojo::model::FieldLayout { } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructWithNestedArrays', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'before', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'after', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Array( + ty: dojo::meta::introspect::Ty::Array( array![ - dojo::model::introspect::Ty::Array( + dojo::meta::introspect::Ty::Array( array![ - dojo::model::introspect::Ty::Array( + dojo::meta::introspect::Ty::Array( array![ - dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty() ].span() ) ].span() @@ -1815,12 +1815,12 @@ dojo::model::introspect::Member { impl StructWithNestedTuplesCopy of core::traits::Copy::; impl StructWithNestedTuplesDrop of core::traits::Drop::; -impl StructWithNestedTuplesIntrospect<> of dojo::model::introspect::Introspect> { +impl StructWithNestedTuplesIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { let sizes : Array> = array![ - dojo::model::introspect::Introspect::::size(), -dojo::model::introspect::Introspect::::size(), + dojo::meta::introspect::Introspect::::size(), +dojo::meta::introspect::Introspect::::size(), Option::Some(3) ]; @@ -1831,27 +1831,27 @@ Option::Some(3) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 387461982739864353524563589639770327077359184971688375275386807599796929637, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 564613130574576288414461160574656432422962213642984413874723251824844509768, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::Layout::Tuple( + dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ), -dojo::model::Layout::Tuple( +dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) ].span() @@ -1862,37 +1862,37 @@ dojo::model::introspect::Introspect::::layout() } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructWithNestedTuples', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'before', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'after', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Tuple( + ty: dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Ty::Tuple( + dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() ), -dojo::model::introspect::Ty::Tuple( +dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() ) ].span() @@ -1907,33 +1907,33 @@ dojo::model::introspect::Introspect::::ty() impl StructWithNestedTuplesAndByteArrayCopy of core::traits::Copy::; impl StructWithNestedTuplesAndByteArrayDrop of core::traits::Drop::; -impl StructWithNestedTuplesAndByteArrayIntrospect<> of dojo::model::introspect::Introspect> { +impl StructWithNestedTuplesAndByteArrayIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 387461982739864353524563589639770327077359184971688375275386807599796929637, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 564613130574576288414461160574656432422962213642984413874723251824844509768, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::Layout::Tuple( + dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ), -dojo::model::Layout::Tuple( +dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) ].span() @@ -1944,37 +1944,37 @@ dojo::model::introspect::Introspect::::layout() } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructWithNestedTuplesAndByteArray', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'before', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'after', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Tuple( + ty: dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Ty::Tuple( + dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() ), -dojo::model::introspect::Ty::Tuple( +dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Ty::ByteArray + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Ty::ByteArray ].span() ) ].span() @@ -1989,53 +1989,53 @@ dojo::model::introspect::Ty::ByteArray impl StructWithNestedEverythingCopy of core::traits::Copy::; impl StructWithNestedEverythingDrop of core::traits::Drop::; -impl StructWithNestedEverythingIntrospect<> of dojo::model::introspect::Introspect> { +impl StructWithNestedEverythingIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 387461982739864353524563589639770327077359184971688375275386807599796929637, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 564613130574576288414461160574656432422962213642984413874723251824844509768, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::Layout::Tuple( + dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ), -dojo::model::Layout::Tuple( +dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ), -dojo::model::Layout::Tuple( +dojo::meta::Layout::Tuple( array![ - dojo::model::Layout::Array( + dojo::meta::Layout::Array( array![ - dojo::model::Layout::Tuple( + dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) ].span() ), -dojo::model::introspect::Introspect::::layout() +dojo::meta::introspect::Introspect::::layout() ].span() ), -dojo::model::Layout::Tuple( +dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout() ].span() ) ].span() @@ -2046,57 +2046,57 @@ dojo::model::Layout::Tuple( } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructWithNestedEverything', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'before', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'after', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Tuple( + ty: dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Ty::Tuple( + dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() ), -dojo::model::introspect::Ty::Tuple( +dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() ), -dojo::model::introspect::Ty::Tuple( +dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Ty::Array( + dojo::meta::introspect::Ty::Array( array![ - dojo::model::introspect::Ty::Tuple( + dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() ) ].span() ), -dojo::model::introspect::Introspect::::ty() +dojo::meta::introspect::Introspect::::ty() ].span() ), -dojo::model::introspect::Ty::Tuple( +dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty() ].span() ) ].span() @@ -2121,34 +2121,34 @@ impl GenericStructSerde, +core::traits::Destruct> o } } -impl GenericStructIntrospect> of dojo::model::introspect::Introspect> { +impl GenericStructIntrospect> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 1246920879054256875300693562709339669009726288543267794550465531256469553289, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'GenericStruct', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 't', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -2169,18 +2169,18 @@ impl StructWithBadOptionSerde of core::serde::Serde:: { } } -impl StructWithBadOptionIntrospect<> of dojo::model::introspect::Introspect> { +impl StructWithBadOptionIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::>::size() + dojo::meta::introspect::Introspect::>::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 512066735765477566404754172672287371265995314501343422459174036873487219331, - layout: dojo::model::introspect::Introspect:: + layout: dojo::meta::introspect::Introspect:: >::layout() } ].span() @@ -2188,16 +2188,16 @@ impl StructWithBadOptionIntrospect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructWithBadOption', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'x', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::>::ty() + ty: dojo::meta::introspect::Introspect::>::ty() } ].span() @@ -2224,11 +2224,11 @@ impl EnumWithBadOptionSerde of core::serde::Serde:: { } } -impl EnumWithBadOptionIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumWithBadOptionIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { let sizes : Array> = array![ - dojo::model::introspect::Introspect::>::size(), + dojo::meta::introspect::Introspect::>::size(), Option::Some(1) ]; @@ -2239,25 +2239,25 @@ Option::Some(1) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 0, - layout: dojo::model::introspect::Introspect::>::layout() + layout: dojo::meta::introspect::Introspect::>::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumWithBadOption', attrs: array![].span(), children: array![ - ('first', dojo::model::introspect::Introspect::>::ty()) + ('first', dojo::meta::introspect::Introspect::>::ty()) ].span() } @@ -2265,14 +2265,14 @@ Option::Some(1) } } -impl EnumIncompatibleAttrsIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumIncompatibleAttrsIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ ].span() @@ -2280,9 +2280,9 @@ impl EnumIncompatibleAttrsIntrospect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumIncompatibleAttrs', attrs: array![].span(), children: array![ @@ -2294,14 +2294,14 @@ impl EnumIncompatibleAttrsIntrospect<> of dojo::model::introspect::Introspect of dojo::model::introspect::Introspect> { +impl EnumIncompatibleAttrsIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Fixed( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Fixed( array![ 8 ].span() @@ -2309,9 +2309,9 @@ impl EnumIncompatibleAttrsIntrospect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumIncompatibleAttrs', attrs: array![].span(), children: array![ @@ -2323,14 +2323,14 @@ impl EnumIncompatibleAttrsIntrospect<> of dojo::model::introspect::Introspect of dojo::model::introspect::Introspect> { +impl StructIncompatibleAttrsIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ ].span() @@ -2338,9 +2338,9 @@ impl StructIncompatibleAttrsIntrospect<> of dojo::model::introspect::Introspect< } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructIncompatibleAttrs', attrs: array![].span(), children: array![ @@ -2352,14 +2352,14 @@ impl StructIncompatibleAttrsIntrospect<> of dojo::model::introspect::Introspect< } } -impl StructIncompatibleAttrsIntrospect<> of dojo::model::introspect::Introspect> { +impl StructIncompatibleAttrsIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Fixed( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Fixed( array![ ].span() @@ -2367,9 +2367,9 @@ impl StructIncompatibleAttrsIntrospect<> of dojo::model::introspect::Introspect< } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructIncompatibleAttrs', attrs: array![].span(), children: array![ @@ -2381,14 +2381,14 @@ impl StructIncompatibleAttrsIntrospect<> of dojo::model::introspect::Introspect< } } -impl StructIncompatibleAttrs2Introspect<> of dojo::model::introspect::Introspect> { +impl StructIncompatibleAttrs2Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ ].span() @@ -2396,9 +2396,9 @@ impl StructIncompatibleAttrs2Introspect<> of dojo::model::introspect::Introspect } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructIncompatibleAttrs2', attrs: array![].span(), children: array![ @@ -2410,14 +2410,14 @@ impl StructIncompatibleAttrs2Introspect<> of dojo::model::introspect::Introspect } } -impl StructIncompatibleAttrs2Introspect<> of dojo::model::introspect::Introspect> { +impl StructIncompatibleAttrs2Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Fixed( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Fixed( array![ ].span() @@ -2425,9 +2425,9 @@ impl StructIncompatibleAttrs2Introspect<> of dojo::model::introspect::Introspect } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructIncompatibleAttrs2', attrs: array![].span(), children: array![ @@ -2439,14 +2439,14 @@ impl StructIncompatibleAttrs2Introspect<> of dojo::model::introspect::Introspect } } -impl EnumIncompatibleAttrs2Introspect<> of dojo::model::introspect::Introspect> { +impl EnumIncompatibleAttrs2Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Enum( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Enum( array![ ].span() @@ -2454,9 +2454,9 @@ impl EnumIncompatibleAttrs2Introspect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumIncompatibleAttrs2', attrs: array![].span(), children: array![ @@ -2468,14 +2468,14 @@ impl EnumIncompatibleAttrs2Introspect<> of dojo::model::introspect::Introspect of dojo::model::introspect::Introspect> { +impl EnumIncompatibleAttrs2Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Fixed( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Fixed( array![ 8 ].span() @@ -2483,9 +2483,9 @@ impl EnumIncompatibleAttrs2Introspect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumIncompatibleAttrs2', attrs: array![].span(), children: array![ @@ -2497,14 +2497,14 @@ impl EnumIncompatibleAttrs2Introspect<> of dojo::model::introspect::Introspect of dojo::model::introspect::Introspect> { +impl StructPacked1Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(1) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Fixed( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Fixed( array![ 8 ].span() @@ -2512,16 +2512,16 @@ impl StructPacked1Introspect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructPacked1', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'x', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -2530,14 +2530,14 @@ impl StructPacked1Introspect<> of dojo::model::introspect::Introspect of dojo::model::introspect::Introspect> { +impl StructPacked2Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(3) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Fixed( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Fixed( array![ 8,128,128 ].span() @@ -2545,21 +2545,21 @@ impl StructPacked2Introspect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructPacked2', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'x', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'y', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -2568,14 +2568,14 @@ dojo::model::introspect::Member { } } -impl StructPacked3Introspect<> of dojo::model::introspect::Introspect> { +impl StructPacked3Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(4) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Fixed( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Fixed( array![ 128,128,8,32 ].span() @@ -2583,24 +2583,24 @@ impl StructPacked3Introspect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructPacked3', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'x', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'y', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Tuple( + ty: dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() ) } @@ -2611,14 +2611,14 @@ dojo::model::introspect::Introspect::::ty() } } -impl StructNotPackable1Introspect<> of dojo::model::introspect::Introspect> { +impl StructNotPackable1Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Fixed( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Fixed( array![ 8,ERROR ].span() @@ -2626,23 +2626,23 @@ impl StructNotPackable1Introspect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructNotPackable1', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'x', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'y', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Array( + ty: dojo::meta::introspect::Ty::Array( array![ - dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty() ].span() ) } @@ -2653,11 +2653,11 @@ dojo::model::introspect::Member { } } -impl StructPackableWithInnerPackedIntrospect<> of dojo::model::introspect::Introspect> { +impl StructPackableWithInnerPackedIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { let sizes : Array> = array![ - dojo::model::introspect::Introspect::::size(), + dojo::meta::introspect::Introspect::::size(), Option::Some(1) ]; @@ -2666,10 +2666,10 @@ Option::Some(1) } - fn layout() -> dojo::model::Layout { + fn layout() -> dojo::meta::Layout { let mut layouts = array![ - dojo::model::Layout::Fixed(array![8].span()), -dojo::model::introspect::Introspect::::layout() + dojo::meta::Layout::Fixed(array![8].span()), +dojo::meta::introspect::Introspect::::layout() ]; let mut merged_layout = ArrayTrait::::new(); @@ -2677,7 +2677,7 @@ dojo::model::introspect::Introspect::::layout() match ArrayTrait::pop_front(ref layouts) { Option::Some(mut layout) => { match layout { - dojo::model::Layout::Fixed(mut l) => { + dojo::meta::Layout::Fixed(mut l) => { loop { match SpanTrait::pop_front(ref l) { Option::Some(x) => merged_layout.append(*x), @@ -2692,26 +2692,26 @@ dojo::model::introspect::Introspect::::layout() }; }; - dojo::model::Layout::Fixed(merged_layout.span()) + dojo::meta::Layout::Fixed(merged_layout.span()) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'StructPackableWithInnerPacked', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'x', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'y', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -2720,14 +2720,14 @@ dojo::model::introspect::Member { } } -impl EnumPacked1Introspect<> of dojo::model::introspect::Introspect> { +impl EnumPacked1Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(1) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Fixed( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Fixed( array![ 8 ].span() @@ -2735,15 +2735,15 @@ impl EnumPacked1Introspect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumPacked1', attrs: array![].span(), children: array![ - ('a', dojo::model::introspect::Ty::Tuple(array![].span())), -('b', dojo::model::introspect::Ty::Tuple(array![].span())), -('c', dojo::model::introspect::Ty::Tuple(array![].span())) + ('a', dojo::meta::introspect::Ty::Tuple(array![].span())), +('b', dojo::meta::introspect::Ty::Tuple(array![].span())), +('c', dojo::meta::introspect::Ty::Tuple(array![].span())) ].span() } @@ -2751,14 +2751,14 @@ impl EnumPacked1Introspect<> of dojo::model::introspect::Introspect of dojo::model::introspect::Introspect> { +impl EnumPacked2Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(2) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Fixed( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Fixed( array![ 8,8 ].span() @@ -2766,15 +2766,15 @@ impl EnumPacked2Introspect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumPacked2', attrs: array![].span(), children: array![ - ('a', dojo::model::introspect::Introspect::::ty()), -('b', dojo::model::introspect::Introspect::::ty()), -('c', dojo::model::introspect::Introspect::::ty()) + ('a', dojo::meta::introspect::Introspect::::ty()), +('b', dojo::meta::introspect::Introspect::::ty()), +('c', dojo::meta::introspect::Introspect::::ty()) ].span() } @@ -2782,14 +2782,14 @@ impl EnumPacked2Introspect<> of dojo::model::introspect::Introspect of dojo::model::introspect::Introspect> { +impl EnumPacked3Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(3) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Fixed( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Fixed( array![ 8,128,128 ].span() @@ -2797,19 +2797,19 @@ impl EnumPacked3Introspect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumPacked3', attrs: array![].span(), children: array![ - ('a', dojo::model::introspect::Ty::Tuple( + ('a', dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() )), -('b', dojo::model::introspect::Introspect::::ty()) +('b', dojo::meta::introspect::Introspect::::ty()) ].span() } @@ -2817,11 +2817,11 @@ dojo::model::introspect::Introspect::::ty() } } -impl EnumPackableWithInnerPackedIntrospect<> of dojo::model::introspect::Introspect> { +impl EnumPackableWithInnerPackedIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { let sizes : Array> = array![ - dojo::model::introspect::Introspect::::size(), + dojo::meta::introspect::Introspect::::size(), Option::Some(1) ]; @@ -2830,10 +2830,10 @@ Option::Some(1) } - fn layout() -> dojo::model::Layout { + fn layout() -> dojo::meta::Layout { let mut layouts = array![ - dojo::model::Layout::Fixed(array![8].span()), -dojo::model::introspect::Introspect::::layout() + dojo::meta::Layout::Fixed(array![8].span()), +dojo::meta::introspect::Introspect::::layout() ]; let mut merged_layout = ArrayTrait::::new(); @@ -2841,7 +2841,7 @@ dojo::model::introspect::Introspect::::layout() match ArrayTrait::pop_front(ref layouts) { Option::Some(mut layout) => { match layout { - dojo::model::Layout::Fixed(mut l) => { + dojo::meta::Layout::Fixed(mut l) => { loop { match SpanTrait::pop_front(ref l) { Option::Some(x) => merged_layout.append(*x), @@ -2856,19 +2856,19 @@ dojo::model::introspect::Introspect::::layout() }; }; - dojo::model::Layout::Fixed(merged_layout.span()) + dojo::meta::Layout::Fixed(merged_layout.span()) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumPackableWithInnerPacked', attrs: array![].span(), children: array![ - ('a', dojo::model::introspect::Introspect::::ty()), -('b', dojo::model::introspect::Introspect::::ty()) + ('a', dojo::meta::introspect::Introspect::::ty()), +('b', dojo::meta::introspect::Introspect::::ty()) ].span() } @@ -2876,25 +2876,25 @@ dojo::model::introspect::Introspect::::layout() } } -impl EnumNotPackable1Introspect<> of dojo::model::introspect::Introspect> { +impl EnumNotPackable1Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { + fn layout() -> dojo::meta::Layout { ERROR } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Enum( - dojo::model::introspect::Enum { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Enum( + dojo::meta::introspect::Enum { name: 'EnumNotPackable1', attrs: array![].span(), children: array![ - ('a', dojo::model::introspect::Introspect::::ty()), -('b', dojo::model::introspect::Introspect::::ty()) + ('a', dojo::meta::introspect::Introspect::::ty()), +('b', dojo::meta::introspect::Introspect::::ty()) ].span() } diff --git a/crates/compiler/src/plugin/plugin_test_data/model b/crates/compiler/src/plugin/plugin_test_data/model index f098168..5ce1ce2 100644 --- a/crates/compiler/src/plugin/plugin_test_data/model +++ b/crates/compiler/src/plugin/plugin_test_data/model @@ -315,39 +315,39 @@ struct ModelWithTupleNoPrimitives { x: u16, y: (u8, Vec3, u32) } -impl BadModelMultipleVersionsIntrospect<> of dojo::model::introspect::Introspect> { +impl BadModelMultipleVersionsIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 578691550836206188651404750433984985630363913126316857592149308417275000080, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'BadModelMultipleVersions', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'v', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -412,31 +412,30 @@ pub impl BadModelMultipleVersionsEntityStoreImpl of BadModelMultipleVersionsEnti pub impl BadModelMultipleVersionsStoreImpl of BadModelMultipleVersionsStore { fn entity_id_from_keys(id: felt252) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> BadModelMultipleVersions { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let id = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let v = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `BadModelMultipleVersions`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + BadModelMultipleVersions { + id, + + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> BadModelMultipleVersions { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); dojo::model::Model::::get(world, serialized.span()) @@ -453,7 +452,7 @@ pub impl BadModelMultipleVersionsStoreImpl of BadModelMultipleVersionsStore { fn get_v(world: dojo::world::IWorldDispatcher, id: felt252) -> Vec3 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); let mut values = dojo::model::Model::::get_member( @@ -498,18 +497,17 @@ pub impl BadModelMultipleVersionsModelEntityImpl of dojo::model::ModelEntity) -> BadModelMultipleVersionsEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let v = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `BadModelMultipleVersionsEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + BadModelMultipleVersionsEntity { + __id: entity_id, + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> BadModelMultipleVersionsEntity { @@ -519,7 +517,12 @@ pub impl BadModelMultipleVersionsModelEntityImpl of dojo::model::ModelEntity::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `BadModelMultipleVersionsEntity`: deserialization failed.") + } + } } fn update_entity(self: @BadModelMultipleVersionsEntity, world: dojo::world::IWorldDispatcher) { @@ -590,7 +593,12 @@ pub impl BadModelMultipleVersionsModelImpl of dojo::model::Model x, + Option::None => { + panic!("Model `BadModelMultipleVersions`: deserialization failed.") + } + } } fn set_model( @@ -705,7 +713,7 @@ pub impl BadModelMultipleVersionsModelImpl of dojo::model::Model Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.id); + core::serde::Serde::serialize(self.id, ref serialized); core::array::ArrayTrait::span(@serialized) } @@ -719,18 +727,18 @@ pub impl BadModelMultipleVersionsModelImpl of dojo::model::Model dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @BadModelMultipleVersions) -> dojo::model::Layout { + fn instance_layout(self: @BadModelMultipleVersions) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -775,19 +783,19 @@ pub mod bad_model_multiple_versions { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -1041,7 +1049,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -1060,7 +1068,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -1143,39 +1151,39 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl BadModelBadVersionTypeIntrospect<> of dojo::model::introspect::Introspect> { +impl BadModelBadVersionTypeIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 578691550836206188651404750433984985630363913126316857592149308417275000080, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'BadModelBadVersionType', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'v', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -1240,31 +1248,30 @@ pub impl BadModelBadVersionTypeEntityStoreImpl of BadModelBadVersionTypeEntitySt pub impl BadModelBadVersionTypeStoreImpl of BadModelBadVersionTypeStore { fn entity_id_from_keys(id: felt252) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> BadModelBadVersionType { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let id = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let v = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `BadModelBadVersionType`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + BadModelBadVersionType { + id, + + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> BadModelBadVersionType { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); dojo::model::Model::::get(world, serialized.span()) @@ -1281,7 +1288,7 @@ pub impl BadModelBadVersionTypeStoreImpl of BadModelBadVersionTypeStore { fn get_v(world: dojo::world::IWorldDispatcher, id: felt252) -> Vec3 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); let mut values = dojo::model::Model::::get_member( @@ -1326,18 +1333,17 @@ pub impl BadModelBadVersionTypeModelEntityImpl of dojo::model::ModelEntity) -> BadModelBadVersionTypeEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let v = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `BadModelBadVersionTypeEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + BadModelBadVersionTypeEntity { + __id: entity_id, + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> BadModelBadVersionTypeEntity { @@ -1347,7 +1353,12 @@ pub impl BadModelBadVersionTypeModelEntityImpl of dojo::model::ModelEntity::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `BadModelBadVersionTypeEntity`: deserialization failed.") + } + } } fn update_entity(self: @BadModelBadVersionTypeEntity, world: dojo::world::IWorldDispatcher) { @@ -1418,7 +1429,12 @@ pub impl BadModelBadVersionTypeModelImpl of dojo::model::Model x, + Option::None => { + panic!("Model `BadModelBadVersionType`: deserialization failed.") + } + } } fn set_model( @@ -1533,7 +1549,7 @@ pub impl BadModelBadVersionTypeModelImpl of dojo::model::Model Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.id); + core::serde::Serde::serialize(self.id, ref serialized); core::array::ArrayTrait::span(@serialized) } @@ -1547,18 +1563,18 @@ pub impl BadModelBadVersionTypeModelImpl of dojo::model::Model dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @BadModelBadVersionType) -> dojo::model::Layout { + fn instance_layout(self: @BadModelBadVersionType) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -1603,19 +1619,19 @@ pub mod bad_model_bad_version_type { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -1869,7 +1885,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -1888,7 +1904,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -1971,39 +1987,39 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl BadModelNoVersionValueIntrospect<> of dojo::model::introspect::Introspect> { +impl BadModelNoVersionValueIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 578691550836206188651404750433984985630363913126316857592149308417275000080, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'BadModelNoVersionValue', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'v', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -2068,31 +2084,30 @@ pub impl BadModelNoVersionValueEntityStoreImpl of BadModelNoVersionValueEntitySt pub impl BadModelNoVersionValueStoreImpl of BadModelNoVersionValueStore { fn entity_id_from_keys(id: felt252) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> BadModelNoVersionValue { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let id = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let v = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `BadModelNoVersionValue`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + BadModelNoVersionValue { + id, + + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> BadModelNoVersionValue { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); dojo::model::Model::::get(world, serialized.span()) @@ -2109,7 +2124,7 @@ pub impl BadModelNoVersionValueStoreImpl of BadModelNoVersionValueStore { fn get_v(world: dojo::world::IWorldDispatcher, id: felt252) -> Vec3 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); let mut values = dojo::model::Model::::get_member( @@ -2154,18 +2169,17 @@ pub impl BadModelNoVersionValueModelEntityImpl of dojo::model::ModelEntity) -> BadModelNoVersionValueEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let v = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `BadModelNoVersionValueEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + BadModelNoVersionValueEntity { + __id: entity_id, + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> BadModelNoVersionValueEntity { @@ -2175,7 +2189,12 @@ pub impl BadModelNoVersionValueModelEntityImpl of dojo::model::ModelEntity::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `BadModelNoVersionValueEntity`: deserialization failed.") + } + } } fn update_entity(self: @BadModelNoVersionValueEntity, world: dojo::world::IWorldDispatcher) { @@ -2246,7 +2265,12 @@ pub impl BadModelNoVersionValueModelImpl of dojo::model::Model x, + Option::None => { + panic!("Model `BadModelNoVersionValue`: deserialization failed.") + } + } } fn set_model( @@ -2361,7 +2385,7 @@ pub impl BadModelNoVersionValueModelImpl of dojo::model::Model Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.id); + core::serde::Serde::serialize(self.id, ref serialized); core::array::ArrayTrait::span(@serialized) } @@ -2375,18 +2399,18 @@ pub impl BadModelNoVersionValueModelImpl of dojo::model::Model dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @BadModelNoVersionValue) -> dojo::model::Layout { + fn instance_layout(self: @BadModelNoVersionValue) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -2431,19 +2455,19 @@ pub mod bad_model_no_version_value { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -2697,7 +2721,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -2716,7 +2740,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -2799,39 +2823,39 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl BadModelUnexpectedArgWithValueIntrospect<> of dojo::model::introspect::Introspect> { +impl BadModelUnexpectedArgWithValueIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 578691550836206188651404750433984985630363913126316857592149308417275000080, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'BadModelUnexpectedArgWithValue', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'v', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -2896,31 +2920,30 @@ pub impl BadModelUnexpectedArgWithValueEntityStoreImpl of BadModelUnexpectedArgW pub impl BadModelUnexpectedArgWithValueStoreImpl of BadModelUnexpectedArgWithValueStore { fn entity_id_from_keys(id: felt252) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> BadModelUnexpectedArgWithValue { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let id = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let v = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `BadModelUnexpectedArgWithValue`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + BadModelUnexpectedArgWithValue { + id, + + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> BadModelUnexpectedArgWithValue { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); dojo::model::Model::::get(world, serialized.span()) @@ -2937,7 +2960,7 @@ pub impl BadModelUnexpectedArgWithValueStoreImpl of BadModelUnexpectedArgWithVal fn get_v(world: dojo::world::IWorldDispatcher, id: felt252) -> Vec3 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); let mut values = dojo::model::Model::::get_member( @@ -2982,18 +3005,17 @@ pub impl BadModelUnexpectedArgWithValueModelEntityImpl of dojo::model::ModelEnti core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> BadModelUnexpectedArgWithValueEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let v = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `BadModelUnexpectedArgWithValueEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + BadModelUnexpectedArgWithValueEntity { + __id: entity_id, + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> BadModelUnexpectedArgWithValueEntity { @@ -3003,7 +3025,12 @@ pub impl BadModelUnexpectedArgWithValueModelEntityImpl of dojo::model::ModelEnti dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `BadModelUnexpectedArgWithValueEntity`: deserialization failed.") + } + } } fn update_entity(self: @BadModelUnexpectedArgWithValueEntity, world: dojo::world::IWorldDispatcher) { @@ -3074,7 +3101,12 @@ pub impl BadModelUnexpectedArgWithValueModelImpl of dojo::model::Model x, + Option::None => { + panic!("Model `BadModelUnexpectedArgWithValue`: deserialization failed.") + } + } } fn set_model( @@ -3189,7 +3221,7 @@ pub impl BadModelUnexpectedArgWithValueModelImpl of dojo::model::Model Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.id); + core::serde::Serde::serialize(self.id, ref serialized); core::array::ArrayTrait::span(@serialized) } @@ -3203,18 +3235,18 @@ pub impl BadModelUnexpectedArgWithValueModelImpl of dojo::model::Model dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @BadModelUnexpectedArgWithValue) -> dojo::model::Layout { + fn instance_layout(self: @BadModelUnexpectedArgWithValue) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -3259,19 +3291,19 @@ pub mod bad_model_unexpected_arg_with_value { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -3525,7 +3557,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -3544,7 +3576,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -3627,39 +3659,39 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl BadModelUnexpectedArgIntrospect<> of dojo::model::introspect::Introspect> { +impl BadModelUnexpectedArgIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 578691550836206188651404750433984985630363913126316857592149308417275000080, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'BadModelUnexpectedArg', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'v', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -3724,31 +3756,30 @@ pub impl BadModelUnexpectedArgEntityStoreImpl of BadModelUnexpectedArgEntityStor pub impl BadModelUnexpectedArgStoreImpl of BadModelUnexpectedArgStore { fn entity_id_from_keys(id: felt252) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> BadModelUnexpectedArg { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let id = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let v = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `BadModelUnexpectedArg`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + BadModelUnexpectedArg { + id, + + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> BadModelUnexpectedArg { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); dojo::model::Model::::get(world, serialized.span()) @@ -3765,7 +3796,7 @@ pub impl BadModelUnexpectedArgStoreImpl of BadModelUnexpectedArgStore { fn get_v(world: dojo::world::IWorldDispatcher, id: felt252) -> Vec3 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); let mut values = dojo::model::Model::::get_member( @@ -3810,18 +3841,17 @@ pub impl BadModelUnexpectedArgModelEntityImpl of dojo::model::ModelEntity) -> BadModelUnexpectedArgEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let v = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `BadModelUnexpectedArgEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + BadModelUnexpectedArgEntity { + __id: entity_id, + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> BadModelUnexpectedArgEntity { @@ -3831,7 +3861,12 @@ pub impl BadModelUnexpectedArgModelEntityImpl of dojo::model::ModelEntity::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `BadModelUnexpectedArgEntity`: deserialization failed.") + } + } } fn update_entity(self: @BadModelUnexpectedArgEntity, world: dojo::world::IWorldDispatcher) { @@ -3902,7 +3937,12 @@ pub impl BadModelUnexpectedArgModelImpl of dojo::model::Model x, + Option::None => { + panic!("Model `BadModelUnexpectedArg`: deserialization failed.") + } + } } fn set_model( @@ -4017,7 +4057,7 @@ pub impl BadModelUnexpectedArgModelImpl of dojo::model::Model Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.id); + core::serde::Serde::serialize(self.id, ref serialized); core::array::ArrayTrait::span(@serialized) } @@ -4031,18 +4071,18 @@ pub impl BadModelUnexpectedArgModelImpl of dojo::model::Model dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @BadModelUnexpectedArg) -> dojo::model::Layout { + fn instance_layout(self: @BadModelUnexpectedArg) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -4087,19 +4127,19 @@ pub mod bad_model_unexpected_arg { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -4353,7 +4393,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -4372,7 +4412,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -4455,39 +4495,39 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl BadModelNotSupportedVersionIntrospect<> of dojo::model::introspect::Introspect> { +impl BadModelNotSupportedVersionIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 578691550836206188651404750433984985630363913126316857592149308417275000080, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'BadModelNotSupportedVersion', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'v', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -4552,31 +4592,30 @@ pub impl BadModelNotSupportedVersionEntityStoreImpl of BadModelNotSupportedVersi pub impl BadModelNotSupportedVersionStoreImpl of BadModelNotSupportedVersionStore { fn entity_id_from_keys(id: felt252) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> BadModelNotSupportedVersion { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let id = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let v = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `BadModelNotSupportedVersion`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + BadModelNotSupportedVersion { + id, + + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> BadModelNotSupportedVersion { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); dojo::model::Model::::get(world, serialized.span()) @@ -4593,7 +4632,7 @@ pub impl BadModelNotSupportedVersionStoreImpl of BadModelNotSupportedVersionStor fn get_v(world: dojo::world::IWorldDispatcher, id: felt252) -> Vec3 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); let mut values = dojo::model::Model::::get_member( @@ -4638,18 +4677,17 @@ pub impl BadModelNotSupportedVersionModelEntityImpl of dojo::model::ModelEntity< core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> BadModelNotSupportedVersionEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let v = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `BadModelNotSupportedVersionEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + BadModelNotSupportedVersionEntity { + __id: entity_id, + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> BadModelNotSupportedVersionEntity { @@ -4659,7 +4697,12 @@ pub impl BadModelNotSupportedVersionModelEntityImpl of dojo::model::ModelEntity< dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `BadModelNotSupportedVersionEntity`: deserialization failed.") + } + } } fn update_entity(self: @BadModelNotSupportedVersionEntity, world: dojo::world::IWorldDispatcher) { @@ -4730,7 +4773,12 @@ pub impl BadModelNotSupportedVersionModelImpl of dojo::model::Model x, + Option::None => { + panic!("Model `BadModelNotSupportedVersion`: deserialization failed.") + } + } } fn set_model( @@ -4845,7 +4893,7 @@ pub impl BadModelNotSupportedVersionModelImpl of dojo::model::Model Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.id); + core::serde::Serde::serialize(self.id, ref serialized); core::array::ArrayTrait::span(@serialized) } @@ -4859,18 +4907,18 @@ pub impl BadModelNotSupportedVersionModelImpl of dojo::model::Model dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @BadModelNotSupportedVersion) -> dojo::model::Layout { + fn instance_layout(self: @BadModelNotSupportedVersion) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -4915,19 +4963,19 @@ pub mod bad_model_not_supported_version { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -5181,7 +5229,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -5200,7 +5248,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -5283,39 +5331,39 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl Modelv0Introspect<> of dojo::model::introspect::Introspect> { +impl Modelv0Introspect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 578691550836206188651404750433984985630363913126316857592149308417275000080, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'Modelv0', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'v', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -5380,31 +5428,30 @@ pub impl Modelv0EntityStoreImpl of Modelv0EntityStore { pub impl Modelv0StoreImpl of Modelv0Store { fn entity_id_from_keys(id: felt252) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> Modelv0 { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let id = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let v = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `Modelv0`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + Modelv0 { + id, + + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> Modelv0 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); dojo::model::Model::::get(world, serialized.span()) @@ -5421,7 +5468,7 @@ pub impl Modelv0StoreImpl of Modelv0Store { fn get_v(world: dojo::world::IWorldDispatcher, id: felt252) -> Vec3 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); let mut values = dojo::model::Model::::get_member( @@ -5466,18 +5513,17 @@ pub impl Modelv0ModelEntityImpl of dojo::model::ModelEntity { core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> Modelv0Entity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let v = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `Modelv0Entity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + Modelv0Entity { + __id: entity_id, + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> Modelv0Entity { @@ -5487,7 +5533,12 @@ pub impl Modelv0ModelEntityImpl of dojo::model::ModelEntity { dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `Modelv0Entity`: deserialization failed.") + } + } } fn update_entity(self: @Modelv0Entity, world: dojo::world::IWorldDispatcher) { @@ -5558,7 +5609,12 @@ pub impl Modelv0ModelImpl of dojo::model::Model { ); let mut _keys = keys; - Modelv0Store::from_values(ref _keys, ref values) + match Modelv0Store::from_values(ref _keys, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("Model `Modelv0`: deserialization failed.") + } + } } fn set_model( @@ -5673,7 +5729,7 @@ pub impl Modelv0ModelImpl of dojo::model::Model { #[inline(always)] fn keys(self: @Modelv0) -> Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.id); + core::serde::Serde::serialize(self.id, ref serialized); core::array::ArrayTrait::span(@serialized) } @@ -5687,18 +5743,18 @@ pub impl Modelv0ModelImpl of dojo::model::Model { } #[inline(always)] - fn layout() -> dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @Modelv0) -> dojo::model::Layout { + fn instance_layout(self: @Modelv0) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -5743,19 +5799,19 @@ pub mod modelv_0 { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -6009,7 +6065,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -6028,7 +6084,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -6111,39 +6167,39 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl ModelWithBadNamespaceFormatIntrospect<> of dojo::model::introspect::Introspect> { +impl ModelWithBadNamespaceFormatIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 578691550836206188651404750433984985630363913126316857592149308417275000080, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'ModelWithBadNamespaceFormat', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'v', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -6208,31 +6264,30 @@ pub impl ModelWithBadNamespaceFormatEntityStoreImpl of ModelWithBadNamespaceForm pub impl ModelWithBadNamespaceFormatStoreImpl of ModelWithBadNamespaceFormatStore { fn entity_id_from_keys(id: felt252) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> ModelWithBadNamespaceFormat { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let id = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let v = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `ModelWithBadNamespaceFormat`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + ModelWithBadNamespaceFormat { + id, + + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> ModelWithBadNamespaceFormat { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); dojo::model::Model::::get(world, serialized.span()) @@ -6249,7 +6304,7 @@ pub impl ModelWithBadNamespaceFormatStoreImpl of ModelWithBadNamespaceFormatStor fn get_v(world: dojo::world::IWorldDispatcher, id: felt252) -> Vec3 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); let mut values = dojo::model::Model::::get_member( @@ -6294,18 +6349,17 @@ pub impl ModelWithBadNamespaceFormatModelEntityImpl of dojo::model::ModelEntity< core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> ModelWithBadNamespaceFormatEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let v = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `ModelWithBadNamespaceFormatEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + ModelWithBadNamespaceFormatEntity { + __id: entity_id, + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> ModelWithBadNamespaceFormatEntity { @@ -6315,7 +6369,12 @@ pub impl ModelWithBadNamespaceFormatModelEntityImpl of dojo::model::ModelEntity< dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `ModelWithBadNamespaceFormatEntity`: deserialization failed.") + } + } } fn update_entity(self: @ModelWithBadNamespaceFormatEntity, world: dojo::world::IWorldDispatcher) { @@ -6386,7 +6445,12 @@ pub impl ModelWithBadNamespaceFormatModelImpl of dojo::model::Model x, + Option::None => { + panic!("Model `ModelWithBadNamespaceFormat`: deserialization failed.") + } + } } fn set_model( @@ -6501,7 +6565,7 @@ pub impl ModelWithBadNamespaceFormatModelImpl of dojo::model::Model Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.id); + core::serde::Serde::serialize(self.id, ref serialized); core::array::ArrayTrait::span(@serialized) } @@ -6515,18 +6579,18 @@ pub impl ModelWithBadNamespaceFormatModelImpl of dojo::model::Model dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @ModelWithBadNamespaceFormat) -> dojo::model::Layout { + fn instance_layout(self: @ModelWithBadNamespaceFormat) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -6571,19 +6635,19 @@ pub mod model_with_bad_namespace_format { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -6837,7 +6901,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -6856,7 +6920,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -6939,39 +7003,39 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl ModelWithShortStringNamespaceIntrospect<> of dojo::model::introspect::Introspect> { +impl ModelWithShortStringNamespaceIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 578691550836206188651404750433984985630363913126316857592149308417275000080, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'ModelWithShortStringNamespace', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'v', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -7036,31 +7100,30 @@ pub impl ModelWithShortStringNamespaceEntityStoreImpl of ModelWithShortStringNam pub impl ModelWithShortStringNamespaceStoreImpl of ModelWithShortStringNamespaceStore { fn entity_id_from_keys(id: felt252) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> ModelWithShortStringNamespace { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let id = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let v = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `ModelWithShortStringNamespace`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + ModelWithShortStringNamespace { + id, + + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> ModelWithShortStringNamespace { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); dojo::model::Model::::get(world, serialized.span()) @@ -7077,7 +7140,7 @@ pub impl ModelWithShortStringNamespaceStoreImpl of ModelWithShortStringNamespace fn get_v(world: dojo::world::IWorldDispatcher, id: felt252) -> Vec3 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); let mut values = dojo::model::Model::::get_member( @@ -7122,18 +7185,17 @@ pub impl ModelWithShortStringNamespaceModelEntityImpl of dojo::model::ModelEntit core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> ModelWithShortStringNamespaceEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let v = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `ModelWithShortStringNamespaceEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + ModelWithShortStringNamespaceEntity { + __id: entity_id, + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> ModelWithShortStringNamespaceEntity { @@ -7143,7 +7205,12 @@ pub impl ModelWithShortStringNamespaceModelEntityImpl of dojo::model::ModelEntit dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `ModelWithShortStringNamespaceEntity`: deserialization failed.") + } + } } fn update_entity(self: @ModelWithShortStringNamespaceEntity, world: dojo::world::IWorldDispatcher) { @@ -7214,7 +7281,12 @@ pub impl ModelWithShortStringNamespaceModelImpl of dojo::model::Model x, + Option::None => { + panic!("Model `ModelWithShortStringNamespace`: deserialization failed.") + } + } } fn set_model( @@ -7329,7 +7401,7 @@ pub impl ModelWithShortStringNamespaceModelImpl of dojo::model::Model Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.id); + core::serde::Serde::serialize(self.id, ref serialized); core::array::ArrayTrait::span(@serialized) } @@ -7343,18 +7415,18 @@ pub impl ModelWithShortStringNamespaceModelImpl of dojo::model::Model dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @ModelWithShortStringNamespace) -> dojo::model::Layout { + fn instance_layout(self: @ModelWithShortStringNamespace) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -7399,19 +7471,19 @@ pub mod model_with_short_string_namespace { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -7665,7 +7737,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -7684,7 +7756,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -7767,39 +7839,39 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl ModelWithStringNamespaceIntrospect<> of dojo::model::introspect::Introspect> { +impl ModelWithStringNamespaceIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 578691550836206188651404750433984985630363913126316857592149308417275000080, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'ModelWithStringNamespace', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'v', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -7864,31 +7936,30 @@ pub impl ModelWithStringNamespaceEntityStoreImpl of ModelWithStringNamespaceEnti pub impl ModelWithStringNamespaceStoreImpl of ModelWithStringNamespaceStore { fn entity_id_from_keys(id: felt252) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> ModelWithStringNamespace { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let id = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let v = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `ModelWithStringNamespace`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + ModelWithStringNamespace { + id, + + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> ModelWithStringNamespace { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); dojo::model::Model::::get(world, serialized.span()) @@ -7905,7 +7976,7 @@ pub impl ModelWithStringNamespaceStoreImpl of ModelWithStringNamespaceStore { fn get_v(world: dojo::world::IWorldDispatcher, id: felt252) -> Vec3 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); let mut values = dojo::model::Model::::get_member( @@ -7950,18 +8021,17 @@ pub impl ModelWithStringNamespaceModelEntityImpl of dojo::model::ModelEntity) -> ModelWithStringNamespaceEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let v = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `ModelWithStringNamespaceEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + ModelWithStringNamespaceEntity { + __id: entity_id, + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> ModelWithStringNamespaceEntity { @@ -7971,7 +8041,12 @@ pub impl ModelWithStringNamespaceModelEntityImpl of dojo::model::ModelEntity::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `ModelWithStringNamespaceEntity`: deserialization failed.") + } + } } fn update_entity(self: @ModelWithStringNamespaceEntity, world: dojo::world::IWorldDispatcher) { @@ -8042,7 +8117,12 @@ pub impl ModelWithStringNamespaceModelImpl of dojo::model::Model x, + Option::None => { + panic!("Model `ModelWithStringNamespace`: deserialization failed.") + } + } } fn set_model( @@ -8157,7 +8237,7 @@ pub impl ModelWithStringNamespaceModelImpl of dojo::model::Model Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.id); + core::serde::Serde::serialize(self.id, ref serialized); core::array::ArrayTrait::span(@serialized) } @@ -8171,18 +8251,18 @@ pub impl ModelWithStringNamespaceModelImpl of dojo::model::Model dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @ModelWithStringNamespace) -> dojo::model::Layout { + fn instance_layout(self: @ModelWithStringNamespace) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -8227,19 +8307,19 @@ pub mod model_with_string_namespace { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -8493,7 +8573,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -8512,7 +8592,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -8595,39 +8675,39 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl PositionIntrospect<> of dojo::model::introspect::Introspect> { +impl PositionIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 578691550836206188651404750433984985630363913126316857592149308417275000080, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'Position', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'v', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -8692,31 +8772,30 @@ pub impl PositionEntityStoreImpl of PositionEntityStore { pub impl PositionStoreImpl of PositionStore { fn entity_id_from_keys(id: felt252) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> Position { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let id = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let v = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `Position`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + Position { + id, + + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> Position { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); dojo::model::Model::::get(world, serialized.span()) @@ -8733,7 +8812,7 @@ pub impl PositionStoreImpl of PositionStore { fn get_v(world: dojo::world::IWorldDispatcher, id: felt252) -> Vec3 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); let mut values = dojo::model::Model::::get_member( @@ -8778,18 +8857,17 @@ pub impl PositionModelEntityImpl of dojo::model::ModelEntity { core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> PositionEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let v = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `PositionEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + PositionEntity { + __id: entity_id, + v, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> PositionEntity { @@ -8799,7 +8877,12 @@ pub impl PositionModelEntityImpl of dojo::model::ModelEntity { dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `PositionEntity`: deserialization failed.") + } + } } fn update_entity(self: @PositionEntity, world: dojo::world::IWorldDispatcher) { @@ -8870,7 +8953,12 @@ pub impl PositionModelImpl of dojo::model::Model { ); let mut _keys = keys; - PositionStore::from_values(ref _keys, ref values) + match PositionStore::from_values(ref _keys, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("Model `Position`: deserialization failed.") + } + } } fn set_model( @@ -8985,7 +9073,7 @@ pub impl PositionModelImpl of dojo::model::Model { #[inline(always)] fn keys(self: @Position) -> Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.id); + core::serde::Serde::serialize(self.id, ref serialized); core::array::ArrayTrait::span(@serialized) } @@ -8999,18 +9087,18 @@ pub impl PositionModelImpl of dojo::model::Model { } #[inline(always)] - fn layout() -> dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @Position) -> dojo::model::Layout { + fn instance_layout(self: @Position) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -9055,19 +9143,19 @@ pub mod position { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -9321,7 +9409,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -9340,7 +9428,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -9423,18 +9511,18 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl RolesIntrospect<> of dojo::model::introspect::Introspect> { +impl RolesIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 387776731289756409274549987067854286905927440612427426920343953432870065647, - layout: dojo::model::introspect::Introspect:: + layout: dojo::meta::introspect::Introspect:: >::layout() } ].span() @@ -9442,18 +9530,18 @@ impl RolesIntrospect<> of dojo::model::introspect::Introspect> { } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'Roles', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'role_ids', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Array( + ty: dojo::meta::introspect::Ty::Array( array![ - dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty() ].span() ) } @@ -9524,21 +9612,18 @@ pub impl RolesStoreImpl of RolesStore { core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> Roles { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + + let role_ids = core::serde::Serde::>::deserialize(ref values)?; - let entity = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `Roles`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } + Option::Some( + Roles { + + role_ids, - core::option::OptionTrait::::unwrap(entity) + } + ) } fn get(world: dojo::world::IWorldDispatcher, ) -> Roles { @@ -9603,18 +9688,17 @@ pub impl RolesModelEntityImpl of dojo::model::ModelEntity { core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> RolesEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let role_ids = core::serde::Serde::>::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `RolesEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + RolesEntity { + __id: entity_id, + role_ids, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> RolesEntity { @@ -9624,7 +9708,12 @@ pub impl RolesModelEntityImpl of dojo::model::ModelEntity { dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `RolesEntity`: deserialization failed.") + } + } } fn update_entity(self: @RolesEntity, world: dojo::world::IWorldDispatcher) { @@ -9695,7 +9784,12 @@ pub impl RolesModelImpl of dojo::model::Model { ); let mut _keys = keys; - RolesStore::from_values(ref _keys, ref values) + match RolesStore::from_values(ref _keys, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("Model `Roles`: deserialization failed.") + } + } } fn set_model( @@ -9823,18 +9917,18 @@ pub impl RolesModelImpl of dojo::model::Model { } #[inline(always)] - fn layout() -> dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @Roles) -> dojo::model::Layout { + fn instance_layout(self: @Roles) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -9879,19 +9973,19 @@ pub mod roles { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -10145,7 +10239,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -10164,7 +10258,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -10247,14 +10341,14 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl OnlyKeyModelIntrospect<> of dojo::model::introspect::Introspect> { +impl OnlyKeyModelIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ ].span() @@ -10262,16 +10356,16 @@ impl OnlyKeyModelIntrospect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'OnlyKeyModel', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -10307,31 +10401,28 @@ pub impl OnlyKeyModelEntityStoreImpl of OnlyKeyModelEntityStore { pub impl OnlyKeyModelStoreImpl of OnlyKeyModelStore { fn entity_id_from_keys(id: felt252) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> OnlyKeyModel { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let id = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `OnlyKeyModel`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } + Option::Some( + OnlyKeyModel { + id, - core::option::OptionTrait::::unwrap(entity) + + } + ) } fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> OnlyKeyModel { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, id); + core::serde::Serde::serialize(@id, ref serialized); dojo::model::Model::::get(world, serialized.span()) @@ -10359,18 +10450,15 @@ pub impl OnlyKeyModelModelEntityImpl of dojo::model::ModelEntity) -> OnlyKeyModelEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `OnlyKeyModelEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + Option::Some( + OnlyKeyModelEntity { + __id: entity_id, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> OnlyKeyModelEntity { @@ -10380,7 +10468,12 @@ pub impl OnlyKeyModelModelEntityImpl of dojo::model::ModelEntity::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `OnlyKeyModelEntity`: deserialization failed.") + } + } } fn update_entity(self: @OnlyKeyModelEntity, world: dojo::world::IWorldDispatcher) { @@ -10451,7 +10544,12 @@ pub impl OnlyKeyModelModelImpl of dojo::model::Model { ); let mut _keys = keys; - OnlyKeyModelStore::from_values(ref _keys, ref values) + match OnlyKeyModelStore::from_values(ref _keys, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("Model `OnlyKeyModel`: deserialization failed.") + } + } } fn set_model( @@ -10566,7 +10664,7 @@ pub impl OnlyKeyModelModelImpl of dojo::model::Model { #[inline(always)] fn keys(self: @OnlyKeyModel) -> Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.id); + core::serde::Serde::serialize(self.id, ref serialized); core::array::ArrayTrait::span(@serialized) } @@ -10579,18 +10677,18 @@ pub impl OnlyKeyModelModelImpl of dojo::model::Model { } #[inline(always)] - fn layout() -> dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @OnlyKeyModel) -> dojo::model::Layout { + fn instance_layout(self: @OnlyKeyModel) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -10635,19 +10733,19 @@ pub mod only_key_model { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -10901,7 +10999,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -10920,7 +11018,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -11003,14 +11101,14 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl U256KeyModelIntrospect<> of dojo::model::introspect::Introspect> { +impl U256KeyModelIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ ].span() @@ -11018,16 +11116,16 @@ impl U256KeyModelIntrospect<> of dojo::model::introspect::Introspect dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'U256KeyModel', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'id', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -11061,34 +11159,27 @@ pub impl U256KeyModelEntityStoreImpl of U256KeyModelEntityStore { #[generate_trait] pub impl U256KeyModelStoreImpl of U256KeyModelStore { - fn entity_id_from_keys(id: u256) -> felt252 { + fn entity_id_from_keys() -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::serde::Serde::serialize(@id, ref serialized); - + core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> U256KeyModel { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); - - let entity = core::serde::Serde::::deserialize(ref serialized); - - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `U256KeyModel`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } + fn from_values(ref keys: Span, ref values: Span) -> Option { + + - core::option::OptionTrait::::unwrap(entity) + Option::Some( + U256KeyModel { + + + } + ) } - fn get(world: dojo::world::IWorldDispatcher, id: u256) -> U256KeyModel { + fn get(world: dojo::world::IWorldDispatcher, ) -> U256KeyModel { let mut serialized = core::array::ArrayTrait::new(); - core::serde::Serde::serialize(@id, ref serialized); - + dojo::model::Model::::get(world, serialized.span()) } @@ -11115,18 +11206,15 @@ pub impl U256KeyModelModelEntityImpl of dojo::model::ModelEntity) -> U256KeyModelEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `U256KeyModelEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + Option::Some( + U256KeyModelEntity { + __id: entity_id, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> U256KeyModelEntity { @@ -11136,7 +11224,12 @@ pub impl U256KeyModelModelEntityImpl of dojo::model::ModelEntity::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `U256KeyModelEntity`: deserialization failed.") + } + } } fn update_entity(self: @U256KeyModelEntity, world: dojo::world::IWorldDispatcher) { @@ -11207,7 +11300,12 @@ pub impl U256KeyModelModelImpl of dojo::model::Model { ); let mut _keys = keys; - U256KeyModelStore::from_values(ref _keys, ref values) + match U256KeyModelStore::from_values(ref _keys, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("Model `U256KeyModel`: deserialization failed.") + } + } } fn set_model( @@ -11322,8 +11420,7 @@ pub impl U256KeyModelModelImpl of dojo::model::Model { #[inline(always)] fn keys(self: @U256KeyModel) -> Span { let mut serialized = core::array::ArrayTrait::new(); - core::serde::Serde::serialize(self.id, ref serialized); - + core::array::ArrayTrait::span(@serialized) } @@ -11335,18 +11432,18 @@ pub impl U256KeyModelModelImpl of dojo::model::Model { } #[inline(always)] - fn layout() -> dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @U256KeyModel) -> dojo::model::Layout { + fn instance_layout(self: @U256KeyModel) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -11391,19 +11488,19 @@ pub mod u_256_key_model { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -11657,7 +11754,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -11676,7 +11773,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -11759,44 +11856,44 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl PlayerIntrospect<> of dojo::model::introspect::Introspect> { +impl PlayerIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(1) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 1528802474226268325865027367859591458315299653151958663884057507666229546336, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() } ].span() ) } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'Player', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'game', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'name', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() } ].span() @@ -11861,32 +11958,33 @@ pub impl PlayerEntityStoreImpl of PlayerEntityStore { pub impl PlayerStoreImpl of PlayerStore { fn entity_id_from_keys(game: felt252, player: ContractAddress) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, game); + core::serde::Serde::serialize(@game, ref serialized); core::serde::Serde::serialize(@player, ref serialized); core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> Player { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let game = core::serde::Serde::::deserialize(ref keys)?; +let player = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let name = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `Player`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + Player { + game, +player, + + name, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, game: felt252, player: ContractAddress) -> Player { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, game); + core::serde::Serde::serialize(@game, ref serialized); core::serde::Serde::serialize(@player, ref serialized); @@ -11904,7 +12002,7 @@ core::serde::Serde::serialize(@player, ref serialized); fn get_name(world: dojo::world::IWorldDispatcher, game: felt252, player: ContractAddress) -> felt252 { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, game); + core::serde::Serde::serialize(@game, ref serialized); core::serde::Serde::serialize(@player, ref serialized); @@ -11945,23 +12043,22 @@ pub impl PlayerModelEntityImpl of dojo::model::ModelEntity { fn values(self: @PlayerEntity) -> Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.name); + core::serde::Serde::serialize(self.name, ref serialized); core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> PlayerEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let name = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `PlayerEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + PlayerEntity { + __id: entity_id, + name, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> PlayerEntity { @@ -11971,7 +12068,12 @@ pub impl PlayerModelEntityImpl of dojo::model::ModelEntity { dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `PlayerEntity`: deserialization failed.") + } + } } fn update_entity(self: @PlayerEntity, world: dojo::world::IWorldDispatcher) { @@ -12042,7 +12144,12 @@ pub impl PlayerModelImpl of dojo::model::Model { ); let mut _keys = keys; - PlayerStore::from_values(ref _keys, ref values) + match PlayerStore::from_values(ref _keys, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("Model `Player`: deserialization failed.") + } + } } fn set_model( @@ -12157,7 +12264,7 @@ pub impl PlayerModelImpl of dojo::model::Model { #[inline(always)] fn keys(self: @Player) -> Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.game); + core::serde::Serde::serialize(self.game, ref serialized); core::serde::Serde::serialize(self.player, ref serialized); core::array::ArrayTrait::span(@serialized) @@ -12166,24 +12273,24 @@ core::serde::Serde::serialize(self.player, ref serialized); #[inline(always)] fn values(self: @Player) -> Span { let mut serialized = core::array::ArrayTrait::new(); - core::array::ArrayTrait::append(ref serialized, *self.name); + core::serde::Serde::serialize(self.name, ref serialized); core::array::ArrayTrait::span(@serialized) } #[inline(always)] - fn layout() -> dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @Player) -> dojo::model::Layout { + fn instance_layout(self: @Player) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -12228,19 +12335,19 @@ pub mod player { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -12494,7 +12601,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -12513,7 +12620,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -12596,22 +12703,22 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl ModelWithSimpleArrayIntrospect<> of dojo::model::introspect::Introspect> { +impl ModelWithSimpleArrayIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 512066735765477566404754172672287371265995314501343422459174036873487219331, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1591024729085637502504777720563487898377940395575083379770417352976841400819, - layout: dojo::model::introspect::Introspect:: + layout: dojo::meta::introspect::Introspect:: >::layout() } ].span() @@ -12619,28 +12726,28 @@ dojo::model::FieldLayout { } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'ModelWithSimpleArray', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'x', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'y', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Array( + ty: dojo::meta::introspect::Ty::Array( array![ - dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty() ].span() ) } @@ -12741,21 +12848,22 @@ pub impl ModelWithSimpleArrayStoreImpl of ModelWithSimpleArrayStore { core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> ModelWithSimpleArray { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let player = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let x = core::serde::Serde::::deserialize(ref values)?; +let y = core::serde::Serde::>::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `ModelWithSimpleArray`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + ModelWithSimpleArray { + player, + + x, +y, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, player: ContractAddress) -> ModelWithSimpleArray { @@ -12856,18 +12964,19 @@ core::serde::Serde::serialize(self.y, ref serialized); core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> ModelWithSimpleArrayEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let x = core::serde::Serde::::deserialize(ref values)?; +let y = core::serde::Serde::>::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `ModelWithSimpleArrayEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + ModelWithSimpleArrayEntity { + __id: entity_id, + x, +y, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> ModelWithSimpleArrayEntity { @@ -12877,7 +12986,12 @@ core::serde::Serde::serialize(self.y, ref serialized); dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `ModelWithSimpleArrayEntity`: deserialization failed.") + } + } } fn update_entity(self: @ModelWithSimpleArrayEntity, world: dojo::world::IWorldDispatcher) { @@ -12948,7 +13062,12 @@ pub impl ModelWithSimpleArrayModelImpl of dojo::model::Model x, + Option::None => { + panic!("Model `ModelWithSimpleArray`: deserialization failed.") + } + } } fn set_model( @@ -13078,18 +13197,18 @@ core::serde::Serde::serialize(self.y, ref serialized); } #[inline(always)] - fn layout() -> dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @ModelWithSimpleArray) -> dojo::model::Layout { + fn instance_layout(self: @ModelWithSimpleArray) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -13134,19 +13253,19 @@ pub mod model_with_simple_array { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -13400,7 +13519,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -13419,7 +13538,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -13502,22 +13621,22 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl ModelWithByteArrayIntrospect<> of dojo::model::introspect::Introspect> { +impl ModelWithByteArrayIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 512066735765477566404754172672287371265995314501343422459174036873487219331, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1591024729085637502504777720563487898377940395575083379770417352976841400819, - layout: dojo::model::introspect::Introspect::::layout() } ].span() @@ -13525,26 +13644,26 @@ dojo::model::FieldLayout { } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'ModelWithByteArray', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'x', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'y', attrs: array![].span(), - ty: dojo::model::introspect::Ty::ByteArray + ty: dojo::meta::introspect::Ty::ByteArray } ].span() @@ -13643,21 +13762,22 @@ pub impl ModelWithByteArrayStoreImpl of ModelWithByteArrayStore { core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> ModelWithByteArray { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let player = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let x = core::serde::Serde::::deserialize(ref values)?; +let y = core::serde::Serde::::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `ModelWithByteArray`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + ModelWithByteArray { + player, + + x, +y, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, player: ContractAddress) -> ModelWithByteArray { @@ -13758,18 +13878,19 @@ core::serde::Serde::serialize(self.y, ref serialized); core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> ModelWithByteArrayEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let x = core::serde::Serde::::deserialize(ref values)?; +let y = core::serde::Serde::::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `ModelWithByteArrayEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + ModelWithByteArrayEntity { + __id: entity_id, + x, +y, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> ModelWithByteArrayEntity { @@ -13779,7 +13900,12 @@ core::serde::Serde::serialize(self.y, ref serialized); dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `ModelWithByteArrayEntity`: deserialization failed.") + } + } } fn update_entity(self: @ModelWithByteArrayEntity, world: dojo::world::IWorldDispatcher) { @@ -13850,7 +13976,12 @@ pub impl ModelWithByteArrayModelImpl of dojo::model::Model { ); let mut _keys = keys; - ModelWithByteArrayStore::from_values(ref _keys, ref values) + match ModelWithByteArrayStore::from_values(ref _keys, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("Model `ModelWithByteArray`: deserialization failed.") + } + } } fn set_model( @@ -13980,18 +14111,18 @@ core::serde::Serde::serialize(self.y, ref serialized); } #[inline(always)] - fn layout() -> dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @ModelWithByteArray) -> dojo::model::Layout { + fn instance_layout(self: @ModelWithByteArray) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -14036,19 +14167,19 @@ pub mod model_with_byte_array { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -14302,7 +14433,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -14321,7 +14452,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -14404,22 +14535,22 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl ModelWithComplexArrayIntrospect<> of dojo::model::introspect::Introspect> { +impl ModelWithComplexArrayIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::None } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 512066735765477566404754172672287371265995314501343422459174036873487219331, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1591024729085637502504777720563487898377940395575083379770417352976841400819, - layout: dojo::model::introspect::Introspect:: + layout: dojo::meta::introspect::Introspect:: >::layout() } ].span() @@ -14427,28 +14558,28 @@ dojo::model::FieldLayout { } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'ModelWithComplexArray', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'x', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'y', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Array( + ty: dojo::meta::introspect::Ty::Array( array![ - dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty() ].span() ) } @@ -14549,21 +14680,22 @@ pub impl ModelWithComplexArrayStoreImpl of ModelWithComplexArrayStore { core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> ModelWithComplexArray { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let player = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let x = core::serde::Serde::::deserialize(ref values)?; +let y = core::serde::Serde::>::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `ModelWithComplexArray`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + ModelWithComplexArray { + player, + + x, +y, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, player: ContractAddress) -> ModelWithComplexArray { @@ -14664,18 +14796,19 @@ core::serde::Serde::serialize(self.y, ref serialized); core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> ModelWithComplexArrayEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let x = core::serde::Serde::::deserialize(ref values)?; +let y = core::serde::Serde::>::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `ModelWithComplexArrayEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + ModelWithComplexArrayEntity { + __id: entity_id, + x, +y, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> ModelWithComplexArrayEntity { @@ -14685,7 +14818,12 @@ core::serde::Serde::serialize(self.y, ref serialized); dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `ModelWithComplexArrayEntity`: deserialization failed.") + } + } } fn update_entity(self: @ModelWithComplexArrayEntity, world: dojo::world::IWorldDispatcher) { @@ -14756,7 +14894,12 @@ pub impl ModelWithComplexArrayModelImpl of dojo::model::Model x, + Option::None => { + panic!("Model `ModelWithComplexArray`: deserialization failed.") + } + } } fn set_model( @@ -14886,18 +15029,18 @@ core::serde::Serde::serialize(self.y, ref serialized); } #[inline(always)] - fn layout() -> dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @ModelWithComplexArray) -> dojo::model::Layout { + fn instance_layout(self: @ModelWithComplexArray) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -14942,19 +15085,19 @@ pub mod model_with_complex_array { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -15208,7 +15351,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -15227,7 +15370,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -15310,26 +15453,26 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl ModelWithTupleIntrospect<> of dojo::model::introspect::Introspect> { +impl ModelWithTupleIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { Option::Some(4) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 512066735765477566404754172672287371265995314501343422459174036873487219331, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1591024729085637502504777720563487898377940395575083379770417352976841400819, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) } @@ -15338,30 +15481,30 @@ dojo::model::introspect::Introspect::::layout() } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'ModelWithTuple', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'x', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'y', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Tuple( + ty: dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() ) } @@ -15462,21 +15605,22 @@ pub impl ModelWithTupleStoreImpl of ModelWithTupleStore { core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> ModelWithTuple { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let player = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let x = core::serde::Serde::::deserialize(ref values)?; +let y = core::serde::Serde::<(u8, u16, u32)>::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `ModelWithTuple`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + ModelWithTuple { + player, + + x, +y, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, player: ContractAddress) -> ModelWithTuple { @@ -15577,18 +15721,19 @@ core::serde::Serde::serialize(self.y, ref serialized); core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> ModelWithTupleEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let x = core::serde::Serde::::deserialize(ref values)?; +let y = core::serde::Serde::<(u8, u16, u32)>::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `ModelWithTupleEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + ModelWithTupleEntity { + __id: entity_id, + x, +y, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> ModelWithTupleEntity { @@ -15598,7 +15743,12 @@ core::serde::Serde::serialize(self.y, ref serialized); dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `ModelWithTupleEntity`: deserialization failed.") + } + } } fn update_entity(self: @ModelWithTupleEntity, world: dojo::world::IWorldDispatcher) { @@ -15669,7 +15819,12 @@ pub impl ModelWithTupleModelImpl of dojo::model::Model { ); let mut _keys = keys; - ModelWithTupleStore::from_values(ref _keys, ref values) + match ModelWithTupleStore::from_values(ref _keys, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("Model `ModelWithTuple`: deserialization failed.") + } + } } fn set_model( @@ -15799,18 +15954,18 @@ core::serde::Serde::serialize(self.y, ref serialized); } #[inline(always)] - fn layout() -> dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @ModelWithTuple) -> dojo::model::Layout { + fn instance_layout(self: @ModelWithTuple) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -15855,19 +16010,19 @@ pub mod model_with_tuple { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -16121,7 +16276,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -16140,7 +16295,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -16223,11 +16378,11 @@ impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } -impl ModelWithTupleNoPrimitivesIntrospect<> of dojo::model::introspect::Introspect> { +impl ModelWithTupleNoPrimitivesIntrospect<> of dojo::meta::introspect::Introspect> { #[inline(always)] fn size() -> Option { let sizes : Array> = array![ - dojo::model::introspect::Introspect::::size(), + dojo::meta::introspect::Introspect::::size(), Option::Some(3) ]; @@ -16238,20 +16393,20 @@ Option::Some(3) } - fn layout() -> dojo::model::Layout { - dojo::model::Layout::Struct( + fn layout() -> dojo::meta::Layout { + dojo::meta::Layout::Struct( array![ - dojo::model::FieldLayout { + dojo::meta::FieldLayout { selector: 512066735765477566404754172672287371265995314501343422459174036873487219331, - layout: dojo::model::introspect::Introspect::::layout() + layout: dojo::meta::introspect::Introspect::::layout() }, -dojo::model::FieldLayout { +dojo::meta::FieldLayout { selector: 1591024729085637502504777720563487898377940395575083379770417352976841400819, - layout: dojo::model::Layout::Tuple( + layout: dojo::meta::Layout::Tuple( array![ - dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout(), -dojo::model::introspect::Introspect::::layout() + dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout(), +dojo::meta::introspect::Introspect::::layout() ].span() ) } @@ -16260,30 +16415,30 @@ dojo::model::introspect::Introspect::::layout() } #[inline(always)] - fn ty() -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Struct( - dojo::model::introspect::Struct { + fn ty() -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Struct( + dojo::meta::introspect::Struct { name: 'ModelWithTupleNoPrimitives', attrs: array![].span(), children: array![ - dojo::model::introspect::Member { + dojo::meta::introspect::Member { name: 'player', attrs: array!['key'].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'x', attrs: array![].span(), - ty: dojo::model::introspect::Introspect::::ty() + ty: dojo::meta::introspect::Introspect::::ty() }, -dojo::model::introspect::Member { +dojo::meta::introspect::Member { name: 'y', attrs: array![].span(), - ty: dojo::model::introspect::Ty::Tuple( + ty: dojo::meta::introspect::Ty::Tuple( array![ - dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty(), -dojo::model::introspect::Introspect::::ty() + dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty(), +dojo::meta::introspect::Introspect::::ty() ].span() ) } @@ -16384,21 +16539,22 @@ pub impl ModelWithTupleNoPrimitivesStoreImpl of ModelWithTupleNoPrimitivesStore core::poseidon::poseidon_hash_span(serialized.span()) } - fn from_values(ref keys: Span, ref values: Span) -> ModelWithTupleNoPrimitives { - let mut serialized = core::array::ArrayTrait::new(); - serialized.append_span(keys); - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(ref keys: Span, ref values: Span) -> Option { + let player = core::serde::Serde::::deserialize(ref keys)?; - let entity = core::serde::Serde::::deserialize(ref serialized); + let x = core::serde::Serde::::deserialize(ref values)?; +let y = core::serde::Serde::<(u8, Vec3, u32)>::deserialize(ref values)?; - if core::option::OptionTrait::::is_none(@entity) { - panic!( - "Model `ModelWithTupleNoPrimitives`: deserialization failed. Ensure the length of the keys tuple is matching the number of #[key] fields in the model struct." - ); - } - core::option::OptionTrait::::unwrap(entity) + Option::Some( + ModelWithTupleNoPrimitives { + player, + + x, +y, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, player: ContractAddress) -> ModelWithTupleNoPrimitives { @@ -16499,18 +16655,19 @@ core::serde::Serde::serialize(self.y, ref serialized); core::array::ArrayTrait::span(@serialized) } - fn from_values(entity_id: felt252, ref values: Span) -> ModelWithTupleNoPrimitivesEntity { - let mut serialized = array![entity_id]; - serialized.append_span(values); - let mut serialized = core::array::ArrayTrait::span(@serialized); + fn from_values(entity_id: felt252, ref values: Span) -> Option { + let x = core::serde::Serde::::deserialize(ref values)?; +let y = core::serde::Serde::<(u8, Vec3, u32)>::deserialize(ref values)?; - let entity_values = core::serde::Serde::::deserialize(ref serialized); - if core::option::OptionTrait::::is_none(@entity_values) { - panic!( - "ModelEntity `ModelWithTupleNoPrimitivesEntity`: deserialization failed." - ); - } - core::option::OptionTrait::::unwrap(entity_values) + + Option::Some( + ModelWithTupleNoPrimitivesEntity { + __id: entity_id, + x, +y, + + } + ) } fn get(world: dojo::world::IWorldDispatcher, entity_id: felt252) -> ModelWithTupleNoPrimitivesEntity { @@ -16520,7 +16677,12 @@ core::serde::Serde::serialize(self.y, ref serialized); dojo::model::ModelIndex::Id(entity_id), dojo::model::Model::::layout() ); - Self::from_values(entity_id, ref values) + match Self::from_values(entity_id, ref values) { + Option::Some(x) => x, + Option::None => { + panic!("ModelEntity `ModelWithTupleNoPrimitivesEntity`: deserialization failed.") + } + } } fn update_entity(self: @ModelWithTupleNoPrimitivesEntity, world: dojo::world::IWorldDispatcher) { @@ -16591,7 +16753,12 @@ pub impl ModelWithTupleNoPrimitivesModelImpl of dojo::model::Model x, + Option::None => { + panic!("Model `ModelWithTupleNoPrimitives`: deserialization failed.") + } + } } fn set_model( @@ -16721,18 +16888,18 @@ core::serde::Serde::serialize(self.y, ref serialized); } #[inline(always)] - fn layout() -> dojo::model::Layout { - dojo::model::introspect::Introspect::::layout() + fn layout() -> dojo::meta::Layout { + dojo::meta::introspect::Introspect::::layout() } #[inline(always)] - fn instance_layout(self: @ModelWithTupleNoPrimitives) -> dojo::model::Layout { + fn instance_layout(self: @ModelWithTupleNoPrimitives) -> dojo::meta::Layout { Self::layout() } #[inline(always)] fn packed_size() -> Option { - dojo::model::layout::compute_packed_size(Self::layout()) + dojo::meta::layout::compute_packed_size(Self::layout()) } } @@ -16777,19 +16944,19 @@ pub mod model_with_tuple_no_primitives { } fn unpacked_size(self: @ContractState) -> Option { - dojo::model::introspect::Introspect::::size() + dojo::meta::introspect::Introspect::::size() } fn packed_size(self: @ContractState) -> Option { dojo::model::Model::::packed_size() } - fn layout(self: @ContractState) -> dojo::model::Layout { + fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::model::Model::::layout() } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Introspect::::ty() + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Introspect::::ty() } } @@ -17043,7 +17210,7 @@ fn __wrapper__DojoModelImpl__layout(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -17062,7 +17229,7 @@ fn __wrapper__DojoModelImpl__schema(mut data: Span::) -> Span::::serialize(@res, ref arr); + core::serde::Serde::::serialize(@res, ref arr); core::array::ArrayTrait::span(@arr) } @@ -17173,7 +17340,7 @@ pub trait BadModelMultipleVersionsEntityStore { pub trait BadModelMultipleVersionsStore { fn entity_id_from_keys(id: felt252) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> BadModelMultipleVersions; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> BadModelMultipleVersions; @@ -17309,7 +17476,7 @@ pub trait BadModelBadVersionTypeEntityStore { pub trait BadModelBadVersionTypeStore { fn entity_id_from_keys(id: felt252) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> BadModelBadVersionType; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> BadModelBadVersionType; @@ -17445,7 +17612,7 @@ pub trait BadModelNoVersionValueEntityStore { pub trait BadModelNoVersionValueStore { fn entity_id_from_keys(id: felt252) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> BadModelNoVersionValue; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> BadModelNoVersionValue; @@ -17581,7 +17748,7 @@ pub trait BadModelUnexpectedArgWithValueEntityStore { pub trait BadModelUnexpectedArgWithValueStore { fn entity_id_from_keys(id: felt252) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> BadModelUnexpectedArgWithValue; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> BadModelUnexpectedArgWithValue; @@ -17717,7 +17884,7 @@ pub trait BadModelUnexpectedArgEntityStore { pub trait BadModelUnexpectedArgStore { fn entity_id_from_keys(id: felt252) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> BadModelUnexpectedArg; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> BadModelUnexpectedArg; @@ -17853,7 +18020,7 @@ pub trait BadModelNotSupportedVersionEntityStore { pub trait BadModelNotSupportedVersionStore { fn entity_id_from_keys(id: felt252) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> BadModelNotSupportedVersion; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> BadModelNotSupportedVersion; @@ -17989,7 +18156,7 @@ pub trait Modelv0EntityStore { pub trait Modelv0Store { fn entity_id_from_keys(id: felt252) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> Modelv0; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> Modelv0; @@ -18125,7 +18292,7 @@ pub trait ModelWithBadNamespaceFormatEntityStore { pub trait ModelWithBadNamespaceFormatStore { fn entity_id_from_keys(id: felt252) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> ModelWithBadNamespaceFormat; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> ModelWithBadNamespaceFormat; @@ -18261,7 +18428,7 @@ pub trait ModelWithShortStringNamespaceEntityStore { pub trait ModelWithShortStringNamespaceStore { fn entity_id_from_keys(id: felt252) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> ModelWithShortStringNamespace; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> ModelWithShortStringNamespace; @@ -18397,7 +18564,7 @@ pub trait ModelWithStringNamespaceEntityStore { pub trait ModelWithStringNamespaceStore { fn entity_id_from_keys(id: felt252) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> ModelWithStringNamespace; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> ModelWithStringNamespace; @@ -18533,7 +18700,7 @@ pub trait PositionEntityStore { pub trait PositionStore { fn entity_id_from_keys(id: felt252) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> Position; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> Position; @@ -18669,7 +18836,7 @@ pub trait RolesEntityStore { pub trait RolesStore { fn entity_id_from_keys() -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> Roles; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, ) -> Roles; @@ -18799,7 +18966,7 @@ pub trait OnlyKeyModelEntityStore { pub trait OnlyKeyModelStore { fn entity_id_from_keys(id: felt252) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> OnlyKeyModel; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, id: felt252) -> OnlyKeyModel; @@ -18923,11 +19090,11 @@ pub trait U256KeyModelEntityStore { } pub trait U256KeyModelStore { - fn entity_id_from_keys(id: u256) -> felt252; + fn entity_id_from_keys() -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> U256KeyModel; + fn from_values(ref keys: Span, ref values: Span) -> Option; - fn get(world: dojo::world::IWorldDispatcher, id: u256) -> U256KeyModel; + fn get(world: dojo::world::IWorldDispatcher, ) -> U256KeyModel; fn set(self: @U256KeyModel, world: dojo::world::IWorldDispatcher); @@ -19057,7 +19224,7 @@ pub trait PlayerEntityStore { pub trait PlayerStore { fn entity_id_from_keys(game: felt252, player: ContractAddress) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> Player; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, game: felt252, player: ContractAddress) -> Player; @@ -19199,7 +19366,7 @@ pub trait ModelWithSimpleArrayEntityStore { pub trait ModelWithSimpleArrayStore { fn entity_id_from_keys(player: ContractAddress) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> ModelWithSimpleArray; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, player: ContractAddress) -> ModelWithSimpleArray; @@ -19345,7 +19512,7 @@ pub trait ModelWithByteArrayEntityStore { pub trait ModelWithByteArrayStore { fn entity_id_from_keys(player: ContractAddress) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> ModelWithByteArray; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, player: ContractAddress) -> ModelWithByteArray; @@ -19491,7 +19658,7 @@ pub trait ModelWithComplexArrayEntityStore { pub trait ModelWithComplexArrayStore { fn entity_id_from_keys(player: ContractAddress) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> ModelWithComplexArray; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, player: ContractAddress) -> ModelWithComplexArray; @@ -19637,7 +19804,7 @@ pub trait ModelWithTupleEntityStore { pub trait ModelWithTupleStore { fn entity_id_from_keys(player: ContractAddress) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> ModelWithTuple; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, player: ContractAddress) -> ModelWithTuple; @@ -19783,7 +19950,7 @@ pub trait ModelWithTupleNoPrimitivesEntityStore { pub trait ModelWithTupleNoPrimitivesStore { fn entity_id_from_keys(player: ContractAddress) -> felt252; - fn from_values(ref keys: Span, ref values: Span) -> ModelWithTupleNoPrimitives; + fn from_values(ref keys: Span, ref values: Span) -> Option; fn get(world: dojo::world::IWorldDispatcher, player: ContractAddress) -> ModelWithTupleNoPrimitives; @@ -26661,6 +26828,11 @@ error: Key is only supported for core types that are 1 felt long once serialized id: u256 ^^ +error: Model must define at least one #[key] attribute + --> /tmp/plugin_test/model/src/lib.cairo:98:8 +struct U256KeyModel { + ^**********^ + error: Model must define at least one member that is not a key --> /tmp/plugin_test/model/src/lib.cairo:98:8 struct U256KeyModel { diff --git a/crates/contracts/src/event/event.cairo b/crates/contracts/src/event/event.cairo new file mode 100644 index 0000000..a81a06e --- /dev/null +++ b/crates/contracts/src/event/event.cairo @@ -0,0 +1,48 @@ +use dojo::meta::Layout; +use dojo::meta::introspect::Ty; +use dojo::world::IWorldDispatcher; + +pub trait Event { + fn emit(self: @T, world: IWorldDispatcher); + + fn name() -> ByteArray; + fn namespace() -> ByteArray; + fn tag() -> ByteArray; + + fn version() -> u8; + + fn selector() -> felt252; + fn instance_selector(self: @T) -> felt252; + + fn name_hash() -> felt252; + fn namespace_hash() -> felt252; + + fn layout() -> Layout; + fn schema(self: @T) -> Ty; + + fn packed_size() -> Option; + fn unpacked_size() -> Option; + + fn historical() -> bool; + fn keys(self: @T) -> Span; + fn values(self: @T) -> Span; +} + +#[starknet::interface] +pub trait IEvent { + fn name(self: @T) -> ByteArray; + fn namespace(self: @T) -> ByteArray; + fn tag(self: @T) -> ByteArray; + + fn version(self: @T) -> u8; + + fn selector(self: @T) -> felt252; + fn name_hash(self: @T) -> felt252; + fn namespace_hash(self: @T) -> felt252; + + fn packed_size(self: @T) -> Option; + fn unpacked_size(self: @T) -> Option; + + fn layout(self: @T) -> Layout; + fn schema(self: @T) -> Ty; +} diff --git a/crates/contracts/src/lib.cairo b/crates/contracts/src/lib.cairo index b3ffa66..b98d050 100644 --- a/crates/contracts/src/lib.cairo +++ b/crates/contracts/src/lib.cairo @@ -6,11 +6,18 @@ pub mod contract { pub mod upgradeable; } -pub mod model { +pub mod event { + pub mod event; + pub use event::{Event, IEvent, IEventDispatcher, IEventDispatcherTrait}; +} + +pub mod meta { pub mod introspect; pub mod layout; pub use layout::{Layout, FieldLayout}; +} +pub mod model { pub mod model; pub use model::{ Model, ModelIndex, ModelEntity, IModel, IModelDispatcher, IModelDispatcherTrait, @@ -76,8 +83,11 @@ pub mod world { #[cfg(test)] mod tests { - mod model { + mod meta { mod introspect; + } + + mod model { mod model; } mod storage { diff --git a/crates/contracts/src/model/introspect.cairo b/crates/contracts/src/meta/introspect.cairo similarity index 97% rename from crates/contracts/src/model/introspect.cairo rename to crates/contracts/src/meta/introspect.cairo index deb35f7..b980a81 100644 --- a/crates/contracts/src/model/introspect.cairo +++ b/crates/contracts/src/meta/introspect.cairo @@ -1,4 +1,4 @@ -use dojo::model::{Layout, FieldLayout}; +use dojo::meta::{Layout, FieldLayout}; use dojo::storage::packing; #[derive(Copy, Drop, Serde)] @@ -241,9 +241,9 @@ pub impl Introspect_option> of Introspect> { fn layout() -> Layout { Layout::Enum( [ - dojo::model::FieldLayout { // Some + dojo::meta::FieldLayout { // Some selector: 0, layout: Introspect::::layout() }, - dojo::model::FieldLayout { // None + dojo::meta::FieldLayout { // None selector: 1, layout: Layout::Fixed([].span()) }, ].span() ) diff --git a/crates/contracts/src/model/layout.cairo b/crates/contracts/src/meta/layout.cairo similarity index 100% rename from crates/contracts/src/model/layout.cairo rename to crates/contracts/src/meta/layout.cairo diff --git a/crates/contracts/src/model/metadata.cairo b/crates/contracts/src/model/metadata.cairo index 7a8e180..0e12187 100644 --- a/crates/contracts/src/model/metadata.cairo +++ b/crates/contracts/src/model/metadata.cairo @@ -8,8 +8,9 @@ use core::byte_array::ByteArray; use core::poseidon::poseidon_hash_span; use core::serde::Serde; -use dojo::model::introspect::{Introspect, Ty, Struct, Member}; -use dojo::model::{Model, ModelIndex, Layout, FieldLayout}; +use dojo::meta::introspect::{Introspect, Ty, Struct, Member}; +use dojo::meta::{Layout, FieldLayout}; +use dojo::model::{Model, ModelIndex}; use dojo::utils; use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; @@ -32,13 +33,9 @@ pub struct ResourceMetadata { #[generate_trait] pub impl ResourceMetadataImpl of ResourceMetadataTrait { - fn from_values(resource_id: felt252, ref values: Span) -> ResourceMetadata { - let metadata_uri = Serde::::deserialize(ref values); - if metadata_uri.is_none() { - panic!("Model `ResourceMetadata`: metadata_uri deserialization failed."); - } - - ResourceMetadata { resource_id, metadata_uri: metadata_uri.unwrap() } + fn from_values(resource_id: felt252, ref values: Span) -> Option { + let metadata_uri = Serde::::deserialize(ref values)?; + Option::Some(ResourceMetadata { resource_id, metadata_uri }) } } @@ -49,7 +46,11 @@ pub impl ResourceMetadataModel of Model { }; let mut values = world.entity(Self::selector(), ModelIndex::Keys(keys), Self::layout()); - ResourceMetadataTrait::from_values(*keys.at(0), ref values) + + match ResourceMetadataTrait::from_values(*keys.at(0), ref values) { + Option::Some(x) => x, + Option::None => panic!("Model `ResourceMetadata`: deserialization failed.") + } } fn set_model(self: @ResourceMetadata, world: IWorldDispatcher,) { @@ -198,8 +199,8 @@ pub mod resource_metadata { use super::ResourceMetadata; use super::ResourceMetadataModel; - use dojo::model::introspect::{Introspect, Ty}; - use dojo::model::Layout; + use dojo::meta::introspect::{Introspect, Ty}; + use dojo::meta::Layout; #[storage] struct Storage {} diff --git a/crates/contracts/src/model/model.cairo b/crates/contracts/src/model/model.cairo index f967fec..863cee7 100644 --- a/crates/contracts/src/model/model.cairo +++ b/crates/contracts/src/model/model.cairo @@ -1,7 +1,7 @@ use starknet::SyscallResult; -use dojo::model::Layout; -use dojo::model::introspect::Ty; +use dojo::meta::Layout; +use dojo::meta::introspect::Ty; use dojo::world::IWorldDispatcher; use dojo::utils::{Descriptor, DescriptorTrait}; @@ -17,7 +17,7 @@ pub enum ModelIndex { pub trait ModelEntity { fn id(self: @T) -> felt252; fn values(self: @T) -> Span; - fn from_values(entity_id: felt252, ref values: Span) -> T; + fn from_values(entity_id: felt252, ref values: Span) -> Option; // Get is always used with the trait path, which results in no ambiguity for the compiler. fn get(world: IWorldDispatcher, entity_id: felt252) -> T; // Update and delete can be used directly on the entity, which results in ambiguity. diff --git a/crates/contracts/src/storage/layout.cairo b/crates/contracts/src/storage/layout.cairo index 34afc91..d29ca32 100644 --- a/crates/contracts/src/storage/layout.cairo +++ b/crates/contracts/src/storage/layout.cairo @@ -1,4 +1,4 @@ -use dojo::model::{Layout, FieldLayout}; +use dojo::meta::{Layout, FieldLayout}; use dojo::utils::{combine_key, find_field_layout}; use super::database; diff --git a/crates/contracts/src/tests/benchmarks.cairo b/crates/contracts/src/tests/benchmarks.cairo index 298057b..a3f3d8a 100644 --- a/crates/contracts/src/tests/benchmarks.cairo +++ b/crates/contracts/src/tests/benchmarks.cairo @@ -12,8 +12,9 @@ use starknet::storage_access::{ }; use starknet::syscalls::{storage_read_syscall, storage_write_syscall}; -use dojo::model::{Model, Layout, ModelIndex}; -use dojo::model::introspect::Introspect; +use dojo::meta::Layout; +use dojo::meta::introspect::Introspect; +use dojo::model::{Model, ModelIndex}; use dojo::storage::{database, storage}; use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; diff --git a/crates/contracts/src/tests/expanded/selector_attack.cairo b/crates/contracts/src/tests/expanded/selector_attack.cairo index 355bfa9..8378a6b 100644 --- a/crates/contracts/src/tests/expanded/selector_attack.cairo +++ b/crates/contracts/src/tests/expanded/selector_attack.cairo @@ -98,12 +98,12 @@ pub mod attacker_model { Option::None } - fn layout(self: @ContractState) -> dojo::model::Layout { - dojo::model::Layout::Fixed([].span()) + fn layout(self: @ContractState) -> dojo::meta::Layout { + dojo::meta::Layout::Fixed([].span()) } - fn schema(self: @ContractState) -> dojo::model::introspect::Ty { - dojo::model::introspect::Ty::Primitive('felt252') + fn schema(self: @ContractState) -> dojo::meta::introspect::Ty { + dojo::meta::introspect::Ty::Primitive('felt252') } } } diff --git a/crates/contracts/src/tests/model/introspect.cairo b/crates/contracts/src/tests/meta/introspect.cairo similarity index 98% rename from crates/contracts/src/tests/model/introspect.cairo rename to crates/contracts/src/tests/meta/introspect.cairo index 8a519af..bfa89e3 100644 --- a/crates/contracts/src/tests/model/introspect.cairo +++ b/crates/contracts/src/tests/meta/introspect.cairo @@ -1,5 +1,5 @@ -use dojo::model::introspect::Introspect; -use dojo::model::{Layout, FieldLayout}; +use dojo::meta::introspect::Introspect; +use dojo::meta::{Layout, FieldLayout}; #[derive(Drop, Introspect)] struct Base { diff --git a/crates/contracts/src/tests/model/model.cairo b/crates/contracts/src/tests/model/model.cairo index b52ebbf..384e6cc 100644 --- a/crates/contracts/src/tests/model/model.cairo +++ b/crates/contracts/src/tests/model/model.cairo @@ -35,14 +35,16 @@ fn test_from_values() { let mut values = [3, 4].span(); let model_entity = ModelEntity::::from_values(1, ref values); + assert!(model_entity.is_some()); + let model_entity = model_entity.unwrap(); assert!(model_entity.__id == 1 && model_entity.v1 == 3 && model_entity.v2 == 4); } #[test] -#[should_panic(expected: "ModelEntity `FooEntity`: deserialization failed.")] fn test_from_values_bad_data() { let mut values = [3].span(); - let _ = ModelEntity::::from_values(1, ref values); + let res = ModelEntity::::from_values(1, ref values); + assert!(res.is_none()); } #[test] diff --git a/crates/contracts/src/tests/world/entities.cairo b/crates/contracts/src/tests/world/entities.cairo index 599ccb7..46f88c6 100644 --- a/crates/contracts/src/tests/world/entities.cairo +++ b/crates/contracts/src/tests/world/entities.cairo @@ -2,8 +2,9 @@ use core::array::{ArrayTrait, SpanTrait}; use starknet::{contract_address_const, ContractAddress}; -use dojo::model::{ModelIndex, Layout, FieldLayout, Model}; -use dojo::model::introspect::Introspect; +use dojo::meta::introspect::Introspect; +use dojo::meta::{Layout, FieldLayout}; +use dojo::model::{ModelIndex, Model}; use dojo::storage::database::MAX_ARRAY_LENGTH; use dojo::utils::entity_id_from_keys; use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait, world}; diff --git a/crates/contracts/src/tests/world/world.cairo b/crates/contracts/src/tests/world/world.cairo index 06c898a..117aa07 100644 --- a/crates/contracts/src/tests/world/world.cairo +++ b/crates/contracts/src/tests/world/world.cairo @@ -3,6 +3,7 @@ use starknet::{contract_address_const, ContractAddress, get_caller_address}; use dojo::world::Resource; use dojo::world::config::Config::{DifferProgramHashUpdate, FactsRegistryUpdate}; use dojo::world::config::{IConfigDispatcher, IConfigDispatcherTrait}; +use dojo::world::world::{Event, EventEmitted}; use dojo::model::{Model, ResourceMetadata}; use dojo::utils::bytearray_hash; use dojo::world::{ @@ -106,14 +107,29 @@ fn test_contract_getter() { #[test] #[available_gas(6000000)] fn test_emit() { + let bob = starknet::contract_address_const::<0xb0b>(); + let world = deploy_world(); - let mut keys = ArrayTrait::new(); - keys.append('MyEvent'); - let mut values = ArrayTrait::new(); - values.append(1); - values.append(2); - world.emit(keys, values.span()); + drop_all_events(world.contract_address); + + starknet::testing::set_contract_address(bob); + + world.emit(selector!("MyEvent"), [1, 2].span(), [3, 4].span(), true); + + let event = starknet::testing::pop_log::(world.contract_address); + + assert(event.is_some(), 'no event'); + + if let Event::EventEmitted(event) = event.unwrap() { + assert(event.event_selector == selector!("MyEvent"), 'bad event selector'); + assert(event.system_address == bob, 'bad system address'); + assert(event.historical, 'bad historical value'); + assert(event.keys == [1, 2].span(), 'bad keys'); + assert(event.values == [3, 4].span(), 'bad keys'); + } else { + core::panic_with_felt252('no EventEmitted event'); + } } diff --git a/crates/contracts/src/utils/utils.cairo b/crates/contracts/src/utils/utils.cairo index b434167..a628f14 100644 --- a/crates/contracts/src/utils/utils.cairo +++ b/crates/contracts/src/utils/utils.cairo @@ -4,7 +4,7 @@ use core::option::Option; use core::poseidon::poseidon_hash_span; use core::serde::Serde; -use dojo::model::{Layout, FieldLayout}; +use dojo::meta::{Layout, FieldLayout}; /// Compute the poseidon hash of a serialized ByteArray pub fn bytearray_hash(data: @ByteArray) -> felt252 { diff --git a/crates/contracts/src/world/errors.cairo b/crates/contracts/src/world/errors.cairo index 284d4e9..44b0ab0 100644 --- a/crates/contracts/src/world/errors.cairo +++ b/crates/contracts/src/world/errors.cairo @@ -22,6 +22,14 @@ pub fn no_namespace_write_access(caller: ContractAddress, namespace: @ByteArray) format!("Caller `{:?}` has no write access on namespace `{}`", caller, namespace) } +pub fn event_already_registered(namespace: @ByteArray, name: @ByteArray) -> ByteArray { + format!("Resource `{}-{}` is already registered", namespace, name) +} + +pub fn event_not_registered(namespace: @ByteArray, name: @ByteArray) -> ByteArray { + format!("Resource `{}-{}` is not registered", namespace, name) +} + pub fn model_already_registered(namespace: @ByteArray, name: @ByteArray) -> ByteArray { format!("Resource `{}-{}` is already registered", namespace, name) } diff --git a/crates/contracts/src/world/world_contract.cairo b/crates/contracts/src/world/world_contract.cairo index eced4b4..b2a05e9 100644 --- a/crates/contracts/src/world/world_contract.cairo +++ b/crates/contracts/src/world/world_contract.cairo @@ -4,7 +4,7 @@ use core::traits::{Into, TryInto}; use starknet::{ContractAddress, ClassHash, storage_access::StorageBaseAddress, SyscallResult}; use dojo::model::{ModelIndex, ResourceMetadata}; -use dojo::model::{Layout}; +use dojo::meta::Layout; /// Resource is the type of the resource that can be registered in the world. /// @@ -20,6 +20,7 @@ use dojo::model::{Layout}; #[derive(Drop, starknet::Store, Serde, Default, Debug)] pub enum Resource { Model: (ContractAddress, felt252), + Event: (ContractAddress, felt252), Contract: (ContractAddress, felt252), Namespace: ByteArray, World, @@ -51,6 +52,9 @@ pub trait IWorld { fn register_namespace(ref self: T, namespace: ByteArray); + fn register_event(ref self: T, class_hash: ClassHash); + fn upgrade_event(ref self: T, class_hash: ClassHash); + fn register_model(ref self: T, class_hash: ClassHash); fn upgrade_model(ref self: T, class_hash: ClassHash); @@ -59,7 +63,13 @@ pub trait IWorld { fn init_contract(ref self: T, selector: felt252, init_calldata: Span); fn uuid(ref self: T) -> usize; - fn emit(self: @T, keys: Array, values: Span); + fn emit( + ref self: T, + event_selector: felt252, + keys: Span, + values: Span, + historical: bool + ); fn entity( self: @T, model_selector: felt252, index: ModelIndex, layout: Layout @@ -146,9 +156,11 @@ pub mod world { IUpgradeableState, IFactRegistryDispatcher, IFactRegistryDispatcherTrait, StorageUpdate, ProgramOutput }; + use dojo::meta::Layout; + use dojo::event::{IEventDispatcher, IEventDispatcherTrait}; use dojo::model::{ - Model, IModelDispatcher, IModelDispatcherTrait, Layout, ResourceMetadata, - ResourceMetadataTrait, metadata + Model, IModelDispatcher, IModelDispatcherTrait, ResourceMetadata, ResourceMetadataTrait, + metadata }; use dojo::storage; use dojo::utils::{ @@ -183,6 +195,8 @@ pub mod world { NamespaceRegistered: NamespaceRegistered, ModelRegistered: ModelRegistered, ModelUpgraded: ModelUpgraded, + EventRegistered: EventRegistered, + EventUpgraded: EventUpgraded, StoreSetRecord: StoreSetRecord, StoreUpdateRecord: StoreUpdateRecord, StoreUpdateMember: StoreUpdateMember, @@ -190,7 +204,8 @@ pub mod world { WriterUpdated: WriterUpdated, OwnerUpdated: OwnerUpdated, ConfigEvent: Config::Event, - StateUpdated: StateUpdated + StateUpdated: StateUpdated, + EventEmitted: EventEmitted } #[derive(Drop, starknet::Event)] @@ -259,6 +274,23 @@ pub mod world { pub prev_address: ContractAddress, } + #[derive(Drop, starknet::Event, Debug, PartialEq)] + pub struct EventRegistered { + pub name: ByteArray, + pub namespace: ByteArray, + pub class_hash: ClassHash, + pub address: ContractAddress, + } + + #[derive(Drop, starknet::Event, Debug, PartialEq)] + pub struct EventUpgraded { + pub name: ByteArray, + pub namespace: ByteArray, + pub class_hash: ClassHash, + pub address: ContractAddress, + pub prev_address: ContractAddress, + } + #[derive(Drop, starknet::Event)] pub struct StoreSetRecord { pub table: felt252, @@ -302,11 +334,24 @@ pub mod world { pub value: bool, } + #[derive(Drop, starknet::Event)] + pub struct EventEmitted { + #[key] + pub event_selector: felt252, + #[key] + pub system_address: ContractAddress, + #[key] + pub historical: bool, + pub keys: Span, + pub values: Span, + } + #[storage] struct Storage { contract_base: ClassHash, nonce: usize, models_salt: usize, + events_salt: usize, resources: Map::, owners: Map::<(felt252, ContractAddress), bool>, writers: Map::<(felt252, ContractAddress), bool>, @@ -387,7 +432,10 @@ pub mod world { Model::::layout() ); - ResourceMetadataTrait::from_values(resource_selector, ref values) + match ResourceMetadataTrait::from_values(resource_selector, ref values) { + Option::Some(x) => x, + Option::None => panic!("Model `ResourceMetadata`: deserialization failed.") + } } /// Sets the metadata of the resource. @@ -524,6 +572,116 @@ pub mod world { EventEmitter::emit(ref self, WriterUpdated { resource, contract, value: false }); } + /// Registers an event in the world. If the event is already registered, + /// the implementation will be updated. + /// + /// # Arguments + /// + /// * `class_hash` - The class hash of the event to be registered. + fn register_event(ref self: ContractState, class_hash: ClassHash) { + let caller = get_caller_address(); + let salt = self.events_salt.read(); + + let (contract_address, _) = starknet::syscalls::deploy_syscall( + class_hash, salt.into(), [].span(), false, + ) + .unwrap_syscall(); + self.events_salt.write(salt + 1); + + let descriptor = DescriptorTrait::from_contract_assert(contract_address); + + if !self.is_namespace_registered(descriptor.namespace_hash()) { + panic_with_byte_array(@errors::namespace_not_registered(descriptor.namespace())); + } + + self.assert_caller_permissions(descriptor.namespace_hash(), Permission::Owner); + + let maybe_existing_event = self.resources.read(descriptor.selector()); + if !maybe_existing_event.is_unregistered() { + panic_with_byte_array( + @errors::event_already_registered(descriptor.namespace(), descriptor.name()) + ); + } + + self + .resources + .write( + descriptor.selector(), + Resource::Event((contract_address, descriptor.namespace_hash())) + ); + self.owners.write((descriptor.selector(), caller), true); + + EventEmitter::emit( + ref self, + EventRegistered { + name: descriptor.name().clone(), + namespace: descriptor.namespace().clone(), + address: contract_address, + class_hash + } + ); + } + + fn upgrade_event(ref self: ContractState, class_hash: ClassHash) { + let salt = self.events_salt.read(); + + let (new_contract_address, _) = starknet::syscalls::deploy_syscall( + class_hash, salt.into(), [].span(), false, + ) + .unwrap_syscall(); + + self.events_salt.write(salt + 1); + + let new_descriptor = DescriptorTrait::from_contract_assert(new_contract_address); + + if !self.is_namespace_registered(new_descriptor.namespace_hash()) { + panic_with_byte_array( + @errors::namespace_not_registered(new_descriptor.namespace()) + ); + } + + self.assert_caller_permissions(new_descriptor.selector(), Permission::Owner); + + let mut prev_address = core::num::traits::Zero::::zero(); + + // If the namespace or name of the event have been changed, the descriptor + // will be different, hence not upgradeable. + match self.resources.read(new_descriptor.selector()) { + Resource::Event((model_address, _)) => { prev_address = model_address; }, + Resource::Unregistered => { + panic_with_byte_array( + @errors::event_not_registered( + new_descriptor.namespace(), new_descriptor.name() + ) + ) + }, + _ => panic_with_byte_array( + @errors::resource_conflict( + @format!("{}-{}", new_descriptor.namespace(), new_descriptor.name()), + @"event" + ) + ) + }; + + self + .resources + .write( + new_descriptor.selector(), + Resource::Event((new_contract_address, new_descriptor.namespace_hash())) + ); + + EventEmitter::emit( + ref self, + EventUpgraded { + name: new_descriptor.name().clone(), + namespace: new_descriptor.namespace().clone(), + prev_address, + address: new_contract_address, + class_hash, + } + ); + } + /// Registers a model in the world. If the model is already registered, /// the implementation will be updated. /// @@ -819,11 +977,19 @@ pub mod world { /// /// * `keys` - The keys of the event. /// * `values` - The data to be logged by the event. - fn emit(self: @ContractState, mut keys: Array, values: Span) { - let system = get_caller_address(); - system.serialize(ref keys); - - emit_event_syscall(keys.span(), values).unwrap_syscall(); + fn emit( + ref self: ContractState, + event_selector: felt252, + keys: Span, + values: Span, + historical: bool + ) { + EventEmitter::emit( + ref self, + EventEmitted { + event_selector, system_address: get_caller_address(), historical, keys, values, + } + ); } /// Gets the values of a model record/entity/member. @@ -1103,6 +1269,12 @@ pub mod world { let d = IDescriptorDispatcher { contract_address }; format!("contract (or its namespace) `{}`", d.tag()) }, + Resource::Event(( + contract_address, _ + )) => { + let d = IDescriptorDispatcher { contract_address }; + format!("event (or its namespace) `{}`", d.tag()) + }, Resource::Model(( contract_address, _ )) => { diff --git a/examples/dojo_simple/src/lib.cairo b/examples/dojo_simple/src/lib.cairo index 2896377..8d13f4b 100644 --- a/examples/dojo_simple/src/lib.cairo +++ b/examples/dojo_simple/src/lib.cairo @@ -19,6 +19,19 @@ pub mod models { } } +pub mod events { + use starknet::ContractAddress; + + #[derive(Drop)] + #[dojo::event] + pub struct PositionUpdated { + #[key] + pub player: ContractAddress, + pub new_x: u32, + pub new_y: u32, + } +} + #[dojo::interface] pub trait IActions { fn spawn(ref world: IWorldDispatcher); @@ -26,7 +39,7 @@ pub trait IActions { #[dojo::contract] pub mod actions { - use super::{IActions, models::{Position, PositionStore}}; + use super::{IActions, models::{Position, PositionStore}, events::PositionUpdated}; #[derive(Drop, Serde)] #[dojo::model] @@ -43,21 +56,22 @@ pub mod actions { let position = Position { player: caller, x: 1, y: 2 }; position.set(world); + + emit!(world, PositionUpdated { player: caller, new_x: 1, new_y: 2 }); + + } } } #[starknet::contract] pub mod sn_actions { - #[storage] struct Storage {} - } #[cfg(test)] mod tests { - #[test] fn test_spawn_world_full() { let _world = spawn_test_world!(); diff --git a/scripts/clippy.sh b/scripts/clippy.sh old mode 100644 new mode 100755 diff --git a/scripts/tests.sh b/scripts/tests.sh old mode 100644 new mode 100755 index c1f2b16..851b1b6 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -9,5 +9,6 @@ cargo test -p dojo-compiler # Testing with the demo compiler. cargo build -r --bin demo-compiler ./target/release/demo-compiler test --manifest-path crates/contracts/Scarb.toml + ./target/release/demo-compiler build --manifest-path examples/dojo_simple/Scarb.toml ./target/release/demo-compiler test --manifest-path examples/dojo_simple/Scarb.toml From 03ff1379254046f135868463e36b3d51a56335ab Mon Sep 17 00:00:00 2001 From: "remy.baranx@gmail.com" Date: Mon, 7 Oct 2024 16:46:10 +0200 Subject: [PATCH 02/11] some code refactoring --- crates/compiler/src/aux_data.rs | 263 +++++++++++++++-------- crates/compiler/src/compiler/compiler.rs | 116 +++------- crates/compiler/src/compiler/manifest.rs | 42 ++++ 3 files changed, 254 insertions(+), 167 deletions(-) diff --git a/crates/compiler/src/aux_data.rs b/crates/compiler/src/aux_data.rs index 859171f..cc2e725 100644 --- a/crates/compiler/src/aux_data.rs +++ b/crates/compiler/src/aux_data.rs @@ -11,12 +11,38 @@ use cairo_lang_defs::plugin::GeneratedFileAuxData; use cairo_lang_filesystem::ids::CrateId; use cairo_lang_starknet::plugin::aux_data::StarkNetContractAuxData; use convert_case::{Case, Casing}; +use dojo_types::naming; use smol_str::SmolStr; use tracing::trace; use super::compiler::manifest::Member; use crate::CAIRO_PATH_SEPARATOR; +pub trait AuxDataTrait { + fn name(&self) -> String; + fn namespace(&self) -> String; + fn tag(&self) -> String; +} + +pub trait AuxDataProcessor: std::fmt::Debug { + const ELEMENT_NAME: &'static str; + + fn contract_path(&self, module_path: &String) -> String; + + fn insert(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String); + + fn process(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String) { + trace!( + contract_path = self.contract_path(&module_path), + ?self, + "Adding dojo {} to aux data.", + Self::ELEMENT_NAME + ); + + self.insert(dojo_aux_data, module_path); + } +} + #[derive(Clone, Debug, PartialEq)] pub struct ModelAuxData { pub name: String, @@ -38,6 +64,42 @@ impl GeneratedFileAuxData for ModelAuxData { } } +impl AuxDataTrait for ModelAuxData { + fn name(&self) -> String { + self.name.clone() + } + fn namespace(&self) -> String { + self.namespace.clone() + } + fn tag(&self) -> String { + naming::get_tag(&self.namespace, &self.name) + } +} + +impl AuxDataProcessor for ModelAuxData { + const ELEMENT_NAME: &'static str = "model"; + + fn insert(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String) { + dojo_aux_data + .models + .insert(self.contract_path(module_path), self.clone()); + } + + // As models are defined from a struct (usually Pascal case), we have converted + // the underlying starknet contract name to snake case in the `#[dojo::model]` attribute + // macro processing. + // Same thing as for contracts, we need to add the model name to the module path + // to get the fully qualified path of the contract. + fn contract_path(&self, module_path: &String) -> String { + format!( + "{}{}{}", + module_path, + CAIRO_PATH_SEPARATOR, + self.name.to_case(Case::Snake) + ) + } +} + #[derive(Clone, Debug, PartialEq)] pub struct EventAuxData { pub name: String, @@ -59,6 +121,42 @@ impl GeneratedFileAuxData for EventAuxData { } } +impl AuxDataTrait for EventAuxData { + fn name(&self) -> String { + self.name.clone() + } + fn namespace(&self) -> String { + self.namespace.clone() + } + fn tag(&self) -> String { + naming::get_tag(&self.namespace, &self.name) + } +} + +impl AuxDataProcessor for EventAuxData { + const ELEMENT_NAME: &'static str = "event"; + + fn insert(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String) { + dojo_aux_data + .events + .insert(self.contract_path(module_path), self.clone()); + } + + // As events are defined from a struct (usually Pascal case), we have converted + // the underlying starknet contract name to snake case in the `#[dojo::event]` attribute + // macro processing. + // Same thing as for contracts, we need to add the event name to the module path + // to get the fully qualified path of the contract. + fn contract_path(&self, module_path: &String) -> String { + format!( + "{}{}{}", + module_path, + CAIRO_PATH_SEPARATOR, + self.name.to_case(Case::Snake) + ) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ContractAuxData { pub name: SmolStr, @@ -80,6 +178,73 @@ impl GeneratedFileAuxData for ContractAuxData { } } +impl AuxDataTrait for ContractAuxData { + fn name(&self) -> String { + self.name.to_string() + } + fn namespace(&self) -> String { + self.namespace.clone() + } + fn tag(&self) -> String { + naming::get_tag(&self.namespace, &self.name) + } +} + +impl AuxDataProcessor for ContractAuxData { + const ELEMENT_NAME: &'static str = "contract"; + + fn insert(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String) { + dojo_aux_data + .contracts + .insert(self.contract_path(module_path), self.clone()); + } + + // The module path for contracts is the path to the contract file, not the fully + // qualified path of the actual contract module. + // Adding the contract name to the module path allows to get the fully qualified path + fn contract_path(&self, module_path: &String) -> String { + format!("{}{}{}", module_path, CAIRO_PATH_SEPARATOR, self.name) + } +} + +impl AuxDataProcessor for StarkNetContractAuxData { + const ELEMENT_NAME: &'static str = "starknet contract"; + + fn insert(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String) { + dojo_aux_data + .sn_contracts + .insert(module_path.clone(), self.contract_path(module_path)); + } + + fn contract_path(&self, _module_path: &String) -> String { + self.contract_name.to_string() + } + + // As every contracts and models are starknet contracts under the hood, + // we need to filter already processed Starknet contracts. + // Also important to note that, the module id for a starknet contract is + // already the fully qualified path of the contract. + // + // Important to note that all the dojo-core contracts are starknet contracts + // (currently world, base and resource_metadata model). They will be added here + // but we may choose to ignore them. + fn process(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String) + where + Self: Sized, + { + if !dojo_aux_data.contains_starknet_contract(&module_path) { + trace!( + %module_path, + contract_name = self.contract_path(module_path), + "Adding {} to aux data.", + Self::ELEMENT_NAME + ); + + self.insert(dojo_aux_data, module_path); + } + } +} + /// Dojo related auxiliary data of the Dojo plugin. /// /// All the keys are full paths to the cairo module that contains the expanded code. @@ -101,7 +266,9 @@ impl DojoAuxData { /// Checks if a starknet contract with the given qualified path has been processed /// for a contract or a model. pub fn contains_starknet_contract(&self, qualified_path: &str) -> bool { - self.contracts.contains_key(qualified_path) || self.models.contains_key(qualified_path) + self.contracts.contains_key(qualified_path) + || self.models.contains_key(qualified_path) + || self.events.contains_key(qualified_path) } /// Creates a new `DojoAuxData` from a list of crate ids and a database by introspecting @@ -124,99 +291,23 @@ impl DojoAuxData { { let module_path = module_id.full_path(db); - if let Some(contract_aux_data) = aux_data.downcast_ref::() { - // The module path for contracts is the path to the contract file, not the fully - // qualified path of the actual contract module. - // Adding the contract name to the module path allows to get the fully qualified path. - let contract_path = format!( - "{}{}{}", - module_path, CAIRO_PATH_SEPARATOR, contract_aux_data.name - ); - - trace!( - contract_path, - ?contract_aux_data, - "Adding dojo contract to aux data." - ); - - dojo_aux_data - .contracts - .insert(contract_path, contract_aux_data.clone()); + if let Some(aux_data) = aux_data.downcast_ref::() { + aux_data.process(&mut dojo_aux_data, &module_path); + continue; } - if let Some(model_aux_data) = aux_data.downcast_ref::() { - // As models are defined from a struct (usually Pascal case), we have converted - // the underlying starknet contract name to snake case in the `#[dojo::model]` attribute - // macro processing. - // Same thing as for contracts, we need to add the model name to the module path - // to get the fully qualified path of the contract. - let model_contract_path = format!( - "{}{}{}", - module_path, - CAIRO_PATH_SEPARATOR, - model_aux_data.name.to_case(Case::Snake) - ); - - trace!( - model_contract_path, - ?model_aux_data, - "Adding dojo model to aux data." - ); - - dojo_aux_data - .models - .insert(model_contract_path, model_aux_data.clone()); + if let Some(aux_data) = aux_data.downcast_ref::() { + aux_data.process(&mut dojo_aux_data, &module_path); continue; } - if let Some(event_aux_data) = aux_data.downcast_ref::() { - // As events are defined from a struct (usually Pascal case), we have converted - // the underlying starknet contract name to snake case in the `#[dojo::event]` attribute - // macro processing. - // Same thing as for contracts, we need to add the event name to the module path - // to get the fully qualified path of the contract. - let event_contract_path = format!( - "{}{}{}", - module_path, - CAIRO_PATH_SEPARATOR, - event_aux_data.name.to_case(Case::Snake) - ); - - trace!( - event_contract_path, - ?event_aux_data, - "Adding dojo event to aux data." - ); - - dojo_aux_data - .events - .insert(event_contract_path, event_aux_data.clone()); + if let Some(aux_data) = aux_data.downcast_ref::() { + aux_data.process(&mut dojo_aux_data, &module_path); continue; } - // As every contracts and models are starknet contracts under the hood, - // we need to filter already processed Starknet contracts. - // Also important to note that, the module id for a starknet contract is - // already the fully qualified path of the contract. - // - // Important to note that all the dojo-core contracts are starknet contracts - // (currently world, base and resource_metadata model). They will be added here - // but we may choose to ignore them. - if let Some(sn_contract_aux_data) = - aux_data.downcast_ref::() - { - if !dojo_aux_data.contains_starknet_contract(&module_path) { - dojo_aux_data.sn_contracts.insert( - module_path.clone(), - sn_contract_aux_data.contract_name.to_string(), - ); - - trace!( - %module_path, - contract_name = %sn_contract_aux_data.contract_name, - "Adding starknet contract to aux data." - ); - } + if let Some(aux_data) = aux_data.downcast_ref::() { + aux_data.process(&mut dojo_aux_data, &module_path); } } } diff --git a/crates/compiler/src/compiler/compiler.rs b/crates/compiler/src/compiler/compiler.rs index c50fc46..927451d 100644 --- a/crates/compiler/src/compiler/compiler.rs +++ b/crates/compiler/src/compiler/compiler.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::fs; use std::rc::Rc; @@ -26,18 +27,19 @@ use starknet::core::types::contract::SierraClass; use starknet::core::types::Felt; use tracing::{trace, trace_span}; -use crate::aux_data::DojoAuxData; +use crate::aux_data::{AuxDataTrait, ContractAuxData, DojoAuxData, EventAuxData, ModelAuxData}; use crate::compiler::manifest::{ AbstractBaseManifest, ContractManifest, EventManifest, ModelManifest, StarknetContractManifest, }; use crate::scarb_extensions::{ProfileSpec, WorkspaceExt}; use crate::{ - BASE_CONTRACT_TAG, BASE_QUALIFIED_PATH, CAIRO_PATH_SEPARATOR, CONTRACTS_DIR, MODELS_DIR, - RESOURCE_METADATA_QUALIFIED_PATH, WORLD_CONTRACT_TAG, WORLD_QUALIFIED_PATH, + BASE_CONTRACT_TAG, BASE_QUALIFIED_PATH, CAIRO_PATH_SEPARATOR, CONTRACTS_DIR, EVENTS_DIR, + MODELS_DIR, RESOURCE_METADATA_QUALIFIED_PATH, WORLD_CONTRACT_TAG, WORLD_QUALIFIED_PATH, }; use super::artifact_manager::{ArtifactManager, CompiledArtifact}; use super::contract_selector::ContractSelector; +use super::manifest::FromAuxDataTrait; use super::scarb_internal; use super::scarb_internal::debug::SierraToCairoDebugInfo; use super::version::check_package_dojo_version; @@ -197,9 +199,21 @@ impl Compiler for DojoCompiler { // Combine the aux data info about the contracts with the artifact data // to create the manifests. - let contracts = write_dojo_contracts_artifacts(&artifact_manager, &aux_data)?; - let models = write_dojo_models_artifacts(&artifact_manager, &aux_data)?; - let events = write_dojo_events_artifacts(&artifact_manager, &aux_data)?; + let contracts = write_dojo_element_artifacts::( + &artifact_manager, + &aux_data.contracts, + CONTRACTS_DIR, + )?; + let models = write_dojo_element_artifacts::( + &artifact_manager, + &aux_data.models, + MODELS_DIR, + )?; + let events = write_dojo_element_artifacts::( + &artifact_manager, + &aux_data.events, + EVENTS_DIR, + )?; let (world, base, sn_contracts) = write_sn_contract_artifacts(&artifact_manager, &aux_data)?; @@ -417,91 +431,31 @@ pub fn collect_crates_ids_from_selectors( .collect::>() } -/// Writes the dojo contracts artifacts to the target directory and returns the contract manifests. -fn write_dojo_contracts_artifacts( +/// Writes the dojo elements artifacts to the target directory and returns the element manifests. +fn write_dojo_element_artifacts>( artifact_manager: &ArtifactManager, - aux_data: &DojoAuxData, -) -> Result> { - let mut contracts = Vec::new(); + aux_data: &HashMap, + element_dir: &str, +) -> Result> { + let mut elements = Vec::new(); - for (qualified_path, contract_aux_data) in aux_data.contracts.iter() { - let tag = naming::get_tag(&contract_aux_data.namespace, &contract_aux_data.name); - let filename = naming::get_filename_from_tag(&tag); + for (qualified_path, aux_data) in aux_data.iter() { + let filename = naming::get_filename_from_tag(&aux_data.tag()); let target_dir = artifact_manager .workspace() .target_dir_profile() - .child(CONTRACTS_DIR); + .child(element_dir); artifact_manager.write_sierra_class(qualified_path, &target_dir, &filename)?; - - contracts.push(ContractManifest { - class_hash: artifact_manager.get_class_hash(qualified_path)?, - qualified_path: qualified_path.to_string(), - tag, - systems: contract_aux_data.systems.clone(), - }); - } - - Ok(contracts) -} - -/// Writes the dojo models artifacts to the target directory and returns the model manifests. -fn write_dojo_models_artifacts( - artifact_manager: &ArtifactManager, - aux_data: &DojoAuxData, -) -> Result> { - let mut models = Vec::new(); - - for (qualified_path, model_aux_data) in aux_data.models.iter() { - let tag = naming::get_tag(&model_aux_data.namespace, &model_aux_data.name); - let filename = naming::get_filename_from_tag(&tag); - - let target_dir = artifact_manager - .workspace() - .target_dir_profile() - .child(MODELS_DIR); - - artifact_manager.write_sierra_class(qualified_path, &target_dir, &filename)?; - - models.push(ModelManifest { - class_hash: artifact_manager.get_class_hash(qualified_path)?, - qualified_path: qualified_path.to_string(), - tag, - members: model_aux_data.members.clone(), - }); - } - - Ok(models) -} - -/// Writes the dojo event artifacts to the target directory and returns the event manifests. -fn write_dojo_events_artifacts( - artifact_manager: &ArtifactManager, - aux_data: &DojoAuxData, -) -> Result> { - let mut events = Vec::new(); - - for (qualified_path, event_aux_data) in aux_data.events.iter() { - let tag = naming::get_tag(&event_aux_data.namespace, &event_aux_data.name); - let filename = naming::get_filename_from_tag(&tag); - - let target_dir = artifact_manager - .workspace() - .target_dir_profile() - .child(MODELS_DIR); - - artifact_manager.write_sierra_class(qualified_path, &target_dir, &filename)?; - - events.push(EventManifest { - class_hash: artifact_manager.get_class_hash(qualified_path)?, - qualified_path: qualified_path.to_string(), - tag, - members: event_aux_data.members.clone(), - }); + elements.push(U::from_aux_data( + aux_data, + artifact_manager.get_class_hash(qualified_path)?, + qualified_path, + )); } - Ok(events) + Ok(elements) } /// Writes the starknet contracts artifacts to the target directory and returns the starknet contract manifests. diff --git a/crates/compiler/src/compiler/manifest.rs b/crates/compiler/src/compiler/manifest.rs index d752067..de6a752 100644 --- a/crates/compiler/src/compiler/manifest.rs +++ b/crates/compiler/src/compiler/manifest.rs @@ -14,6 +14,7 @@ use serde_with::serde_as; use starknet::core::serde::unsigned_field_element::UfeHex; use starknet::core::types::Felt; +use crate::aux_data::{AuxDataTrait, ContractAuxData, EventAuxData, ModelAuxData}; use crate::scarb_extensions::{FilesystemExt, WorkspaceExt}; use crate::{ BASE_CONTRACT_TAG, CAIRO_PATH_SEPARATOR, CONTRACTS_DIR, EVENTS_DIR, MODELS_DIR, @@ -41,6 +42,10 @@ pub trait ManifestMethods { fn to_toml_string(&self) -> Result; } +pub trait FromAuxDataTrait { + fn from_aux_data(aux_data: &T, class_hash: Felt, qualified_path: &String) -> Self; +} + /// Represents the contract of a dojo contract. #[serde_as] #[derive(Clone, Default, Debug, Serialize, Deserialize)] @@ -70,6 +75,21 @@ impl ManifestMethods for ContractManifest { } } +impl FromAuxDataTrait for ContractManifest { + fn from_aux_data( + aux_data: &ContractAuxData, + class_hash: Felt, + qualified_path: &String, + ) -> Self { + Self { + class_hash, + qualified_path: qualified_path.clone(), + tag: aux_data.tag(), + systems: aux_data.systems.clone(), + } + } +} + /// Represents the contract of a dojo model. #[serde_as] #[derive(Clone, Default, Debug, Serialize, Deserialize)] @@ -99,6 +119,17 @@ impl ManifestMethods for ModelManifest { } } +impl FromAuxDataTrait for ModelManifest { + fn from_aux_data(aux_data: &ModelAuxData, class_hash: Felt, qualified_path: &String) -> Self { + Self { + class_hash, + qualified_path: qualified_path.clone(), + tag: aux_data.tag(), + members: aux_data.members.clone(), + } + } +} + /// Represents the contract of a dojo event. #[serde_as] #[derive(Clone, Default, Debug, Serialize, Deserialize)] @@ -128,6 +159,17 @@ impl ManifestMethods for EventManifest { } } +impl FromAuxDataTrait for EventManifest { + fn from_aux_data(aux_data: &EventAuxData, class_hash: Felt, qualified_path: &String) -> Self { + Self { + class_hash, + qualified_path: qualified_path.clone(), + tag: aux_data.tag(), + members: aux_data.members.clone(), + } + } +} + /// Represents a starknet contract. #[serde_as] #[derive(Clone, Default, Debug, Serialize, Deserialize)] From 0ce923380396a1a345911b341197e299c791d9e2 Mon Sep 17 00:00:00 2001 From: "remy.baranx@gmail.com" Date: Mon, 7 Oct 2024 21:27:23 +0200 Subject: [PATCH 03/11] review comments --- crates/compiler/src/compiler/compiler.rs | 10 +++++----- .../src/plugin/attribute_macros/patches.rs | 18 ------------------ crates/contracts/src/event/event.cairo | 6 ------ .../contracts/src/world/world_contract.cairo | 6 ++---- 4 files changed, 7 insertions(+), 33 deletions(-) diff --git a/crates/compiler/src/compiler/compiler.rs b/crates/compiler/src/compiler/compiler.rs index 927451d..de82244 100644 --- a/crates/compiler/src/compiler/compiler.rs +++ b/crates/compiler/src/compiler/compiler.rs @@ -199,17 +199,17 @@ impl Compiler for DojoCompiler { // Combine the aux data info about the contracts with the artifact data // to create the manifests. - let contracts = write_dojo_element_artifacts::( + let contracts = write_dojo_resource_artifacts::( &artifact_manager, &aux_data.contracts, CONTRACTS_DIR, )?; - let models = write_dojo_element_artifacts::( + let models = write_dojo_resource_artifacts::( &artifact_manager, &aux_data.models, MODELS_DIR, )?; - let events = write_dojo_element_artifacts::( + let events = write_dojo_resource_artifacts::( &artifact_manager, &aux_data.events, EVENTS_DIR, @@ -431,8 +431,8 @@ pub fn collect_crates_ids_from_selectors( .collect::>() } -/// Writes the dojo elements artifacts to the target directory and returns the element manifests. -fn write_dojo_element_artifacts>( +/// Writes the dojo resource artifacts to the target directory and returns the resource manifests. +fn write_dojo_resource_artifacts>( artifact_manager: &ArtifactManager, aux_data: &HashMap, element_dir: &str, diff --git a/crates/compiler/src/plugin/attribute_macros/patches.rs b/crates/compiler/src/plugin/attribute_macros/patches.rs index 15b31d4..6012d4a 100644 --- a/crates/compiler/src/plugin/attribute_macros/patches.rs +++ b/crates/compiler/src/plugin/attribute_macros/patches.rs @@ -581,16 +581,6 @@ pub impl $type_name$EventImpl of dojo::event::Event<$type_name$> { dojo::meta::introspect::Introspect::<$type_name$>::layout() } - #[inline(always)] - fn packed_size() -> Option { - dojo::meta::layout::compute_packed_size(Self::layout()) - } - - #[inline(always)] - fn unpacked_size() -> Option { - dojo::meta::introspect::Introspect::<$type_name$>::size() - } - #[inline(always)] fn schema(self: @$type_name$) -> dojo::meta::introspect::Ty { dojo::meta::introspect::Introspect::<$type_name$>::ty() @@ -653,14 +643,6 @@ pub mod $contract_name$ { $event_namespace_hash$ } - fn unpacked_size(self: @ContractState) -> Option { - dojo::meta::introspect::Introspect::<$type_name$>::size() - } - - fn packed_size(self: @ContractState) -> Option { - dojo::event::Event::<$type_name$>::packed_size() - } - fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::event::Event::<$type_name$>::layout() } diff --git a/crates/contracts/src/event/event.cairo b/crates/contracts/src/event/event.cairo index a81a06e..25da2eb 100644 --- a/crates/contracts/src/event/event.cairo +++ b/crates/contracts/src/event/event.cairo @@ -20,9 +20,6 @@ pub trait Event { fn layout() -> Layout; fn schema(self: @T) -> Ty; - fn packed_size() -> Option; - fn unpacked_size() -> Option; - fn historical() -> bool; fn keys(self: @T) -> Span; fn values(self: @T) -> Span; @@ -40,9 +37,6 @@ pub trait IEvent { fn name_hash(self: @T) -> felt252; fn namespace_hash(self: @T) -> felt252; - fn packed_size(self: @T) -> Option; - fn unpacked_size(self: @T) -> Option; - fn layout(self: @T) -> Layout; fn schema(self: @T) -> Ty; } diff --git a/crates/contracts/src/world/world_contract.cairo b/crates/contracts/src/world/world_contract.cairo index b2a05e9..ccbb087 100644 --- a/crates/contracts/src/world/world_contract.cairo +++ b/crates/contracts/src/world/world_contract.cairo @@ -572,8 +572,7 @@ pub mod world { EventEmitter::emit(ref self, WriterUpdated { resource, contract, value: false }); } - /// Registers an event in the world. If the event is already registered, - /// the implementation will be updated. + /// Registers an event in the world. /// /// # Arguments /// @@ -682,8 +681,7 @@ pub mod world { ); } - /// Registers a model in the world. If the model is already registered, - /// the implementation will be updated. + /// Registers a model in the world. /// /// # Arguments /// From acefb54bb6d7edeccf470b55e9d4518bb8e481f8 Mon Sep 17 00:00:00 2001 From: glihm Date: Tue, 8 Oct 2024 16:59:34 -0600 Subject: [PATCH 04/11] fix: cleanup manifests to annotations --- bins/demo-compiler/src/commands/clean.rs | 6 +- crates/compiler/src/aux_data.rs | 383 ++++++++---------- crates/compiler/src/compiler/annotation.rs | 212 ++++++++++ .../compiler/src/compiler/artifact_manager.rs | 135 ++++++ crates/compiler/src/compiler/compiler.rs | 162 +------- crates/compiler/src/compiler/manifest.rs | 367 ----------------- crates/compiler/src/compiler/mod.rs | 2 +- .../src/compiler/scarb_internal/mod.rs | 6 +- crates/compiler/src/contract_store.rs | 0 crates/compiler/src/namespace_config.rs | 2 +- .../src/plugin/attribute_macros/element.rs | 2 +- .../src/plugin/attribute_macros/model.rs | 2 +- .../src/plugin/inline_macros/utils.rs | 16 +- crates/compiler/src/scarb_extensions.rs | 32 -- 14 files changed, 541 insertions(+), 786 deletions(-) create mode 100644 crates/compiler/src/compiler/annotation.rs delete mode 100644 crates/compiler/src/compiler/manifest.rs create mode 100644 crates/compiler/src/contract_store.rs diff --git a/bins/demo-compiler/src/commands/clean.rs b/bins/demo-compiler/src/commands/clean.rs index 8c3f5d7..8e5a992 100644 --- a/bins/demo-compiler/src/commands/clean.rs +++ b/bins/demo-compiler/src/commands/clean.rs @@ -7,10 +7,6 @@ use tracing::trace; #[derive(Debug, Args)] pub struct CleanArgs { - #[arg(long)] - #[arg(help = "Removes the scarb artifacts AND the dojo compiler manifests.")] - pub remove_dojo_manifests: bool, - #[arg(long)] #[arg(help = "Clean all profiles.")] pub all_profiles: bool, @@ -27,7 +23,7 @@ impl CleanArgs { ProfileSpec::WorkspaceCurrent }; - DojoCompiler::clean(config, profile_spec, self.remove_dojo_manifests)?; + DojoCompiler::clean(config, profile_spec)?; Ok(()) } diff --git a/crates/compiler/src/aux_data.rs b/crates/compiler/src/aux_data.rs index cc2e725..f87f4ee 100644 --- a/crates/compiler/src/aux_data.rs +++ b/crates/compiler/src/aux_data.rs @@ -3,53 +3,64 @@ //! The plugin generates aux data for models, contracts and events. //! Then the compiler uses this aux data to generate the manifests and organize the artifacts. -use std::collections::HashMap; - -use cairo_lang_compiler::db::RootDatabase; -use cairo_lang_defs::db::DefsGroup; +use anyhow::Result; use cairo_lang_defs::plugin::GeneratedFileAuxData; -use cairo_lang_filesystem::ids::CrateId; use cairo_lang_starknet::plugin::aux_data::StarkNetContractAuxData; use convert_case::{Case, Casing}; use dojo_types::naming; use smol_str::SmolStr; use tracing::trace; -use super::compiler::manifest::Member; -use crate::CAIRO_PATH_SEPARATOR; +use super::compiler::annotation::Member; +use crate::{ + compiler::{ + annotation::{ + ContractAnnotation, EventAnnotation, ModelAnnotation, StarknetContractAnnotation, + }, + artifact_manager::ArtifactManager, + }, + CAIRO_PATH_SEPARATOR, +}; -pub trait AuxDataTrait { - fn name(&self) -> String; - fn namespace(&self) -> String; - fn tag(&self) -> String; +#[derive(Clone, Debug, PartialEq)] +pub struct ModelAuxData { + pub name: String, + pub namespace: String, + pub members: Vec, } -pub trait AuxDataProcessor: std::fmt::Debug { - const ELEMENT_NAME: &'static str; - - fn contract_path(&self, module_path: &String) -> String; - - fn insert(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String); - - fn process(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String) { - trace!( - contract_path = self.contract_path(&module_path), - ?self, - "Adding dojo {} to aux data.", - Self::ELEMENT_NAME - ); - - self.insert(dojo_aux_data, module_path); - } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ContractAuxData { + pub name: SmolStr, + pub namespace: String, + pub systems: Vec, } #[derive(Clone, Debug, PartialEq)] -pub struct ModelAuxData { +pub struct EventAuxData { pub name: String, pub namespace: String, pub members: Vec, } +pub trait AuxDataToAnnotation { + /// Returns the qualified path of the contract, since dependingo on the aux data type + /// the qualified path is computed differently from the module path. + /// + /// # Arguments + /// + /// * `module_path` - The path to the module that generated the aux data. + fn contract_qualified_path(&self, module_path: &String) -> String; + + /// Converts the aux data to the corresponding annotation. + /// + /// # Arguments + /// + /// * `artifact_manager` - The artifact manager to get the class from the artifact. + /// * `module_path` - The path to the module that generated the aux data. + fn to_annotation(&self, artifact_manager: &ArtifactManager, module_path: &String) -> Result; +} + impl GeneratedFileAuxData for ModelAuxData { fn as_any(&self) -> &dyn std::any::Any { self @@ -64,33 +75,13 @@ impl GeneratedFileAuxData for ModelAuxData { } } -impl AuxDataTrait for ModelAuxData { - fn name(&self) -> String { - self.name.clone() - } - fn namespace(&self) -> String { - self.namespace.clone() - } - fn tag(&self) -> String { - naming::get_tag(&self.namespace, &self.name) - } -} - -impl AuxDataProcessor for ModelAuxData { - const ELEMENT_NAME: &'static str = "model"; - - fn insert(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String) { - dojo_aux_data - .models - .insert(self.contract_path(module_path), self.clone()); - } - - // As models are defined from a struct (usually Pascal case), we have converted - // the underlying starknet contract name to snake case in the `#[dojo::model]` attribute - // macro processing. - // Same thing as for contracts, we need to add the model name to the module path - // to get the fully qualified path of the contract. - fn contract_path(&self, module_path: &String) -> String { +impl AuxDataToAnnotation for ModelAuxData { + fn contract_qualified_path(&self, module_path: &String) -> String { + // As models are defined from a struct (usually Pascal case), we have converted + // the underlying starknet contract name to snake case in the `#[dojo::model]` attribute + // macro processing. + // Same thing as for contracts, we need to add the model name to the module path + // to get the fully qualified path of the contract. format!( "{}{}{}", module_path, @@ -98,13 +89,35 @@ impl AuxDataProcessor for ModelAuxData { self.name.to_case(Case::Snake) ) } -} -#[derive(Clone, Debug, PartialEq)] -pub struct EventAuxData { - pub name: String, - pub namespace: String, - pub members: Vec, + fn to_annotation( + &self, + artifact_manager: &ArtifactManager, + module_path: &String, + ) -> Result { + let contract_qualified_path = self.contract_qualified_path(&module_path); + + let artifact = artifact_manager + .get_artifact(&contract_qualified_path) + .ok_or(anyhow::anyhow!("Artifact not found"))?; + + let annotation = ModelAnnotation { + qualified_path: contract_qualified_path.clone(), + class_hash: artifact.class_hash, + tag: naming::get_tag(&self.namespace, &self.name), + members: self.members.clone(), + }; + + trace!( + contract_path = contract_qualified_path, + ?self, + "Generating annotations for model {} ({}).", + annotation.tag, + annotation.qualified_path, + ); + + Ok(annotation) + } } impl GeneratedFileAuxData for EventAuxData { @@ -121,33 +134,13 @@ impl GeneratedFileAuxData for EventAuxData { } } -impl AuxDataTrait for EventAuxData { - fn name(&self) -> String { - self.name.clone() - } - fn namespace(&self) -> String { - self.namespace.clone() - } - fn tag(&self) -> String { - naming::get_tag(&self.namespace, &self.name) - } -} - -impl AuxDataProcessor for EventAuxData { - const ELEMENT_NAME: &'static str = "event"; - - fn insert(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String) { - dojo_aux_data - .events - .insert(self.contract_path(module_path), self.clone()); - } - - // As events are defined from a struct (usually Pascal case), we have converted - // the underlying starknet contract name to snake case in the `#[dojo::event]` attribute - // macro processing. - // Same thing as for contracts, we need to add the event name to the module path - // to get the fully qualified path of the contract. - fn contract_path(&self, module_path: &String) -> String { +impl AuxDataToAnnotation for EventAuxData { + fn contract_qualified_path(&self, module_path: &String) -> String { + // As events are defined from a struct (usually Pascal case), we have converted + // the underlying starknet contract name to snake case in the `#[dojo::event]` attribute + // macro processing. + // Same thing as for contracts, we need to add the event name to the module path + // to get the fully qualified path of the contract. format!( "{}{}{}", module_path, @@ -155,13 +148,35 @@ impl AuxDataProcessor for EventAuxData { self.name.to_case(Case::Snake) ) } -} -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ContractAuxData { - pub name: SmolStr, - pub namespace: String, - pub systems: Vec, + fn to_annotation( + &self, + artifact_manager: &ArtifactManager, + module_path: &String, + ) -> Result { + let contract_qualified_path = self.contract_qualified_path(&module_path); + + let artifact = artifact_manager + .get_artifact(&contract_qualified_path) + .ok_or(anyhow::anyhow!("Artifact not found"))?; + + let annotation = EventAnnotation { + qualified_path: contract_qualified_path.clone(), + class_hash: artifact.class_hash, + tag: naming::get_tag(&self.namespace, &self.name), + members: self.members.clone(), + }; + + trace!( + contract_path = contract_qualified_path, + ?self, + "Generating annotations for event {} ({}).", + annotation.tag, + annotation.qualified_path, + ); + + Ok(annotation) + } } impl GeneratedFileAuxData for ContractAuxData { @@ -178,141 +193,75 @@ impl GeneratedFileAuxData for ContractAuxData { } } -impl AuxDataTrait for ContractAuxData { - fn name(&self) -> String { - self.name.to_string() - } - fn namespace(&self) -> String { - self.namespace.clone() - } - fn tag(&self) -> String { - naming::get_tag(&self.namespace, &self.name) +impl AuxDataToAnnotation for ContractAuxData { + fn contract_qualified_path(&self, module_path: &String) -> String { + // The module path for contracts is the path to the contract file, not the fully + // qualified path of the actual contract module. + // Adding the contract name to the module path allows to get the fully qualified path + format!("{}{}{}", module_path, CAIRO_PATH_SEPARATOR, self.name) } -} -impl AuxDataProcessor for ContractAuxData { - const ELEMENT_NAME: &'static str = "contract"; + fn to_annotation( + &self, + artifact_manager: &ArtifactManager, + module_path: &String, + ) -> Result { + let contract_qualified_path = self.contract_qualified_path(&module_path); - fn insert(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String) { - dojo_aux_data - .contracts - .insert(self.contract_path(module_path), self.clone()); - } + let artifact = artifact_manager + .get_artifact(&contract_qualified_path) + .ok_or(anyhow::anyhow!("Artifact not found"))?; - // The module path for contracts is the path to the contract file, not the fully - // qualified path of the actual contract module. - // Adding the contract name to the module path allows to get the fully qualified path - fn contract_path(&self, module_path: &String) -> String { - format!("{}{}{}", module_path, CAIRO_PATH_SEPARATOR, self.name) - } -} + let annotation = ContractAnnotation { + qualified_path: contract_qualified_path.clone(), + class_hash: artifact.class_hash, + tag: naming::get_tag(&self.namespace, &self.name), + systems: self.systems.clone(), + }; -impl AuxDataProcessor for StarkNetContractAuxData { - const ELEMENT_NAME: &'static str = "starknet contract"; + trace!( + contract_path = contract_qualified_path, + ?self, + "Generating annotations for dojo contract {} ({}).", + annotation.tag, + annotation.qualified_path, + ); - fn insert(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String) { - dojo_aux_data - .sn_contracts - .insert(module_path.clone(), self.contract_path(module_path)); + Ok(annotation) } +} - fn contract_path(&self, _module_path: &String) -> String { - self.contract_name.to_string() +impl AuxDataToAnnotation for StarkNetContractAuxData { + fn contract_qualified_path(&self, module_path: &String) -> String { + // The qualified path for starknet contracts is the same as the module path. + module_path.clone() } - // As every contracts and models are starknet contracts under the hood, - // we need to filter already processed Starknet contracts. - // Also important to note that, the module id for a starknet contract is - // already the fully qualified path of the contract. - // - // Important to note that all the dojo-core contracts are starknet contracts - // (currently world, base and resource_metadata model). They will be added here - // but we may choose to ignore them. - fn process(&self, dojo_aux_data: &mut DojoAuxData, module_path: &String) - where - Self: Sized, - { - if !dojo_aux_data.contains_starknet_contract(&module_path) { - trace!( - %module_path, - contract_name = self.contract_path(module_path), - "Adding {} to aux data.", - Self::ELEMENT_NAME - ); - - self.insert(dojo_aux_data, module_path); - } - } -} + fn to_annotation( + &self, + artifact_manager: &ArtifactManager, + module_path: &String, + ) -> Result { + let contract_qualified_path = self.contract_qualified_path(&module_path); -/// Dojo related auxiliary data of the Dojo plugin. -/// -/// All the keys are full paths to the cairo module that contains the expanded code. -/// This eases the match with compiled artifacts that are using the fully qualified path -/// as keys. -#[derive(Debug, Default, PartialEq)] -pub struct DojoAuxData { - /// A list of events that were processed by the plugin. - pub events: HashMap, - /// A list of models that were processed by the plugin. - pub models: HashMap, - /// A list of contracts that were processed by the plugin. - pub contracts: HashMap, - /// A list of starknet contracts that were processed by the plugin (qualified path, contract name). - pub sn_contracts: HashMap, -} + let artifact = artifact_manager + .get_artifact(&contract_qualified_path) + .ok_or(anyhow::anyhow!("Artifact not found"))?; -impl DojoAuxData { - /// Checks if a starknet contract with the given qualified path has been processed - /// for a contract or a model. - pub fn contains_starknet_contract(&self, qualified_path: &str) -> bool { - self.contracts.contains_key(qualified_path) - || self.models.contains_key(qualified_path) - || self.events.contains_key(qualified_path) - } + let annotation = StarknetContractAnnotation { + qualified_path: contract_qualified_path.clone(), + class_hash: artifact.class_hash, + name: self.contract_name.to_string(), + }; - /// Creates a new `DojoAuxData` from a list of crate ids and a database by introspecting - /// the generated files of each module in the database. - pub fn from_crates(crate_ids: &[CrateId], db: &RootDatabase) -> Self { - let mut dojo_aux_data = DojoAuxData::default(); - - for crate_id in crate_ids { - for module_id in db.crate_modules(*crate_id).as_ref() { - let file_infos = db - .module_generated_file_infos(*module_id) - .unwrap_or(std::sync::Arc::new([])); - - // Skip(1) to avoid internal aux data of Starknet aux data. - for aux_data in file_infos - .iter() - .skip(1) - .filter_map(|info| info.as_ref().map(|i| &i.aux_data)) - .filter_map(|aux_data| aux_data.as_ref().map(|aux_data| aux_data.0.as_any())) - { - let module_path = module_id.full_path(db); - - if let Some(aux_data) = aux_data.downcast_ref::() { - aux_data.process(&mut dojo_aux_data, &module_path); - continue; - } - - if let Some(aux_data) = aux_data.downcast_ref::() { - aux_data.process(&mut dojo_aux_data, &module_path); - continue; - } - - if let Some(aux_data) = aux_data.downcast_ref::() { - aux_data.process(&mut dojo_aux_data, &module_path); - continue; - } - - if let Some(aux_data) = aux_data.downcast_ref::() { - aux_data.process(&mut dojo_aux_data, &module_path); - } - } - } - } + trace!( + contract_path = contract_qualified_path, + ?self, + "Generating annotations for starknet contract {} ({}).", + annotation.name, + annotation.qualified_path, + ); - dojo_aux_data + Ok(annotation) } } diff --git a/crates/compiler/src/compiler/annotation.rs b/crates/compiler/src/compiler/annotation.rs new file mode 100644 index 0000000..466bf14 --- /dev/null +++ b/crates/compiler/src/compiler/annotation.rs @@ -0,0 +1,212 @@ +//! Dojo resource annotations. +//! +//! The dojo resource annotations are used to annotate the artifacts +//! generated by the compiler with information about the Dojo resources +//! found during the compilation process. + +use std::io::{Read, Write}; + +use anyhow::Result; +use scarb::core::Workspace; +use serde::{Deserialize, Serialize}; +use serde_with::serde_as; +use starknet::core::serde::unsigned_field_element::UfeHex; +use starknet::core::types::Felt; + +use crate::scarb_extensions::WorkspaceExt; +use crate::{BASE_CONTRACT_TAG, BASE_QUALIFIED_PATH, WORLD_CONTRACT_TAG, WORLD_QUALIFIED_PATH}; + +const DOJO_ANNOTATION_FILE_NAME: &str = "annotations"; + +/// Represents a member of a struct. +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub struct Member { + // Name of the member. + pub name: String, + // Type of the member. + #[serde(rename = "type")] + pub ty: String, + // Whether the member is a key. + pub key: bool, +} + +/// Represents the annotations of a dojo contract. +#[serde_as] +#[derive(Clone, Default, Debug, Serialize, Deserialize)] +#[cfg_attr(test, derive(PartialEq))] +#[serde(tag = "kind", rename = "DojoContract")] +pub struct ContractAnnotation { + #[serde_as(as = "UfeHex")] + pub class_hash: Felt, + pub qualified_path: String, + pub tag: String, + pub systems: Vec, +} + +/// Represents the annotations of a dojo model. +#[serde_as] +#[derive(Clone, Default, Debug, Serialize, Deserialize)] +#[cfg_attr(test, derive(PartialEq))] +#[serde(tag = "kind", rename = "DojoModel")] +pub struct ModelAnnotation { + #[serde_as(as = "UfeHex")] + pub class_hash: Felt, + pub qualified_path: String, + pub tag: String, + pub members: Vec, +} + +/// Represents the annotations of a dojo event. +#[serde_as] +#[derive(Clone, Default, Debug, Serialize, Deserialize)] +#[cfg_attr(test, derive(PartialEq))] +#[serde(tag = "kind", rename = "DojoEvent")] +pub struct EventAnnotation { + #[serde_as(as = "UfeHex")] + pub class_hash: Felt, + pub qualified_path: String, + pub tag: String, + pub members: Vec, +} + +/// Represents the world contract annotation. +#[serde_as] +#[derive(Clone, Debug, Serialize, Deserialize)] +#[cfg_attr(test, derive(PartialEq))] +#[serde(tag = "kind", rename = "DojoWorld")] +pub struct WorldAnnotation { + #[serde_as(as = "UfeHex")] + pub class_hash: Felt, + pub qualified_path: String, + pub tag: String, +} + +impl Default for WorldAnnotation { + fn default() -> Self { + Self { + class_hash: Felt::ZERO, + qualified_path: WORLD_QUALIFIED_PATH.to_string(), + tag: WORLD_CONTRACT_TAG.to_string(), + } + } +} + +/// Represents the base contract annotation. +#[serde_as] +#[derive(Clone, Debug, Serialize, Deserialize)] +#[cfg_attr(test, derive(PartialEq))] +#[serde(tag = "kind", rename = "DojoBase")] +pub struct BaseAnnotation { + #[serde_as(as = "UfeHex")] + pub class_hash: Felt, + pub qualified_path: String, + pub tag: String, +} + +impl Default for BaseAnnotation { + fn default() -> Self { + Self { + class_hash: Felt::ZERO, + qualified_path: BASE_QUALIFIED_PATH.to_string(), + tag: BASE_CONTRACT_TAG.to_string(), + } + } +} + +/// Represents the annotations of a starknet contract. +#[serde_as] +#[derive(Clone, Default, Debug, Serialize, Deserialize)] +#[cfg_attr(test, derive(PartialEq))] +#[serde(tag = "kind", rename = "StarknetContract")] +pub struct StarknetContractAnnotation { + #[serde_as(as = "UfeHex")] + pub class_hash: Felt, + pub qualified_path: String, + pub name: String, +} + +/// An abstract representation of the annotations of dojo resources. +#[derive(Clone, Debug, Default, Serialize, Deserialize)] +pub struct DojoAnnotation { + pub world: WorldAnnotation, + pub base: BaseAnnotation, + pub contracts: Vec, + pub models: Vec, + pub events: Vec, + pub sn_contracts: Vec, +} + +impl DojoAnnotation { + /// Creates a new abstract base manifest. + pub fn new() -> Self { + Self { + world: WorldAnnotation::default(), + base: BaseAnnotation::default(), + contracts: vec![], + models: vec![], + events: vec![], + sn_contracts: vec![], + } + } + + /// Checks if the provided qualified path is a dojo resource. + pub fn is_dojo_resource(&self, qualified_path: &str) -> bool { + self.contracts + .iter() + .any(|c| c.qualified_path == qualified_path) + || self + .models + .iter() + .any(|m| m.qualified_path == qualified_path) + || self + .events + .iter() + .any(|e| e.qualified_path == qualified_path) + || self.world.qualified_path == qualified_path + || self.base.qualified_path == qualified_path + } + + /// Reads the annotations from the target directory of the provided workspace, + /// for the current profile. + /// + /// # Arguments + /// + /// * `workspace` - The workspace to read the annotations from. + pub fn read(workspace: &Workspace) -> Result { + let target_dir = workspace.target_dir_profile(); + + let mut file = target_dir.open_ro( + format!("{}.toml", DOJO_ANNOTATION_FILE_NAME), + &format!("Dojo annotations"), + workspace.config(), + )?; + + let mut content = String::new(); + file.read_to_string(&mut content)?; + + let annotations = toml::from_str(&content)?; + + Ok(annotations) + } + + /// Writes the annotations to the target directory of the provided workspace, + /// for the current profile. + /// + /// # Arguments + /// + /// * `workspace` - The workspace to write the annotations to. + pub fn write(&self, workspace: &Workspace) -> Result<()> { + let target_dir = workspace.target_dir_profile(); + let content = toml::to_string(&self)?; + + let mut file = target_dir.open_rw( + format!("{}.toml", DOJO_ANNOTATION_FILE_NAME), + &format!("Dojo annotations"), + workspace.config(), + )?; + + file.write(content.as_bytes())?; + + Ok(()) + } +} diff --git a/crates/compiler/src/compiler/artifact_manager.rs b/crates/compiler/src/compiler/artifact_manager.rs index 33ea0bb..5e526c8 100644 --- a/crates/compiler/src/compiler/artifact_manager.rs +++ b/crates/compiler/src/compiler/artifact_manager.rs @@ -14,12 +14,25 @@ use std::ops::DerefMut; use std::rc::Rc; use anyhow::{Context, Result}; +use cairo_lang_compiler::db::RootDatabase; +use cairo_lang_defs::db::DefsGroup; +use cairo_lang_filesystem::ids::CrateId; +use cairo_lang_starknet::plugin::aux_data::StarkNetContractAuxData; use cairo_lang_starknet_classes::contract_class::ContractClass; +use dojo_types::naming; use scarb::core::Workspace; use scarb::flock::Filesystem; use starknet::core::types::Felt; use tracing::trace; +use crate::aux_data::{AuxDataToAnnotation, ContractAuxData, EventAuxData, ModelAuxData}; +use crate::scarb_extensions::WorkspaceExt; +use crate::{ + BASE_CONTRACT_TAG, BASE_QUALIFIED_PATH, CAIRO_PATH_SEPARATOR, CONTRACTS_DIR, EVENTS_DIR, + MODELS_DIR, RESOURCE_METADATA_QUALIFIED_PATH, WORLD_CONTRACT_TAG, WORLD_QUALIFIED_PATH, +}; + +use super::annotation::{BaseAnnotation, DojoAnnotation, WorldAnnotation}; use super::scarb_internal::debug::SierraToCairoDebugInfo; #[derive(Debug, Clone)] @@ -40,6 +53,8 @@ pub struct ArtifactManager<'w> { workspace: &'w Workspace<'w>, /// The compiled artifacts. compiled_artifacts: CompiledArtifactByPath, + /// Dojo annotations. + dojo_annotations: DojoAnnotation, } impl<'w> ArtifactManager<'w> { @@ -48,7 +63,88 @@ impl<'w> ArtifactManager<'w> { Self { workspace, compiled_artifacts: HashMap::new(), + dojo_annotations: DojoAnnotation::default(), + } + } + + /// Sets the dojo annotations form the aux data extracted from the database. + pub fn set_dojo_annotations(&mut self, db: &RootDatabase, crate_ids: &[CrateId]) -> Result<()> { + // Ensures that the dojo annotations are empty to not keep any stale data. + self.dojo_annotations = DojoAnnotation::default(); + + for crate_id in crate_ids { + for module_id in db.crate_modules(*crate_id).as_ref() { + let file_infos = db + .module_generated_file_infos(*module_id) + .unwrap_or(std::sync::Arc::new([])); + + // Skip(1) to avoid internal aux data of Starknet aux data. + for aux_data in file_infos + .iter() + .skip(1) + .filter_map(|info| info.as_ref().map(|i| &i.aux_data)) + .filter_map(|aux_data| aux_data.as_ref().map(|aux_data| aux_data.0.as_any())) + { + let module_path = module_id.full_path(db); + + if let Some(aux_data) = aux_data.downcast_ref::() { + let annotation = aux_data.to_annotation(self, &module_path)?; + self.dojo_annotations.contracts.push(annotation); + continue; + } + + if let Some(aux_data) = aux_data.downcast_ref::() { + let annotation = aux_data.to_annotation(self, &module_path)?; + self.dojo_annotations.models.push(annotation); + continue; + } + + if let Some(aux_data) = aux_data.downcast_ref::() { + let annotation = aux_data.to_annotation(self, &module_path)?; + self.dojo_annotations.events.push(annotation); + continue; + } + + if let Some(aux_data) = aux_data.downcast_ref::() { + let annotation = aux_data.to_annotation(self, &module_path)?; + + if annotation.qualified_path == WORLD_QUALIFIED_PATH { + self.dojo_annotations.world = WorldAnnotation { + class_hash: annotation.class_hash, + qualified_path: WORLD_QUALIFIED_PATH.to_string(), + tag: WORLD_CONTRACT_TAG.to_string(), + }; + } else if annotation.qualified_path == BASE_QUALIFIED_PATH { + self.dojo_annotations.base = BaseAnnotation { + class_hash: annotation.class_hash, + qualified_path: BASE_QUALIFIED_PATH.to_string(), + tag: BASE_CONTRACT_TAG.to_string(), + }; + } else if annotation.qualified_path == RESOURCE_METADATA_QUALIFIED_PATH { + // Skip this annotation as not used in the migration process. + continue; + } else { + self.dojo_annotations.sn_contracts.push(annotation); + } + } + } + } } + + // Since dojo resources are just starknet contracts under the hood, + // we remove them from the sn_contracts list. We can't filter them earlier + // as we need to wait all the annotations to be extracted before filtering. + let mut filtered_sn_contracts = self.dojo_annotations.sn_contracts.clone(); + + filtered_sn_contracts.retain(|sn_contract| { + !self + .dojo_annotations + .is_dojo_resource(&sn_contract.qualified_path) + }); + + self.dojo_annotations.sn_contracts = filtered_sn_contracts; + + Ok(()) } /// Returns the workspace of the current compilation. @@ -86,6 +182,45 @@ impl<'w> ArtifactManager<'w> { self.compiled_artifacts.insert(qualified_path, artifact); } + /// Writes all the dojo annotations and artifacts to the filesystem. + pub fn write(&self) -> Result<()> { + self.dojo_annotations.write(self.workspace)?; + + let target_dir = self.workspace.target_dir_profile(); + + self.write_sierra_class(WORLD_QUALIFIED_PATH, &target_dir, WORLD_CONTRACT_TAG)?; + self.write_sierra_class(BASE_QUALIFIED_PATH, &target_dir, BASE_CONTRACT_TAG)?; + + for contract in &self.dojo_annotations.contracts { + let filename = naming::get_filename_from_tag(&contract.tag); + let target_dir = target_dir.child(CONTRACTS_DIR); + self.write_sierra_class(&contract.qualified_path, &target_dir, &filename)?; + } + + for model in &self.dojo_annotations.models { + let filename = naming::get_filename_from_tag(&model.tag); + let target_dir = target_dir.child(MODELS_DIR); + self.write_sierra_class(&model.qualified_path, &target_dir, &filename)?; + } + + for event in &self.dojo_annotations.events { + let filename = naming::get_filename_from_tag(&event.tag); + let target_dir = target_dir.child(EVENTS_DIR); + self.write_sierra_class(&event.qualified_path, &target_dir, &filename)?; + } + + for sn_contract in &self.dojo_annotations.sn_contracts { + // TODO: we might want to use namespace for starknet contracts too. + let file_name = sn_contract + .qualified_path + .replace(CAIRO_PATH_SEPARATOR, "_"); + + self.write_sierra_class(&sn_contract.qualified_path, &target_dir, &file_name)?; + } + + Ok(()) + } + /// Saves a Sierra contract class to a JSON file. /// If debug info is available, it will also be saved to a separate file. /// diff --git a/crates/compiler/src/compiler/compiler.rs b/crates/compiler/src/compiler/compiler.rs index de82244..dca0d79 100644 --- a/crates/compiler/src/compiler/compiler.rs +++ b/crates/compiler/src/compiler/compiler.rs @@ -27,10 +27,6 @@ use starknet::core::types::contract::SierraClass; use starknet::core::types::Felt; use tracing::{trace, trace_span}; -use crate::aux_data::{AuxDataTrait, ContractAuxData, DojoAuxData, EventAuxData, ModelAuxData}; -use crate::compiler::manifest::{ - AbstractBaseManifest, ContractManifest, EventManifest, ModelManifest, StarknetContractManifest, -}; use crate::scarb_extensions::{ProfileSpec, WorkspaceExt}; use crate::{ BASE_CONTRACT_TAG, BASE_QUALIFIED_PATH, CAIRO_PATH_SEPARATOR, CONTRACTS_DIR, EVENTS_DIR, @@ -39,11 +35,12 @@ use crate::{ use super::artifact_manager::{ArtifactManager, CompiledArtifact}; use super::contract_selector::ContractSelector; -use super::manifest::FromAuxDataTrait; use super::scarb_internal; use super::scarb_internal::debug::SierraToCairoDebugInfo; use super::version::check_package_dojo_version; +pub const DOJO_TARGET_NAME: &str = "dojo"; + #[derive(Debug, Default)] pub struct DojoCompiler { /// Output the debug information of the compiled Sierra contracts. @@ -78,7 +75,7 @@ impl DojoCompiler { ws.profile_check()?; - DojoCompiler::clean(config, ProfileSpec::WorkspaceCurrent, true)?; + DojoCompiler::clean(config, ProfileSpec::WorkspaceCurrent)?; trace!(?packages); @@ -98,11 +95,7 @@ impl DojoCompiler { Ok(()) } - pub fn clean( - config: &Config, - profile_spec: ProfileSpec, - remove_base_manifests: bool, - ) -> Result<()> { + pub fn clean(config: &Config, profile_spec: ProfileSpec) -> Result<()> { let ws = scarb::ops::read_workspace(config.manifest_path(), config)?; ws.profile_check()?; @@ -115,7 +108,6 @@ impl DojoCompiler { trace!( profile = profile_name, ?profile_spec, - remove_base_manifests, "Cleaning dojo compiler artifacts." ); @@ -124,20 +116,10 @@ impl DojoCompiler { ProfileSpec::All => { let target_dir = ws.target_dir(); let _ = fs::remove_dir_all(target_dir.to_string()); - - if remove_base_manifests { - let manifest_dir = ws.dojo_manifests_dir(); - let _ = fs::remove_dir_all(manifest_dir.to_string()); - } } ProfileSpec::WorkspaceCurrent => { let target_dir_profile = ws.target_dir_profile(); let _ = fs::remove_dir_all(target_dir_profile.to_string()); - - if remove_base_manifests { - let manifest_dir_profile = ws.dojo_base_manfiests_dir_profile(); - let _ = fs::remove_dir_all(manifest_dir_profile.to_string()); - } } } @@ -164,9 +146,14 @@ impl Props { } } +/// Implements the `Compiler` trait for the `DojoCompiler`. +/// +/// The `compile` method is the entry point for the compilation process +/// if the dojo target is used, which is called after the pre-processing +/// of the Cairo compiler (where the dojo plugin is actually executed). impl Compiler for DojoCompiler { fn target_kind(&self) -> TargetKind { - TargetKind::new("dojo") + TargetKind::new(DOJO_TARGET_NAME) } fn compile( @@ -190,43 +177,11 @@ impl Compiler for DojoCompiler { &ws.config().ui(), )?; - let artifact_manager = + let mut artifact_manager = compile_contracts(db, &contracts, compiler_config, &ws, self.output_debug_info)?; - let aux_data = DojoAuxData::from_crates(&main_crate_ids, db); - - let mut base_manifest = AbstractBaseManifest::new(ws); - - // Combine the aux data info about the contracts with the artifact data - // to create the manifests. - let contracts = write_dojo_resource_artifacts::( - &artifact_manager, - &aux_data.contracts, - CONTRACTS_DIR, - )?; - let models = write_dojo_resource_artifacts::( - &artifact_manager, - &aux_data.models, - MODELS_DIR, - )?; - let events = write_dojo_resource_artifacts::( - &artifact_manager, - &aux_data.events, - EVENTS_DIR, - )?; - let (world, base, sn_contracts) = - write_sn_contract_artifacts(&artifact_manager, &aux_data)?; - - base_manifest.world = world; - base_manifest.base = base; - base_manifest.contracts.extend(contracts); - base_manifest.models.extend(models); - base_manifest.events.extend(events); - base_manifest.sn_contracts.extend(sn_contracts); - - base_manifest.write()?; - - // TODO: add a check to ensure all the artifacts have been processed? + artifact_manager.set_dojo_annotations(db, &main_crate_ids)?; + artifact_manager.write()?; Ok(()) } @@ -430,94 +385,3 @@ pub fn collect_crates_ids_from_selectors( .map(|package_name: SmolStr| db.intern_crate(CrateLongId::Real(package_name))) .collect::>() } - -/// Writes the dojo resource artifacts to the target directory and returns the resource manifests. -fn write_dojo_resource_artifacts>( - artifact_manager: &ArtifactManager, - aux_data: &HashMap, - element_dir: &str, -) -> Result> { - let mut elements = Vec::new(); - - for (qualified_path, aux_data) in aux_data.iter() { - let filename = naming::get_filename_from_tag(&aux_data.tag()); - - let target_dir = artifact_manager - .workspace() - .target_dir_profile() - .child(element_dir); - - artifact_manager.write_sierra_class(qualified_path, &target_dir, &filename)?; - elements.push(U::from_aux_data( - aux_data, - artifact_manager.get_class_hash(qualified_path)?, - qualified_path, - )); - } - - Ok(elements) -} - -/// Writes the starknet contracts artifacts to the target directory and returns the starknet contract manifests. -/// -/// Returns a tuple with the world contract manifest, the base contract manifest and the other starknet contract manifests. -fn write_sn_contract_artifacts( - artifact_manager: &ArtifactManager, - aux_data: &DojoAuxData, -) -> Result<( - StarknetContractManifest, - StarknetContractManifest, - Vec, -)> { - let mut contracts = Vec::new(); - let mut world = StarknetContractManifest::default(); - let mut base = StarknetContractManifest::default(); - - for (qualified_path, contract_name) in aux_data.sn_contracts.iter() { - let target_dir = artifact_manager.workspace().target_dir_profile(); - - let file_name = match qualified_path.as_str() { - WORLD_QUALIFIED_PATH => { - let name = WORLD_CONTRACT_TAG.to_string(); - - world = StarknetContractManifest { - class_hash: artifact_manager.get_class_hash(qualified_path)?, - qualified_path: qualified_path.to_string(), - name: name.clone(), - }; - - name - } - BASE_QUALIFIED_PATH => { - let name = BASE_CONTRACT_TAG.to_string(); - - base = StarknetContractManifest { - class_hash: artifact_manager.get_class_hash(qualified_path)?, - qualified_path: qualified_path.to_string(), - name: name.clone(), - }; - - name - } - RESOURCE_METADATA_QUALIFIED_PATH => { - // Skip this dojo contract as not used in the migration process. - continue; - } - _ => { - let file_name = qualified_path.replace(CAIRO_PATH_SEPARATOR, "_"); - - contracts.push(StarknetContractManifest { - class_hash: artifact_manager.get_class_hash(qualified_path)?, - qualified_path: qualified_path.to_string(), - name: contract_name.clone(), - }); - - file_name - } - }; - - artifact_manager.write_sierra_class(qualified_path, &target_dir, &file_name)?; - } - - Ok((world, base, contracts)) -} diff --git a/crates/compiler/src/compiler/manifest.rs b/crates/compiler/src/compiler/manifest.rs deleted file mode 100644 index de6a752..0000000 --- a/crates/compiler/src/compiler/manifest.rs +++ /dev/null @@ -1,367 +0,0 @@ -//! Manifests generated by the compiler. -//! -//! The manifests files contains metadata about -//! the contracts being compiled, since in Dojo -//! every resource is represented as a starknet contract. - -use std::io::{Read, Write}; - -use anyhow::Result; -use dojo_types::naming; -use scarb::core::{Config, Workspace}; -use serde::{Deserialize, Serialize}; -use serde_with::serde_as; -use starknet::core::serde::unsigned_field_element::UfeHex; -use starknet::core::types::Felt; - -use crate::aux_data::{AuxDataTrait, ContractAuxData, EventAuxData, ModelAuxData}; -use crate::scarb_extensions::{FilesystemExt, WorkspaceExt}; -use crate::{ - BASE_CONTRACT_TAG, CAIRO_PATH_SEPARATOR, CONTRACTS_DIR, EVENTS_DIR, MODELS_DIR, - WORLD_CONTRACT_TAG, -}; - -const TOML_EXTENSION: &str = "toml"; - -/// Represents a member of a struct. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] -pub struct Member { - // Name of the member. - pub name: String, - // Type of the member. - #[serde(rename = "type")] - pub ty: String, - // Whether the member is a key. - pub key: bool, -} - -pub trait ManifestMethods { - fn type_name(&self) -> String; - fn tag(&self) -> String; - fn qualified_path(&self) -> String; - fn to_toml_string(&self) -> Result; -} - -pub trait FromAuxDataTrait { - fn from_aux_data(aux_data: &T, class_hash: Felt, qualified_path: &String) -> Self; -} - -/// Represents the contract of a dojo contract. -#[serde_as] -#[derive(Clone, Default, Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq))] -#[serde(tag = "kind", rename = "DojoContract")] -pub struct ContractManifest { - #[serde_as(as = "UfeHex")] - pub class_hash: Felt, - pub qualified_path: String, - pub tag: String, - pub systems: Vec, -} - -impl ManifestMethods for ContractManifest { - fn type_name(&self) -> String { - "contract".to_string() - } - - fn tag(&self) -> String { - self.tag.clone() - } - fn qualified_path(&self) -> String { - self.qualified_path.clone() - } - fn to_toml_string(&self) -> Result { - toml::to_string(self) - } -} - -impl FromAuxDataTrait for ContractManifest { - fn from_aux_data( - aux_data: &ContractAuxData, - class_hash: Felt, - qualified_path: &String, - ) -> Self { - Self { - class_hash, - qualified_path: qualified_path.clone(), - tag: aux_data.tag(), - systems: aux_data.systems.clone(), - } - } -} - -/// Represents the contract of a dojo model. -#[serde_as] -#[derive(Clone, Default, Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq))] -#[serde(tag = "kind", rename = "DojoModel")] -pub struct ModelManifest { - #[serde_as(as = "UfeHex")] - pub class_hash: Felt, - pub qualified_path: String, - pub tag: String, - pub members: Vec, -} - -impl ManifestMethods for ModelManifest { - fn type_name(&self) -> String { - "model".to_string() - } - - fn tag(&self) -> String { - self.tag.clone() - } - fn qualified_path(&self) -> String { - self.qualified_path.clone() - } - fn to_toml_string(&self) -> Result { - toml::to_string(self) - } -} - -impl FromAuxDataTrait for ModelManifest { - fn from_aux_data(aux_data: &ModelAuxData, class_hash: Felt, qualified_path: &String) -> Self { - Self { - class_hash, - qualified_path: qualified_path.clone(), - tag: aux_data.tag(), - members: aux_data.members.clone(), - } - } -} - -/// Represents the contract of a dojo event. -#[serde_as] -#[derive(Clone, Default, Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq))] -#[serde(tag = "kind", rename = "DojoEvent")] -pub struct EventManifest { - #[serde_as(as = "UfeHex")] - pub class_hash: Felt, - pub qualified_path: String, - pub tag: String, - pub members: Vec, -} - -impl ManifestMethods for EventManifest { - fn type_name(&self) -> String { - "event".to_string() - } - - fn tag(&self) -> String { - self.tag.clone() - } - fn qualified_path(&self) -> String { - self.qualified_path.clone() - } - fn to_toml_string(&self) -> Result { - toml::to_string(self) - } -} - -impl FromAuxDataTrait for EventManifest { - fn from_aux_data(aux_data: &EventAuxData, class_hash: Felt, qualified_path: &String) -> Self { - Self { - class_hash, - qualified_path: qualified_path.clone(), - tag: aux_data.tag(), - members: aux_data.members.clone(), - } - } -} - -/// Represents a starknet contract. -#[serde_as] -#[derive(Clone, Default, Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq))] -#[serde(tag = "kind", rename = "StarknetContract")] -pub struct StarknetContractManifest { - #[serde_as(as = "UfeHex")] - pub class_hash: Felt, - pub qualified_path: String, - pub name: String, -} - -/// An abstract representation of the manifest files combined. -/// -/// An [`AbstractBaseManifest`] internalizes the workspace reference -/// to automatically provide the paths to the manifest files based on the -/// workspace configuration. -#[derive(Clone, Debug)] -pub struct AbstractBaseManifest<'w> { - workspace: &'w Workspace<'w>, - pub world: StarknetContractManifest, - pub base: StarknetContractManifest, - pub contracts: Vec, - pub models: Vec, - pub events: Vec, - pub sn_contracts: Vec, -} - -impl<'w> AbstractBaseManifest<'w> { - /// Creates a new abstract base manifest. - pub fn new(workspace: &'w Workspace) -> Self { - Self { - workspace, - world: StarknetContractManifest::default(), - base: StarknetContractManifest::default(), - contracts: vec![], - models: vec![], - events: vec![], - sn_contracts: vec![], - } - } - - pub fn read(&mut self) -> Result<()> { - fn read_elements( - config: &Config, - name: &str, - dir: scarb::flock::Filesystem, - vec: &mut Vec, - ) -> Result<()> - where - T: serde::de::DeserializeOwned, - { - for file_name in dir.list_files()? { - let mut file = dir.open_ro( - &file_name, - &format!("{name} manifest for `{}`", &file_name), - config, - )?; - let mut s = String::new(); - file.read_to_string(&mut s)?; - vec.push(toml::from_str(&s)?); - } - - Ok(()) - } - - let base_dir = self.workspace.dojo_base_manfiests_dir_profile(); - - read_elements( - self.workspace.config(), - "contract", - base_dir.child(CONTRACTS_DIR), - &mut self.contracts, - )?; - read_elements( - self.workspace.config(), - "model", - base_dir.child(MODELS_DIR), - &mut self.models, - )?; - read_elements( - self.workspace.config(), - "event", - base_dir.child(EVENTS_DIR), - &mut self.events, - )?; - - for file_name in base_dir.list_files()? { - let mut file = base_dir.open_ro( - &file_name, - &format!("starknet contract manifest for `{}`", &file_name), - self.workspace.config(), - )?; - let mut sn_contract_str = String::new(); - file.read_to_string(&mut sn_contract_str)?; - - if file_name == format!("{}.toml", naming::get_filename_from_tag(WORLD_CONTRACT_TAG)) { - self.world = toml::from_str(&sn_contract_str)?; - } else if file_name - == format!("{}.toml", naming::get_filename_from_tag(BASE_CONTRACT_TAG)) - { - self.base = toml::from_str(&sn_contract_str)?; - } else { - self.sn_contracts.push(toml::from_str(&sn_contract_str)?); - } - } - - Ok(()) - } - - /// Writes the manifest to the given path. - /// - /// # Arguments - /// - /// * `path` - The path to write the manifest files to. - pub fn write(&self) -> Result<()> { - fn write_element( - config: &Config, - dir: scarb::flock::Filesystem, - elements: &Vec, - ) -> Result<()> - where - T: ManifestMethods, - { - for element in elements { - let name = format!( - "{}.{}", - naming::get_filename_from_tag(&element.tag()), - TOML_EXTENSION - ); - - let mut file = dir.open_rw( - name, - &format!( - "{} manifest for `{}`", - element.type_name(), - element.qualified_path() - ), - config, - )?; - - file.write(element.to_toml_string()?.as_bytes())?; - } - - Ok(()) - } - - let base_dir = self.workspace.dojo_base_manfiests_dir_profile(); - - let world = toml::to_string(&self.world)?; - - let mut file = base_dir.open_rw( - format!("{}.toml", naming::get_filename_from_tag(WORLD_CONTRACT_TAG)), - &format!("world manifest"), - self.workspace.config(), - )?; - - file.write(world.as_bytes())?; - - let base = toml::to_string(&self.base)?; - - let mut file = base_dir.open_rw( - format!("{}.toml", naming::get_filename_from_tag(BASE_CONTRACT_TAG)), - &format!("base manifest"), - self.workspace.config(), - )?; - - file.write(base.as_bytes())?; - - let config = self.workspace.config(); - write_element(config, base_dir.child(CONTRACTS_DIR), &self.contracts)?; - write_element(config, base_dir.child(MODELS_DIR), &self.models)?; - write_element(config, base_dir.child(EVENTS_DIR), &self.events)?; - - for sn_contract in &self.sn_contracts { - let name = format!( - "{}.{}", - sn_contract - .qualified_path - .replace(CAIRO_PATH_SEPARATOR, "_"), - TOML_EXTENSION - ); - - let mut file = base_dir.open_rw( - name, - &format!("starknet contract manifest for `{}`", sn_contract.name), - self.workspace.config(), - )?; - - file.write(toml::to_string(sn_contract)?.as_bytes())?; - } - - Ok(()) - } -} diff --git a/crates/compiler/src/compiler/mod.rs b/crates/compiler/src/compiler/mod.rs index ea22da0..6f4e6b1 100644 --- a/crates/compiler/src/compiler/mod.rs +++ b/crates/compiler/src/compiler/mod.rs @@ -1,8 +1,8 @@ +pub mod annotation; pub mod artifact_manager; pub mod compiler; pub mod config; pub mod contract_selector; -pub mod manifest; pub mod scarb_internal; pub mod version; diff --git a/crates/compiler/src/compiler/scarb_internal/mod.rs b/crates/compiler/src/compiler/scarb_internal/mod.rs index 34998f1..6061c06 100644 --- a/crates/compiler/src/compiler/scarb_internal/mod.rs +++ b/crates/compiler/src/compiler/scarb_internal/mod.rs @@ -25,7 +25,7 @@ use tracing::trace; use crate::compiler::config::{CompilerConfig, DojoConfigLoader}; use crate::namespace_config::{ - NamespaceConfig, DEFAULT_NAMESPACE_CFG_KEY, DOJO_MANIFESTS_DIR_CFG_KEY, NAMESPACE_CFG_PREFIX, + NamespaceConfig, DEFAULT_NAMESPACE_CFG_KEY, DOJO_ANNOTATIONS_DIR_CFG_KEY, NAMESPACE_CFG_PREFIX, WORKSPACE_CURRENT_PROFILE_CFG_KEY, }; use crate::plugin::plugin::dojo_plugin_suite; @@ -271,8 +271,8 @@ pub fn cfg_set_from_component( cfg_set.insert(component_cfg); cfg_set.insert(Cfg { - key: DOJO_MANIFESTS_DIR_CFG_KEY.into(), - value: Some(ws.dojo_manifests_dir_profile().to_string().into()), + key: DOJO_ANNOTATIONS_DIR_CFG_KEY.into(), + value: Some(ws.target_dir_profile().to_string().into()), }); cfg_set.insert(Cfg { diff --git a/crates/compiler/src/contract_store.rs b/crates/compiler/src/contract_store.rs new file mode 100644 index 0000000..e69de29 diff --git a/crates/compiler/src/namespace_config.rs b/crates/compiler/src/namespace_config.rs index de717d1..c859404 100644 --- a/crates/compiler/src/namespace_config.rs +++ b/crates/compiler/src/namespace_config.rs @@ -7,7 +7,7 @@ use serde::Deserialize; pub const NAMESPACE_CFG_PREFIX: &str = "nm|"; pub const DEFAULT_NAMESPACE_CFG_KEY: &str = "namespace_default"; -pub const DOJO_MANIFESTS_DIR_CFG_KEY: &str = "dojo_manifests_dir"; +pub const DOJO_ANNOTATIONS_DIR_CFG_KEY: &str = "dojo_annotations_dir"; pub const WORKSPACE_CURRENT_PROFILE_CFG_KEY: &str = "ws_current_profile"; pub const DEFAULT_NAMESPACE: &str = "DEFAULT_NAMESPACE"; diff --git a/crates/compiler/src/plugin/attribute_macros/element.rs b/crates/compiler/src/plugin/attribute_macros/element.rs index 3d60f3f..3ddbaf4 100644 --- a/crates/compiler/src/plugin/attribute_macros/element.rs +++ b/crates/compiler/src/plugin/attribute_macros/element.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use crate::compiler::manifest::Member; +use crate::compiler::annotation::Member; use crate::namespace_config::NamespaceConfig; use cairo_lang_defs::patcher::RewriteNode; use cairo_lang_defs::plugin::PluginDiagnostic; diff --git a/crates/compiler/src/plugin/attribute_macros/model.rs b/crates/compiler/src/plugin/attribute_macros/model.rs index fb046fc..db818c2 100644 --- a/crates/compiler/src/plugin/attribute_macros/model.rs +++ b/crates/compiler/src/plugin/attribute_macros/model.rs @@ -15,7 +15,7 @@ use dojo_types::naming; use starknet::core::utils::get_selector_from_name; use crate::aux_data::ModelAuxData; -use crate::compiler::manifest::Member; +use crate::compiler::annotation::Member; use crate::namespace_config::NamespaceConfig; use crate::plugin::derive_macros::{ extract_derive_attr_names, handle_derive_attrs, DOJO_INTROSPECT_DERIVE, DOJO_PACKED_DERIVE, diff --git a/crates/compiler/src/plugin/inline_macros/utils.rs b/crates/compiler/src/plugin/inline_macros/utils.rs index c4622aa..222ad37 100644 --- a/crates/compiler/src/plugin/inline_macros/utils.rs +++ b/crates/compiler/src/plugin/inline_macros/utils.rs @@ -12,8 +12,8 @@ use dojo_types::naming; use scarb::compiler::Profile; use scarb::core::Config; -use crate::compiler::manifest::AbstractBaseManifest; -use crate::namespace_config::{DOJO_MANIFESTS_DIR_CFG_KEY, WORKSPACE_CURRENT_PROFILE_CFG_KEY}; +use crate::compiler::annotation::DojoAnnotation; +use crate::namespace_config::{DOJO_ANNOTATIONS_DIR_CFG_KEY, WORKSPACE_CURRENT_PROFILE_CFG_KEY}; #[derive(Debug)] pub enum SystemRWOpRecord { @@ -55,14 +55,12 @@ pub fn load_manifest_models_and_namespaces( let ws = scarb::ops::read_workspace(config.manifest_path(), &config)?; - let mut base_abstract_manifest = AbstractBaseManifest::new(&ws); + let annotations = DojoAnnotation::read(&ws)?; - base_abstract_manifest.read()?; + let mut models = HashSet::::new(); + let mut namespaces = HashSet::::new(); - let mut models = HashSet::new(); - let mut namespaces = HashSet::new(); - - for model in base_abstract_manifest.models { + for model in annotations.models { let qualified_path = model.qualified_path; let namespace = naming::split_tag(&model.tag)?.0; @@ -83,7 +81,7 @@ pub fn load_manifest_models_and_namespaces( /// Gets the dojo_manifests_dir for the current profile from the cfg_set. pub fn get_dojo_manifests_dir(cfg_set: CfgSet) -> anyhow::Result { for cfg in cfg_set.into_iter() { - if cfg.key == DOJO_MANIFESTS_DIR_CFG_KEY { + if cfg.key == DOJO_ANNOTATIONS_DIR_CFG_KEY { return Ok(Utf8PathBuf::from(cfg.value.unwrap().as_str().to_string())); } } diff --git a/crates/compiler/src/scarb_extensions.rs b/crates/compiler/src/scarb_extensions.rs index c451e3e..d3e99a5 100644 --- a/crates/compiler/src/scarb_extensions.rs +++ b/crates/compiler/src/scarb_extensions.rs @@ -57,12 +57,6 @@ impl FilesystemExt for Filesystem { pub trait WorkspaceExt { /// Returns the target directory for the current profile. fn target_dir_profile(&self) -> Filesystem; - /// Returns the manifests directory for the current profile. - fn dojo_base_manfiests_dir_profile(&self) -> Filesystem; - /// Returns the base manifests directory. - fn dojo_manifests_dir(&self) -> Filesystem; - /// Returns the manifests directory for the current profile. - fn dojo_manifests_dir_profile(&self) -> Filesystem; /// Checks if the current profile is valid for the workspace. fn profile_check(&self) -> Result<()>; } @@ -76,32 +70,6 @@ impl WorkspaceExt for Workspace<'_> { ) } - fn dojo_base_manfiests_dir_profile(&self) -> Filesystem { - let manifests_dir = self.dojo_manifests_dir(); - - manifests_dir.children(&[ - self.current_profile() - .expect("Current profile always exists") - .as_str(), - MANIFESTS_BASE_DIR, - ]) - } - - fn dojo_manifests_dir(&self) -> Filesystem { - let base_dir = self.manifest_path().parent().unwrap(); - Filesystem::new(base_dir.to_path_buf()).child(MANIFESTS_DIR) - } - - fn dojo_manifests_dir_profile(&self) -> Filesystem { - let manifests_dir = self.dojo_manifests_dir(); - - manifests_dir.child( - self.current_profile() - .expect("Current profile always exists") - .as_str(), - ) - } - fn profile_check(&self) -> Result<()> { if let Err(e) = self.current_profile() { if e.to_string().contains("has no profile") { From 6e65634ca8586f1fa035501c9bcd873e7160654e Mon Sep 17 00:00:00 2001 From: glihm Date: Tue, 8 Oct 2024 18:24:44 -0600 Subject: [PATCH 05/11] fix: simplify annotations since they are used by the artifacts manager --- crates/compiler/src/aux_data.rs | 64 +---- crates/compiler/src/compiler/annotation.rs | 149 ++++++++-- .../compiler/src/compiler/artifact_manager.rs | 265 ++++++++++-------- crates/compiler/src/compiler/compiler.rs | 11 +- .../src/compiler/scarb_internal/debug.rs | 10 +- .../src/plugin/attribute_macros/contract.rs | 4 +- crates/compiler/src/scarb_extensions.rs | 2 - 7 files changed, 301 insertions(+), 204 deletions(-) diff --git a/crates/compiler/src/aux_data.rs b/crates/compiler/src/aux_data.rs index f87f4ee..69d9e70 100644 --- a/crates/compiler/src/aux_data.rs +++ b/crates/compiler/src/aux_data.rs @@ -8,35 +8,32 @@ use cairo_lang_defs::plugin::GeneratedFileAuxData; use cairo_lang_starknet::plugin::aux_data::StarkNetContractAuxData; use convert_case::{Case, Casing}; use dojo_types::naming; -use smol_str::SmolStr; +use serde::{Deserialize, Serialize}; use tracing::trace; use super::compiler::annotation::Member; use crate::{ - compiler::{ - annotation::{ - ContractAnnotation, EventAnnotation, ModelAnnotation, StarknetContractAnnotation, - }, - artifact_manager::ArtifactManager, + compiler::annotation::{ + ContractAnnotation, EventAnnotation, ModelAnnotation, StarknetContractAnnotation, }, CAIRO_PATH_SEPARATOR, }; -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct ModelAuxData { pub name: String, pub namespace: String, pub members: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct ContractAuxData { - pub name: SmolStr, + pub name: String, pub namespace: String, pub systems: Vec, } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct EventAuxData { pub name: String, pub namespace: String, @@ -56,9 +53,8 @@ pub trait AuxDataToAnnotation { /// /// # Arguments /// - /// * `artifact_manager` - The artifact manager to get the class from the artifact. /// * `module_path` - The path to the module that generated the aux data. - fn to_annotation(&self, artifact_manager: &ArtifactManager, module_path: &String) -> Result; + fn to_annotation(&self, module_path: &String) -> Result; } impl GeneratedFileAuxData for ModelAuxData { @@ -90,20 +86,11 @@ impl AuxDataToAnnotation for ModelAuxData { ) } - fn to_annotation( - &self, - artifact_manager: &ArtifactManager, - module_path: &String, - ) -> Result { + fn to_annotation(&self, module_path: &String) -> Result { let contract_qualified_path = self.contract_qualified_path(&module_path); - let artifact = artifact_manager - .get_artifact(&contract_qualified_path) - .ok_or(anyhow::anyhow!("Artifact not found"))?; - let annotation = ModelAnnotation { qualified_path: contract_qualified_path.clone(), - class_hash: artifact.class_hash, tag: naming::get_tag(&self.namespace, &self.name), members: self.members.clone(), }; @@ -149,20 +136,11 @@ impl AuxDataToAnnotation for EventAuxData { ) } - fn to_annotation( - &self, - artifact_manager: &ArtifactManager, - module_path: &String, - ) -> Result { + fn to_annotation(&self, module_path: &String) -> Result { let contract_qualified_path = self.contract_qualified_path(&module_path); - let artifact = artifact_manager - .get_artifact(&contract_qualified_path) - .ok_or(anyhow::anyhow!("Artifact not found"))?; - let annotation = EventAnnotation { qualified_path: contract_qualified_path.clone(), - class_hash: artifact.class_hash, tag: naming::get_tag(&self.namespace, &self.name), members: self.members.clone(), }; @@ -201,20 +179,11 @@ impl AuxDataToAnnotation for ContractAuxData { format!("{}{}{}", module_path, CAIRO_PATH_SEPARATOR, self.name) } - fn to_annotation( - &self, - artifact_manager: &ArtifactManager, - module_path: &String, - ) -> Result { + fn to_annotation(&self, module_path: &String) -> Result { let contract_qualified_path = self.contract_qualified_path(&module_path); - let artifact = artifact_manager - .get_artifact(&contract_qualified_path) - .ok_or(anyhow::anyhow!("Artifact not found"))?; - let annotation = ContractAnnotation { qualified_path: contract_qualified_path.clone(), - class_hash: artifact.class_hash, tag: naming::get_tag(&self.namespace, &self.name), systems: self.systems.clone(), }; @@ -237,20 +206,11 @@ impl AuxDataToAnnotation for StarkNetContractAuxData module_path.clone() } - fn to_annotation( - &self, - artifact_manager: &ArtifactManager, - module_path: &String, - ) -> Result { + fn to_annotation(&self, module_path: &String) -> Result { let contract_qualified_path = self.contract_qualified_path(&module_path); - let artifact = artifact_manager - .get_artifact(&contract_qualified_path) - .ok_or(anyhow::anyhow!("Artifact not found"))?; - let annotation = StarknetContractAnnotation { qualified_path: contract_qualified_path.clone(), - class_hash: artifact.class_hash, name: self.contract_name.to_string(), }; diff --git a/crates/compiler/src/compiler/annotation.rs b/crates/compiler/src/compiler/annotation.rs index 466bf14..3437629 100644 --- a/crates/compiler/src/compiler/annotation.rs +++ b/crates/compiler/src/compiler/annotation.rs @@ -3,21 +3,40 @@ //! The dojo resource annotations are used to annotate the artifacts //! generated by the compiler with information about the Dojo resources //! found during the compilation process. +//! +//! The purpose of this file is to convey the annotations to the different +//! steps of the compilation decoupling from the aux data type that is very specific +//! to the `attribute_macros` plugin. Aux data don't have access to the qualified path, +//! annotations do include the qualified path. +//! +//! The qualified path in the annotation is the link connecting the artifact +//! to the annotation. use std::io::{Read, Write}; use anyhow::Result; +use cairo_lang_compiler::db::RootDatabase; +use cairo_lang_defs::db::DefsGroup; +use cairo_lang_filesystem::ids::CrateId; +use cairo_lang_starknet::plugin::aux_data::StarkNetContractAuxData; +use dojo_types::naming; use scarb::core::Workspace; use serde::{Deserialize, Serialize}; use serde_with::serde_as; -use starknet::core::serde::unsigned_field_element::UfeHex; -use starknet::core::types::Felt; +use crate::aux_data::{AuxDataToAnnotation, ContractAuxData, EventAuxData, ModelAuxData}; use crate::scarb_extensions::WorkspaceExt; -use crate::{BASE_CONTRACT_TAG, BASE_QUALIFIED_PATH, WORLD_CONTRACT_TAG, WORLD_QUALIFIED_PATH}; +use crate::{ + BASE_CONTRACT_TAG, BASE_QUALIFIED_PATH, CAIRO_PATH_SEPARATOR, RESOURCE_METADATA_QUALIFIED_PATH, + WORLD_CONTRACT_TAG, WORLD_QUALIFIED_PATH, +}; const DOJO_ANNOTATION_FILE_NAME: &str = "annotations"; +pub trait AnnotationInfo { + fn filename(&self) -> String; +} + /// Represents a member of a struct. #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct Member { @@ -36,8 +55,6 @@ pub struct Member { #[cfg_attr(test, derive(PartialEq))] #[serde(tag = "kind", rename = "DojoContract")] pub struct ContractAnnotation { - #[serde_as(as = "UfeHex")] - pub class_hash: Felt, pub qualified_path: String, pub tag: String, pub systems: Vec, @@ -49,8 +66,6 @@ pub struct ContractAnnotation { #[cfg_attr(test, derive(PartialEq))] #[serde(tag = "kind", rename = "DojoModel")] pub struct ModelAnnotation { - #[serde_as(as = "UfeHex")] - pub class_hash: Felt, pub qualified_path: String, pub tag: String, pub members: Vec, @@ -62,8 +77,6 @@ pub struct ModelAnnotation { #[cfg_attr(test, derive(PartialEq))] #[serde(tag = "kind", rename = "DojoEvent")] pub struct EventAnnotation { - #[serde_as(as = "UfeHex")] - pub class_hash: Felt, pub qualified_path: String, pub tag: String, pub members: Vec, @@ -75,8 +88,6 @@ pub struct EventAnnotation { #[cfg_attr(test, derive(PartialEq))] #[serde(tag = "kind", rename = "DojoWorld")] pub struct WorldAnnotation { - #[serde_as(as = "UfeHex")] - pub class_hash: Felt, pub qualified_path: String, pub tag: String, } @@ -84,7 +95,6 @@ pub struct WorldAnnotation { impl Default for WorldAnnotation { fn default() -> Self { Self { - class_hash: Felt::ZERO, qualified_path: WORLD_QUALIFIED_PATH.to_string(), tag: WORLD_CONTRACT_TAG.to_string(), } @@ -97,8 +107,6 @@ impl Default for WorldAnnotation { #[cfg_attr(test, derive(PartialEq))] #[serde(tag = "kind", rename = "DojoBase")] pub struct BaseAnnotation { - #[serde_as(as = "UfeHex")] - pub class_hash: Felt, pub qualified_path: String, pub tag: String, } @@ -106,7 +114,6 @@ pub struct BaseAnnotation { impl Default for BaseAnnotation { fn default() -> Self { Self { - class_hash: Felt::ZERO, qualified_path: BASE_QUALIFIED_PATH.to_string(), tag: BASE_CONTRACT_TAG.to_string(), } @@ -119,12 +126,46 @@ impl Default for BaseAnnotation { #[cfg_attr(test, derive(PartialEq))] #[serde(tag = "kind", rename = "StarknetContract")] pub struct StarknetContractAnnotation { - #[serde_as(as = "UfeHex")] - pub class_hash: Felt, pub qualified_path: String, pub name: String, } +impl AnnotationInfo for ModelAnnotation { + fn filename(&self) -> String { + naming::get_filename_from_tag(&self.tag) + } +} + +impl AnnotationInfo for EventAnnotation { + fn filename(&self) -> String { + naming::get_filename_from_tag(&self.tag) + } +} + +impl AnnotationInfo for ContractAnnotation { + fn filename(&self) -> String { + naming::get_filename_from_tag(&self.tag) + } +} + +impl AnnotationInfo for StarknetContractAnnotation { + fn filename(&self) -> String { + self.qualified_path.replace(CAIRO_PATH_SEPARATOR, "_") + } +} + +impl AnnotationInfo for WorldAnnotation { + fn filename(&self) -> String { + WORLD_CONTRACT_TAG.to_string() + } +} + +impl AnnotationInfo for BaseAnnotation { + fn filename(&self) -> String { + BASE_CONTRACT_TAG.to_string() + } +} + /// An abstract representation of the annotations of dojo resources. #[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct DojoAnnotation { @@ -166,6 +207,80 @@ impl DojoAnnotation { || self.base.qualified_path == qualified_path } + /// Sets the dojo annotations form the aux data extracted from the database. + pub fn from_aux_data(db: &RootDatabase, crate_ids: &[CrateId]) -> Result { + let mut annotations = DojoAnnotation::default(); + + for crate_id in crate_ids { + for module_id in db.crate_modules(*crate_id).as_ref() { + let file_infos = db + .module_generated_file_infos(*module_id) + .unwrap_or(std::sync::Arc::new([])); + + // Skip(1) to avoid internal aux data of Starknet aux data. + for aux_data in file_infos + .iter() + .skip(1) + .filter_map(|info| info.as_ref().map(|i| &i.aux_data)) + .filter_map(|aux_data| aux_data.as_ref().map(|aux_data| aux_data.0.as_any())) + { + let module_path = module_id.full_path(db); + + if let Some(aux_data) = aux_data.downcast_ref::() { + let annotation = aux_data.to_annotation(&module_path)?; + annotations.contracts.push(annotation); + continue; + } + + if let Some(aux_data) = aux_data.downcast_ref::() { + let annotation = aux_data.to_annotation(&module_path)?; + annotations.models.push(annotation); + continue; + } + + if let Some(aux_data) = aux_data.downcast_ref::() { + let annotation = aux_data.to_annotation(&module_path)?; + annotations.events.push(annotation); + continue; + } + + if let Some(aux_data) = aux_data.downcast_ref::() { + let annotation = aux_data.to_annotation(&module_path)?; + + if annotation.qualified_path == WORLD_QUALIFIED_PATH { + annotations.world = WorldAnnotation { + qualified_path: WORLD_QUALIFIED_PATH.to_string(), + tag: WORLD_CONTRACT_TAG.to_string(), + }; + } else if annotation.qualified_path == BASE_QUALIFIED_PATH { + annotations.base = BaseAnnotation { + qualified_path: BASE_QUALIFIED_PATH.to_string(), + tag: BASE_CONTRACT_TAG.to_string(), + }; + } else if annotation.qualified_path == RESOURCE_METADATA_QUALIFIED_PATH { + // Skip this annotation as not used in the migration process. + continue; + } else { + annotations.sn_contracts.push(annotation); + } + } + } + } + } + + // Since dojo resources are just starknet contracts under the hood, + // we remove them from the sn_contracts list. We can't filter them earlier + // as we need to wait all the annotations to be extracted before filtering. + let mut filtered_sn_contracts = annotations.sn_contracts.clone(); + + filtered_sn_contracts + .retain(|sn_contract| !annotations.is_dojo_resource(&sn_contract.qualified_path)); + + annotations.sn_contracts = filtered_sn_contracts; + + Ok(annotations) + } + /// Reads the annotations from the target directory of the provided workspace, /// for the current profile. /// diff --git a/crates/compiler/src/compiler/artifact_manager.rs b/crates/compiler/src/compiler/artifact_manager.rs index 5e526c8..f7ab59b 100644 --- a/crates/compiler/src/compiler/artifact_manager.rs +++ b/crates/compiler/src/compiler/artifact_manager.rs @@ -3,11 +3,12 @@ //! The primary purpose of this module is to manage the compiled artifacts //! and abstract the writing of the artifacts to the filesystem. //! -//! The artifact manager doesn't have any context of the nature of the contracts -//! that are being compiled (dojo contract, model contract, starknet contract, ...). +//! The artifact manager can be completed with the dojo annotations extracted +//! from the aux data of the generated files, which retain the information about +//! the nature of the contracts being compiled. //! -//! The plugin aux data are the one that will keep this information mapped to the -//! qualified path of the compiled contracts. +//! When using annotations, the qualified path is the link connecting the artifact +//! to the annotation. use std::collections::HashMap; use std::ops::DerefMut; @@ -15,24 +16,18 @@ use std::rc::Rc; use anyhow::{Context, Result}; use cairo_lang_compiler::db::RootDatabase; -use cairo_lang_defs::db::DefsGroup; use cairo_lang_filesystem::ids::CrateId; -use cairo_lang_starknet::plugin::aux_data::StarkNetContractAuxData; use cairo_lang_starknet_classes::contract_class::ContractClass; -use dojo_types::naming; use scarb::core::Workspace; use scarb::flock::Filesystem; use starknet::core::types::Felt; use tracing::trace; -use crate::aux_data::{AuxDataToAnnotation, ContractAuxData, EventAuxData, ModelAuxData}; +use crate::compiler::compiler::compute_class_hash_of_contract_class; use crate::scarb_extensions::WorkspaceExt; -use crate::{ - BASE_CONTRACT_TAG, BASE_QUALIFIED_PATH, CAIRO_PATH_SEPARATOR, CONTRACTS_DIR, EVENTS_DIR, - MODELS_DIR, RESOURCE_METADATA_QUALIFIED_PATH, WORLD_CONTRACT_TAG, WORLD_QUALIFIED_PATH, -}; +use crate::{CONTRACTS_DIR, EVENTS_DIR, MODELS_DIR}; -use super::annotation::{BaseAnnotation, DojoAnnotation, WorldAnnotation}; +use super::annotation::{AnnotationInfo, DojoAnnotation}; use super::scarb_internal::debug::SierraToCairoDebugInfo; #[derive(Debug, Clone)] @@ -53,8 +48,8 @@ pub struct ArtifactManager<'w> { workspace: &'w Workspace<'w>, /// The compiled artifacts. compiled_artifacts: CompiledArtifactByPath, - /// Dojo annotations. - dojo_annotations: DojoAnnotation, + /// Dojo annotation. + dojo_annotation: DojoAnnotation, } impl<'w> ArtifactManager<'w> { @@ -63,90 +58,24 @@ impl<'w> ArtifactManager<'w> { Self { workspace, compiled_artifacts: HashMap::new(), - dojo_annotations: DojoAnnotation::default(), + dojo_annotation: DojoAnnotation::default(), } } /// Sets the dojo annotations form the aux data extracted from the database. - pub fn set_dojo_annotations(&mut self, db: &RootDatabase, crate_ids: &[CrateId]) -> Result<()> { + pub fn set_dojo_annotation(&mut self, db: &RootDatabase, crate_ids: &[CrateId]) -> Result<()> { // Ensures that the dojo annotations are empty to not keep any stale data. - self.dojo_annotations = DojoAnnotation::default(); - - for crate_id in crate_ids { - for module_id in db.crate_modules(*crate_id).as_ref() { - let file_infos = db - .module_generated_file_infos(*module_id) - .unwrap_or(std::sync::Arc::new([])); - - // Skip(1) to avoid internal aux data of Starknet aux data. - for aux_data in file_infos - .iter() - .skip(1) - .filter_map(|info| info.as_ref().map(|i| &i.aux_data)) - .filter_map(|aux_data| aux_data.as_ref().map(|aux_data| aux_data.0.as_any())) - { - let module_path = module_id.full_path(db); - - if let Some(aux_data) = aux_data.downcast_ref::() { - let annotation = aux_data.to_annotation(self, &module_path)?; - self.dojo_annotations.contracts.push(annotation); - continue; - } - - if let Some(aux_data) = aux_data.downcast_ref::() { - let annotation = aux_data.to_annotation(self, &module_path)?; - self.dojo_annotations.models.push(annotation); - continue; - } - - if let Some(aux_data) = aux_data.downcast_ref::() { - let annotation = aux_data.to_annotation(self, &module_path)?; - self.dojo_annotations.events.push(annotation); - continue; - } - - if let Some(aux_data) = aux_data.downcast_ref::() { - let annotation = aux_data.to_annotation(self, &module_path)?; - - if annotation.qualified_path == WORLD_QUALIFIED_PATH { - self.dojo_annotations.world = WorldAnnotation { - class_hash: annotation.class_hash, - qualified_path: WORLD_QUALIFIED_PATH.to_string(), - tag: WORLD_CONTRACT_TAG.to_string(), - }; - } else if annotation.qualified_path == BASE_QUALIFIED_PATH { - self.dojo_annotations.base = BaseAnnotation { - class_hash: annotation.class_hash, - qualified_path: BASE_QUALIFIED_PATH.to_string(), - tag: BASE_CONTRACT_TAG.to_string(), - }; - } else if annotation.qualified_path == RESOURCE_METADATA_QUALIFIED_PATH { - // Skip this annotation as not used in the migration process. - continue; - } else { - self.dojo_annotations.sn_contracts.push(annotation); - } - } - } - } - } - - // Since dojo resources are just starknet contracts under the hood, - // we remove them from the sn_contracts list. We can't filter them earlier - // as we need to wait all the annotations to be extracted before filtering. - let mut filtered_sn_contracts = self.dojo_annotations.sn_contracts.clone(); - - filtered_sn_contracts.retain(|sn_contract| { - !self - .dojo_annotations - .is_dojo_resource(&sn_contract.qualified_path) - }); - - self.dojo_annotations.sn_contracts = filtered_sn_contracts; + self.dojo_annotation = DojoAnnotation::default(); + self.dojo_annotation = DojoAnnotation::from_aux_data(db, crate_ids)?; Ok(()) } + /// Returns the dojo annotation. + pub fn dojo_annotation(&self) -> &DojoAnnotation { + &self.dojo_annotation + } + /// Returns the workspace of the current compilation. pub fn workspace(&self) -> &Workspace { self.workspace @@ -184,43 +113,117 @@ impl<'w> ArtifactManager<'w> { /// Writes all the dojo annotations and artifacts to the filesystem. pub fn write(&self) -> Result<()> { - self.dojo_annotations.write(self.workspace)?; + self.dojo_annotation.write(self.workspace)?; let target_dir = self.workspace.target_dir_profile(); - self.write_sierra_class(WORLD_QUALIFIED_PATH, &target_dir, WORLD_CONTRACT_TAG)?; - self.write_sierra_class(BASE_QUALIFIED_PATH, &target_dir, BASE_CONTRACT_TAG)?; + self.write_sierra_class( + &self.dojo_annotation.world.qualified_path, + &target_dir, + &self.dojo_annotation.world.filename(), + )?; + self.write_sierra_class( + &self.dojo_annotation.base.qualified_path, + &target_dir, + &self.dojo_annotation.base.filename(), + )?; - for contract in &self.dojo_annotations.contracts { - let filename = naming::get_filename_from_tag(&contract.tag); + for contract in &self.dojo_annotation.contracts { + let filename = contract.filename(); let target_dir = target_dir.child(CONTRACTS_DIR); self.write_sierra_class(&contract.qualified_path, &target_dir, &filename)?; } - for model in &self.dojo_annotations.models { - let filename = naming::get_filename_from_tag(&model.tag); + for model in &self.dojo_annotation.models { + let filename = model.filename(); let target_dir = target_dir.child(MODELS_DIR); self.write_sierra_class(&model.qualified_path, &target_dir, &filename)?; } - for event in &self.dojo_annotations.events { - let filename = naming::get_filename_from_tag(&event.tag); + for event in &self.dojo_annotation.events { + let filename = event.filename(); let target_dir = target_dir.child(EVENTS_DIR); self.write_sierra_class(&event.qualified_path, &target_dir, &filename)?; } - for sn_contract in &self.dojo_annotations.sn_contracts { + for sn_contract in &self.dojo_annotation.sn_contracts { // TODO: we might want to use namespace for starknet contracts too. - let file_name = sn_contract - .qualified_path - .replace(CAIRO_PATH_SEPARATOR, "_"); - + let file_name = sn_contract.filename(); self.write_sierra_class(&sn_contract.qualified_path, &target_dir, &file_name)?; } Ok(()) } + /// Reads the artifacts from the filesystem by reading the dojo annotations. + pub fn read(&mut self, workspace: &'w Workspace) -> Result<()> { + self.dojo_annotation = DojoAnnotation::read(workspace)?; + + self.add_artifact( + self.dojo_annotation.world.qualified_path.to_string(), + self.read_compiled_artifact( + &self.dojo_annotation.world.qualified_path, + &workspace.target_dir_profile(), + &self.dojo_annotation.world.filename(), + )?, + ); + + self.add_artifact( + self.dojo_annotation.base.qualified_path.to_string(), + self.read_compiled_artifact( + &self.dojo_annotation.base.qualified_path, + &workspace.target_dir_profile(), + &self.dojo_annotation.base.filename(), + )?, + ); + + for contract in self.dojo_annotation.contracts.clone() { + let target_dir = workspace.target_dir_profile().child(CONTRACTS_DIR); + + self.add_artifact( + contract.qualified_path.to_string(), + self.read_compiled_artifact( + &contract.qualified_path, + &target_dir, + &contract.filename(), + )?, + ); + } + + for model in self.dojo_annotation.models.clone() { + let target_dir = workspace.target_dir_profile().child(MODELS_DIR); + + self.add_artifact( + model.qualified_path.to_string(), + self.read_compiled_artifact(&model.qualified_path, &target_dir, &model.filename())?, + ); + } + + for event in self.dojo_annotation.events.clone() { + let target_dir = workspace.target_dir_profile().child(EVENTS_DIR); + + self.add_artifact( + event.qualified_path.to_string(), + self.read_compiled_artifact(&event.qualified_path, &target_dir, &event.filename())?, + ); + } + + for sn_contract in self.dojo_annotation.sn_contracts.clone() { + let target_dir = workspace.target_dir_profile(); + + self.add_artifact( + sn_contract.qualified_path.to_string(), + self.read_compiled_artifact( + &sn_contract.qualified_path, + &target_dir, + &sn_contract.filename(), + )?, + ); + } + + Ok(()) + } + /// Saves a Sierra contract class to a JSON file. /// If debug info is available, it will also be saved to a separate file. /// @@ -229,7 +232,7 @@ impl<'w> ArtifactManager<'w> { /// * `qualified_path` - The cairo module qualified path. /// * `target_dir` - The target directory to save the artifact to. /// * `file_name` - The name of the file to save the artifact to, without extension. - pub fn write_sierra_class( + fn write_sierra_class( &self, qualified_path: &str, target_dir: &Filesystem, @@ -265,34 +268,60 @@ impl<'w> ArtifactManager<'w> { Ok(()) } - /// Saves the ABI of a compiled artifact to a JSON file. + /// Reads a Sierra contract class from a JSON file. + /// If debug info is available, it will also be read from a separate file. /// /// # Arguments /// /// * `qualified_path` - The cairo module qualified path. /// * `target_dir` - The target directory to save the artifact to. /// * `file_name` - The name of the file to save the artifact to, without extension. - pub fn write_abi( + fn read_compiled_artifact( &self, qualified_path: &str, target_dir: &Filesystem, file_name: &str, - ) -> anyhow::Result<()> { - trace!(target_dir = ?target_dir, qualified_path, file_name, "Saving abi file."); - - let artifact = self - .get_artifact(qualified_path) - .context(format!("Artifact file for `{}` not found.", qualified_path))?; + ) -> anyhow::Result { + trace!(target_dir = ?target_dir, qualified_path, file_name, "Reading compiled artifact."); - let mut file = target_dir.open_rw( + let mut file = target_dir.open_ro( format!("{file_name}.json"), - &format!("abi file for `{}`", qualified_path), + &format!("sierra class file for `{}`", qualified_path), self.workspace.config(), )?; - serde_json::to_writer_pretty(file.deref_mut(), &artifact.contract_class.abi) - .with_context(|| format!("failed to serialize abi: {qualified_path}"))?; + // Read the class, that must be present, and recompute the class hash. + let contract_class: ContractClass = serde_json::from_reader(file.deref_mut())?; - Ok(()) + let class_hash = + compute_class_hash_of_contract_class(&contract_class).with_context(|| { + format!( + "problem computing class hash for contract `{}`", + qualified_path + ) + })?; + + // Debug info may or may not be present. + let debug_info = if target_dir.child(format!("{file_name}.debug.json")).exists() { + trace!(target_dir = ?target_dir, qualified_path, file_name, "Reading sierra debug info."); + + let mut file = target_dir.open_ro( + format!("{file_name}.debug.json"), + &format!("sierra debug info for `{}`", qualified_path), + self.workspace.config(), + )?; + + Some(Rc::new(serde_json::from_reader(file.deref_mut())?)) + } else { + None + }; + + let compiled_artifact = CompiledArtifact { + class_hash, + contract_class: Rc::new(contract_class), + debug_info, + }; + + Ok(compiled_artifact) } } diff --git a/crates/compiler/src/compiler/compiler.rs b/crates/compiler/src/compiler/compiler.rs index dca0d79..9978776 100644 --- a/crates/compiler/src/compiler/compiler.rs +++ b/crates/compiler/src/compiler/compiler.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use std::fs; use std::rc::Rc; @@ -13,7 +12,6 @@ use cairo_lang_starknet::contract::{find_contracts, ContractDeclaration}; use cairo_lang_starknet_classes::allowed_libfuncs::{AllowedLibfuncsError, ListSelector}; use cairo_lang_starknet_classes::contract_class::ContractClass; use cairo_lang_utils::UpcastMut; -use dojo_types::naming; use itertools::{izip, Itertools}; use scarb::compiler::helpers::build_compiler_config; use scarb::compiler::{CairoCompilationUnit, CompilationUnitAttributes, Compiler}; @@ -28,10 +26,7 @@ use starknet::core::types::Felt; use tracing::{trace, trace_span}; use crate::scarb_extensions::{ProfileSpec, WorkspaceExt}; -use crate::{ - BASE_CONTRACT_TAG, BASE_QUALIFIED_PATH, CAIRO_PATH_SEPARATOR, CONTRACTS_DIR, EVENTS_DIR, - MODELS_DIR, RESOURCE_METADATA_QUALIFIED_PATH, WORLD_CONTRACT_TAG, WORLD_QUALIFIED_PATH, -}; +use crate::{BASE_QUALIFIED_PATH, WORLD_QUALIFIED_PATH}; use super::artifact_manager::{ArtifactManager, CompiledArtifact}; use super::contract_selector::ContractSelector; @@ -180,7 +175,7 @@ impl Compiler for DojoCompiler { let mut artifact_manager = compile_contracts(db, &contracts, compiler_config, &ws, self.output_debug_info)?; - artifact_manager.set_dojo_annotations(db, &main_crate_ids)?; + artifact_manager.set_dojo_annotation(db, &main_crate_ids)?; artifact_manager.write()?; Ok(()) @@ -341,7 +336,7 @@ fn compile_contracts<'w>( } /// Computes the class hash of a contract class. -fn compute_class_hash_of_contract_class(class: &ContractClass) -> Result { +pub fn compute_class_hash_of_contract_class(class: &ContractClass) -> Result { let class_str = serde_json::to_string(&class)?; let sierra_class = serde_json::from_str::(&class_str) .map_err(|e| anyhow!("error parsing Sierra class: {e}"))?; diff --git a/crates/compiler/src/compiler/scarb_internal/debug.rs b/crates/compiler/src/compiler/scarb_internal/debug.rs index 0a8805a..3b13833 100644 --- a/crates/compiler/src/compiler/scarb_internal/debug.rs +++ b/crates/compiler/src/compiler/scarb_internal/debug.rs @@ -15,7 +15,7 @@ use cairo_lang_sierra_generator::program_generator::{ use cairo_lang_starknet::compile::{extract_semantic_entrypoints, SemanticEntryPoints}; use cairo_lang_starknet::contract::ContractDeclaration; use itertools::{chain, Itertools}; -use serde::Serialize; +use serde::{Deserialize, Serialize}; pub fn compile_prepared_db_to_debug_info( db: &RootDatabase, @@ -60,13 +60,13 @@ fn compile_contract_with_prepared_and_checked_db_to_debug_info( Ok(debug_info) } -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct SierraToCairoDebugInfo { pub sierra_statements_to_cairo_info: HashMap, } /// Human readable position inside a file, in lines and characters. -#[derive(Debug, Serialize, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct TextPosition { /// Line index, 0 based. pub line: usize, @@ -74,14 +74,14 @@ pub struct TextPosition { pub col: usize, } -#[derive(Debug, Serialize, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Location { pub start: TextPosition, pub end: TextPosition, pub file_path: String, } -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct SierraStatementToCairoDebugInfo { pub cairo_locations: Vec, } diff --git a/crates/compiler/src/plugin/attribute_macros/contract.rs b/crates/compiler/src/plugin/attribute_macros/contract.rs index 01bcb92..28ffc3e 100644 --- a/crates/compiler/src/plugin/attribute_macros/contract.rs +++ b/crates/compiler/src/plugin/attribute_macros/contract.rs @@ -189,8 +189,8 @@ impl DojoContract { name: name.clone(), content: code, aux_data: Some(DynGeneratedFileAuxData::new(ContractAuxData { - name, - namespace: contract_namespace.clone(), + name: name.to_string(), + namespace: contract_namespace.to_string(), systems: contract.systems.clone(), })), code_mappings, diff --git a/crates/compiler/src/scarb_extensions.rs b/crates/compiler/src/scarb_extensions.rs index d3e99a5..2ee03b7 100644 --- a/crates/compiler/src/scarb_extensions.rs +++ b/crates/compiler/src/scarb_extensions.rs @@ -2,8 +2,6 @@ use anyhow::Result; use camino::Utf8Path; use scarb::{core::Workspace, flock::Filesystem}; -use crate::{MANIFESTS_BASE_DIR, MANIFESTS_DIR}; - /// Handy enum for selecting the current profile or all profiles. #[derive(Debug)] pub enum ProfileSpec { From e313f5b40c568b866b9dd6101d52fe9cc547b941 Mon Sep 17 00:00:00 2001 From: glihm Date: Tue, 8 Oct 2024 19:47:37 -0600 Subject: [PATCH 06/11] fix: remove unused file --- bins/demo-compiler/src/utils.rs | 136 -------------------------------- 1 file changed, 136 deletions(-) delete mode 100644 bins/demo-compiler/src/utils.rs diff --git a/bins/demo-compiler/src/utils.rs b/bins/demo-compiler/src/utils.rs deleted file mode 100644 index 662076e..0000000 --- a/bins/demo-compiler/src/utils.rs +++ /dev/null @@ -1,136 +0,0 @@ -use std::str::FromStr; - -use anyhow::{Error, Result}; -use camino::Utf8PathBuf; -use dojo_world::config::Environment; -use dojo_world::contracts::world::WorldContract; -use dojo_world::contracts::WorldContractReader; -use dojo_world::metadata::dojo_metadata_from_workspace; -use scarb::core::{Config, TomlManifest}; -use semver::Version; -use starknet::providers::jsonrpc::HttpTransport; -use starknet::providers::JsonRpcClient; - -use crate::commands::options::account::{AccountOptions, SozoAccount, WorldAddressOrName}; -use crate::commands::options::starknet::StarknetOptions; -use crate::commands::options::world::WorldOptions; - -/// Load metadata from the Scarb configuration. -/// -/// # Arguments -/// -/// * `config` - Scarb project configuration. -/// -/// # Returns -/// -/// A [`Environment`] on success. -pub fn load_metadata_from_config(config: &Config) -> Result, Error> { - let env_metadata = if config.manifest_path().exists() { - let ws = scarb::ops::read_workspace(config.manifest_path(), config)?; - let dojo_metadata = dojo_metadata_from_workspace(&ws)?; - - dojo_metadata.env().cloned() - } else { - None - }; - - Ok(env_metadata) -} - -/// Build a world contract from the provided environment. -/// -/// # Arguments -/// -/// * `world` - The world options such as the world address, -/// * `account` - The account options, -/// * `starknet` - The Starknet options such as the RPC url, -/// * `env_metadata` - Optional environment coming from Scarb configuration. -/// -/// # Returns -/// -/// A [`WorldContract`] on success. -pub async fn world_from_env_metadata( - world: WorldOptions, - account: AccountOptions, - starknet: &StarknetOptions, - env_metadata: &Option, - config: &Config, -) -> Result>>, Error> { - let env_metadata = env_metadata.as_ref(); - - let world_address = world.address(env_metadata)?; - let provider = starknet.provider(env_metadata)?; - let account = account - .account( - provider, - WorldAddressOrName::Address(world_address), - starknet, - env_metadata, - config, - ) - .await?; - - Ok(WorldContract::new(world_address, account)) -} - -/// Build a world contract reader from the provided environment. -/// -/// # Arguments -/// -/// * `world` - The world options such as the world address, -/// * `starknet` - The Starknet options such as the RPC url, -/// * `env_metadata` - Optional environment coming from Scarb configuration. -/// -/// # Returns -/// -/// A [`WorldContractReader`] on success. -pub async fn world_reader_from_env_metadata( - world: WorldOptions, - starknet: StarknetOptions, - env_metadata: &Option, -) -> Result>, Error> { - let world_address = world.address(env_metadata.as_ref())?; - let provider = starknet.provider(env_metadata.as_ref())?; - - Ok(WorldContractReader::new(world_address, provider)) -} - -pub fn verify_cairo_version_compatibility(manifest_path: &Utf8PathBuf) -> Result<()> { - let scarb_cairo_version = scarb::version::get().cairo; - // When manifest file doesn't exists ignore it. Would be the case during `sozo init` - let Ok(manifest) = TomlManifest::read_from_path(manifest_path) else { return Ok(()) }; - - // For any kind of error, like package not specified, cairo version not specified return - // without an error - let Some(package) = manifest.package else { return Ok(()) }; - - let Some(cairo_version) = package.cairo_version else { return Ok(()) }; - - // only when cairo version is found in manifest file confirm that it matches - let version_req = cairo_version.as_defined().unwrap(); - let version = Version::from_str(scarb_cairo_version.version).unwrap(); - if !version_req.matches(&version) { - anyhow::bail!( - "Specified cairo version not supported by dojo. Please verify and update dojo." - ); - }; - - Ok(()) -} - -pub fn generate_version() -> String { - const DOJO_VERSION: &str = env!("CARGO_PKG_VERSION"); - let scarb_version = scarb::version::get().version; - let scarb_sierra_version = scarb::version::get().sierra.version; - let scarb_cairo_version = scarb::version::get().cairo.version; - - let version_string = format!( - "{}\nscarb: {}\ncairo: {}\nsierra: {}", - DOJO_VERSION, scarb_version, scarb_cairo_version, scarb_sierra_version, - ); - version_string -} - -pub fn is_address(tag_or_address: &str) -> bool { - tag_or_address.starts_with("0x") -} From 4a97d068f8888045e0dff7dc3160a14c19c8a3ed Mon Sep 17 00:00:00 2001 From: glihm Date: Tue, 8 Oct 2024 19:52:09 -0600 Subject: [PATCH 07/11] fix: remove unused file --- crates/compiler/src/contract_store.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 crates/compiler/src/contract_store.rs diff --git a/crates/compiler/src/contract_store.rs b/crates/compiler/src/contract_store.rs deleted file mode 100644 index e69de29..0000000 From d31525c1fa2571e8b32cfe01a8eea36f900c1699 Mon Sep 17 00:00:00 2001 From: glihm Date: Tue, 8 Oct 2024 19:57:16 -0600 Subject: [PATCH 08/11] fix: fix tests for events --- .../src/plugin/plugin_test_data/event | 174 ------------------ 1 file changed, 174 deletions(-) diff --git a/crates/compiler/src/plugin/plugin_test_data/event b/crates/compiler/src/plugin/plugin_test_data/event index 2b08abd..c99b22d 100644 --- a/crates/compiler/src/plugin/plugin_test_data/event +++ b/crates/compiler/src/plugin/plugin_test_data/event @@ -184,16 +184,6 @@ pub impl MessageEventImpl of dojo::event::Event { dojo::meta::introspect::Introspect::::layout() } - #[inline(always)] - fn packed_size() -> Option { - dojo::meta::layout::compute_packed_size(Self::layout()) - } - - #[inline(always)] - fn unpacked_size() -> Option { - dojo::meta::introspect::Introspect::::size() - } - #[inline(always)] fn schema(self: @Message) -> dojo::meta::introspect::Ty { dojo::meta::introspect::Introspect::::ty() @@ -257,14 +247,6 @@ pub mod message { 1452123528942907587532668415362544424816022573043154497385993678618948064048 } - fn unpacked_size(self: @ContractState) -> Option { - dojo::meta::introspect::Introspect::::size() - } - - fn packed_size(self: @ContractState) -> Option { - dojo::event::Event::::packed_size() - } - fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::event::Event::::layout() } @@ -465,44 +447,6 @@ fn __wrapper__DojoEventImpl__namespace_hash(mut data: Span::) -> Span:: core::array::ArrayTrait::span(@arr) } -#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] -fn __wrapper__DojoEventImpl__unpacked_size(mut data: Span::) -> Span:: { - core::internal::require_implicit::(); - core::internal::revoke_ap_tracking(); - core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); - - assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); - core::option::OptionTraitImpl::expect( - core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', - ); - let mut contract_state = unsafe_new_contract_state(); - let res = DojoEventImpl::unpacked_size(@contract_state, ); - let mut arr = ArrayTrait::new(); - // References. - // Result. - core::serde::Serde::>::serialize(@res, ref arr); - core::array::ArrayTrait::span(@arr) -} - -#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] -fn __wrapper__DojoEventImpl__packed_size(mut data: Span::) -> Span:: { - core::internal::require_implicit::(); - core::internal::revoke_ap_tracking(); - core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); - - assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); - core::option::OptionTraitImpl::expect( - core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', - ); - let mut contract_state = unsafe_new_contract_state(); - let res = DojoEventImpl::packed_size(@contract_state, ); - let mut arr = ArrayTrait::new(); - // References. - // Result. - core::serde::Serde::>::serialize(@res, ref arr); - core::array::ArrayTrait::span(@arr) -} - #[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] fn __wrapper__DojoEventImpl__layout(mut data: Span::) -> Span:: { core::internal::require_implicit::(); @@ -550,8 +494,6 @@ pub mod __external { pub use super::__wrapper__DojoEventImpl__selector as selector; pub use super::__wrapper__DojoEventImpl__name_hash as name_hash; pub use super::__wrapper__DojoEventImpl__namespace_hash as namespace_hash; - pub use super::__wrapper__DojoEventImpl__unpacked_size as unpacked_size; - pub use super::__wrapper__DojoEventImpl__packed_size as packed_size; pub use super::__wrapper__DojoEventImpl__layout as layout; pub use super::__wrapper__DojoEventImpl__schema as schema; } @@ -696,16 +638,6 @@ pub impl MyEventWithNamespaceEventImpl of dojo::event::Event::layout() } - #[inline(always)] - fn packed_size() -> Option { - dojo::meta::layout::compute_packed_size(Self::layout()) - } - - #[inline(always)] - fn unpacked_size() -> Option { - dojo::meta::introspect::Introspect::::size() - } - #[inline(always)] fn schema(self: @MyEventWithNamespace) -> dojo::meta::introspect::Ty { dojo::meta::introspect::Introspect::::ty() @@ -767,14 +699,6 @@ pub mod my_event_with_namespace { 1452123528942907587532668415362544424816022573043154497385993678618948064048 } - fn unpacked_size(self: @ContractState) -> Option { - dojo::meta::introspect::Introspect::::size() - } - - fn packed_size(self: @ContractState) -> Option { - dojo::event::Event::::packed_size() - } - fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::event::Event::::layout() } @@ -975,44 +899,6 @@ fn __wrapper__DojoEventImpl__namespace_hash(mut data: Span::) -> Span:: core::array::ArrayTrait::span(@arr) } -#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] -fn __wrapper__DojoEventImpl__unpacked_size(mut data: Span::) -> Span:: { - core::internal::require_implicit::(); - core::internal::revoke_ap_tracking(); - core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); - - assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); - core::option::OptionTraitImpl::expect( - core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', - ); - let mut contract_state = unsafe_new_contract_state(); - let res = DojoEventImpl::unpacked_size(@contract_state, ); - let mut arr = ArrayTrait::new(); - // References. - // Result. - core::serde::Serde::>::serialize(@res, ref arr); - core::array::ArrayTrait::span(@arr) -} - -#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] -fn __wrapper__DojoEventImpl__packed_size(mut data: Span::) -> Span:: { - core::internal::require_implicit::(); - core::internal::revoke_ap_tracking(); - core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); - - assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); - core::option::OptionTraitImpl::expect( - core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', - ); - let mut contract_state = unsafe_new_contract_state(); - let res = DojoEventImpl::packed_size(@contract_state, ); - let mut arr = ArrayTrait::new(); - // References. - // Result. - core::serde::Serde::>::serialize(@res, ref arr); - core::array::ArrayTrait::span(@arr) -} - #[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] fn __wrapper__DojoEventImpl__layout(mut data: Span::) -> Span:: { core::internal::require_implicit::(); @@ -1060,8 +946,6 @@ pub mod __external { pub use super::__wrapper__DojoEventImpl__selector as selector; pub use super::__wrapper__DojoEventImpl__name_hash as name_hash; pub use super::__wrapper__DojoEventImpl__namespace_hash as namespace_hash; - pub use super::__wrapper__DojoEventImpl__unpacked_size as unpacked_size; - pub use super::__wrapper__DojoEventImpl__packed_size as packed_size; pub use super::__wrapper__DojoEventImpl__layout as layout; pub use super::__wrapper__DojoEventImpl__schema as schema; } @@ -1206,16 +1090,6 @@ pub impl MyEventNoHistoricalEventImpl of dojo::event::Event dojo::meta::introspect::Introspect::::layout() } - #[inline(always)] - fn packed_size() -> Option { - dojo::meta::layout::compute_packed_size(Self::layout()) - } - - #[inline(always)] - fn unpacked_size() -> Option { - dojo::meta::introspect::Introspect::::size() - } - #[inline(always)] fn schema(self: @MyEventNoHistorical) -> dojo::meta::introspect::Ty { dojo::meta::introspect::Introspect::::ty() @@ -1277,14 +1151,6 @@ pub mod my_event_no_historical { 1452123528942907587532668415362544424816022573043154497385993678618948064048 } - fn unpacked_size(self: @ContractState) -> Option { - dojo::meta::introspect::Introspect::::size() - } - - fn packed_size(self: @ContractState) -> Option { - dojo::event::Event::::packed_size() - } - fn layout(self: @ContractState) -> dojo::meta::Layout { dojo::event::Event::::layout() } @@ -1485,44 +1351,6 @@ fn __wrapper__DojoEventImpl__namespace_hash(mut data: Span::) -> Span:: core::array::ArrayTrait::span(@arr) } -#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] -fn __wrapper__DojoEventImpl__unpacked_size(mut data: Span::) -> Span:: { - core::internal::require_implicit::(); - core::internal::revoke_ap_tracking(); - core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); - - assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); - core::option::OptionTraitImpl::expect( - core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', - ); - let mut contract_state = unsafe_new_contract_state(); - let res = DojoEventImpl::unpacked_size(@contract_state, ); - let mut arr = ArrayTrait::new(); - // References. - // Result. - core::serde::Serde::>::serialize(@res, ref arr); - core::array::ArrayTrait::span(@arr) -} - -#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] -fn __wrapper__DojoEventImpl__packed_size(mut data: Span::) -> Span:: { - core::internal::require_implicit::(); - core::internal::revoke_ap_tracking(); - core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas'); - - assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments'); - core::option::OptionTraitImpl::expect( - core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas', - ); - let mut contract_state = unsafe_new_contract_state(); - let res = DojoEventImpl::packed_size(@contract_state, ); - let mut arr = ArrayTrait::new(); - // References. - // Result. - core::serde::Serde::>::serialize(@res, ref arr); - core::array::ArrayTrait::span(@arr) -} - #[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)] fn __wrapper__DojoEventImpl__layout(mut data: Span::) -> Span:: { core::internal::require_implicit::(); @@ -1570,8 +1398,6 @@ pub mod __external { pub use super::__wrapper__DojoEventImpl__selector as selector; pub use super::__wrapper__DojoEventImpl__name_hash as name_hash; pub use super::__wrapper__DojoEventImpl__namespace_hash as namespace_hash; - pub use super::__wrapper__DojoEventImpl__unpacked_size as unpacked_size; - pub use super::__wrapper__DojoEventImpl__packed_size as packed_size; pub use super::__wrapper__DojoEventImpl__layout as layout; pub use super::__wrapper__DojoEventImpl__schema as schema; } From 957c5c06fb2925e854fdb8329fd568d1c7dc66a9 Mon Sep 17 00:00:00 2001 From: glihm Date: Tue, 8 Oct 2024 21:12:53 -0600 Subject: [PATCH 09/11] fix: add permission on event and adjust tests --- .../src/plugin/attribute_macros/patches.rs | 23 +++++++++ .../src/plugin/plugin_test_data/event | 30 ++++++++++++ crates/contracts/src/event/event.cairo | 5 ++ crates/contracts/src/lib.cairo | 3 ++ crates/contracts/src/tests/helpers.cairo | 8 ++++ crates/contracts/src/tests/world/world.cairo | 17 +++++-- .../contracts/src/world/world_contract.cairo | 47 ++++++++++++++++--- examples/dojo_simple/src/lib.cairo | 4 +- scripts/cairo_fmt.sh | 6 ++- scripts/rust_fmt.sh | 6 ++- 10 files changed, 133 insertions(+), 16 deletions(-) diff --git a/crates/compiler/src/plugin/attribute_macros/patches.rs b/crates/compiler/src/plugin/attribute_macros/patches.rs index 6012d4a..985bfc0 100644 --- a/crates/compiler/src/plugin/attribute_macros/patches.rs +++ b/crates/compiler/src/plugin/attribute_macros/patches.rs @@ -524,6 +524,13 @@ pub mod $contract_name$ { "; pub const EVENT_PATCH: &str = " +#[generate_trait] +pub impl $type_name$EmitterImpl of $type_name$Emitter { + fn emit(self: @$type_name$, world: dojo::world::IWorldDispatcher) { + dojo::event::Event::<$type_name$>::emit(self, world); + } +} + pub impl $type_name$EventImpl of dojo::event::Event<$type_name$> { fn emit(self: @$type_name$, world: dojo::world::IWorldDispatcher) { @@ -606,6 +613,22 @@ pub impl $type_name$EventImpl of dojo::event::Event<$type_name$> { } } +#[cfg(target: \"test\")] +pub impl $type_name$EventImplTest of dojo::event::EventTest<$type_name$> { + fn emit_test(self: @$type_name$, world: dojo::world::IWorldDispatcher) { + let world_test = dojo::world::IWorldTestDispatcher { contract_address: \ + world.contract_address }; + + dojo::world::IWorldTestDispatcherTrait::emit_test( + world_test, + dojo::event::Event::<$type_name$>::selector(), + dojo::event::Event::<$type_name$>::keys(self), + dojo::event::Event::<$type_name$>::values(self), + dojo::event::Event::<$type_name$>::historical() + ); + } +} + #[starknet::contract] pub mod $contract_name$ { use super::$type_name$; diff --git a/crates/compiler/src/plugin/plugin_test_data/event b/crates/compiler/src/plugin/plugin_test_data/event index c99b22d..56f7364 100644 --- a/crates/compiler/src/plugin/plugin_test_data/event +++ b/crates/compiler/src/plugin/plugin_test_data/event @@ -127,6 +127,13 @@ dojo::meta::introspect::Member { } } +#[generate_trait] +pub impl MessageEmitterImpl of MessageEmitter { + fn emit(self: @Message, world: dojo::world::IWorldDispatcher) { + dojo::event::Event::::emit(self, world); + } +} + pub impl MessageEventImpl of dojo::event::Event { fn emit(self: @Message, world: dojo::world::IWorldDispatcher) { @@ -581,6 +588,13 @@ dojo::meta::introspect::Member { } } +#[generate_trait] +pub impl MyEventWithNamespaceEmitterImpl of MyEventWithNamespaceEmitter { + fn emit(self: @MyEventWithNamespace, world: dojo::world::IWorldDispatcher) { + dojo::event::Event::::emit(self, world); + } +} + pub impl MyEventWithNamespaceEventImpl of dojo::event::Event { fn emit(self: @MyEventWithNamespace, world: dojo::world::IWorldDispatcher) { @@ -1033,6 +1047,13 @@ dojo::meta::introspect::Member { } } +#[generate_trait] +pub impl MyEventNoHistoricalEmitterImpl of MyEventNoHistoricalEmitter { + fn emit(self: @MyEventNoHistorical, world: dojo::world::IWorldDispatcher) { + dojo::event::Event::::emit(self, world); + } +} + pub impl MyEventNoHistoricalEventImpl of dojo::event::Event { fn emit(self: @MyEventNoHistorical, world: dojo::world::IWorldDispatcher) { @@ -1443,5 +1464,14 @@ impl StorageStorageBaseCopy of core::traits::Copy::; impl StorageStorageBaseMutDrop of core::traits::Drop::; impl StorageStorageBaseMutCopy of core::traits::Copy::; } +pub trait MessageEmitter { + fn emit(self: @Message, world: dojo::world::IWorldDispatcher); +} +pub trait MyEventWithNamespaceEmitter { + fn emit(self: @MyEventWithNamespace, world: dojo::world::IWorldDispatcher); +} +pub trait MyEventNoHistoricalEmitter { + fn emit(self: @MyEventNoHistorical, world: dojo::world::IWorldDispatcher); +} //! > expected_diagnostics diff --git a/crates/contracts/src/event/event.cairo b/crates/contracts/src/event/event.cairo index 25da2eb..89d687a 100644 --- a/crates/contracts/src/event/event.cairo +++ b/crates/contracts/src/event/event.cairo @@ -40,3 +40,8 @@ pub trait IEvent { fn layout(self: @T) -> Layout; fn schema(self: @T) -> Ty; } + +#[cfg(target: "test")] +pub trait EventTest { + fn emit_test(self: @T, world: IWorldDispatcher); +} diff --git a/crates/contracts/src/lib.cairo b/crates/contracts/src/lib.cairo index b98d050..5d38ef1 100644 --- a/crates/contracts/src/lib.cairo +++ b/crates/contracts/src/lib.cairo @@ -9,6 +9,9 @@ pub mod contract { pub mod event { pub mod event; pub use event::{Event, IEvent, IEventDispatcher, IEventDispatcherTrait}; + + #[cfg(target: "test")] + pub use event::{EventTest}; } pub mod meta { diff --git a/crates/contracts/src/tests/helpers.cairo b/crates/contracts/src/tests/helpers.cairo index 54d22cf..281bb33 100644 --- a/crates/contracts/src/tests/helpers.cairo +++ b/crates/contracts/src/tests/helpers.cairo @@ -5,6 +5,14 @@ use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; use dojo::model::Model; use dojo::utils::test::{deploy_with_world_address, spawn_test_world}; +#[derive(Copy, Drop, Serde, Debug)] +#[dojo::event] +pub struct SimpleEvent { + #[key] + pub id: u32, + pub data: (felt252, felt252), +} + #[derive(Copy, Drop, Serde, Debug)] #[dojo::model] pub struct Foo { diff --git a/crates/contracts/src/tests/world/world.cairo b/crates/contracts/src/tests/world/world.cairo index 117aa07..1b0eae9 100644 --- a/crates/contracts/src/tests/world/world.cairo +++ b/crates/contracts/src/tests/world/world.cairo @@ -12,7 +12,8 @@ use dojo::world::{ }; use dojo::tests::helpers::{ IbarDispatcher, IbarDispatcherTrait, drop_all_events, deploy_world_and_bar, Foo, foo, bar, - Character, character, test_contract, test_contract_with_dojo_init_args + Character, character, test_contract, test_contract_with_dojo_init_args, SimpleEvent, + simple_event, SimpleEventEmitter }; use dojo::utils::test::{spawn_test_world, deploy_with_world_address, GasCounterTrait}; @@ -110,23 +111,29 @@ fn test_emit() { let bob = starknet::contract_address_const::<0xb0b>(); let world = deploy_world(); + world.register_event(simple_event::TEST_CLASS_HASH.try_into().unwrap()); + world.grant_writer(dojo::event::Event::::selector(), bob); drop_all_events(world.contract_address); starknet::testing::set_contract_address(bob); - world.emit(selector!("MyEvent"), [1, 2].span(), [3, 4].span(), true); + let simple_event = SimpleEvent { id: 2, data: (3, 4) }; + simple_event.emit(world); let event = starknet::testing::pop_log::(world.contract_address); assert(event.is_some(), 'no event'); if let Event::EventEmitted(event) = event.unwrap() { - assert(event.event_selector == selector!("MyEvent"), 'bad event selector'); + assert( + event.event_selector == dojo::event::Event::::selector(), + 'bad event selector' + ); assert(event.system_address == bob, 'bad system address'); assert(event.historical, 'bad historical value'); - assert(event.keys == [1, 2].span(), 'bad keys'); - assert(event.values == [3, 4].span(), 'bad keys'); + assert(event.keys == [2].span(), 'bad keys'); + assert(event.values == [3, 4].span(), 'bad values'); } else { core::panic_with_felt252('no EventEmitted event'); } diff --git a/crates/contracts/src/world/world_contract.cairo b/crates/contracts/src/world/world_contract.cairo index ccbb087..23e967f 100644 --- a/crates/contracts/src/world/world_contract.cairo +++ b/crates/contracts/src/world/world_contract.cairo @@ -110,6 +110,14 @@ pub trait IWorldTest { ); fn delete_entity_test(ref self: T, model_selector: felt252, index: ModelIndex, layout: Layout); + + fn emit_test( + ref self: T, + event_selector: felt252, + keys: Span, + values: Span, + historical: bool + ); } #[starknet::interface] @@ -415,6 +423,21 @@ pub mod world { ) { self.delete_entity_internal(model_selector, index, layout); } + + fn emit_test( + ref self: ContractState, + event_selector: felt252, + keys: Span, + values: Span, + historical: bool + ) { + EventEmitter::emit( + ref self, + EventEmitted { + event_selector, system_address: get_caller_address(), historical, keys, values + } + ); + } } #[abi(embed_v0)] @@ -982,12 +1005,24 @@ pub mod world { values: Span, historical: bool ) { - EventEmitter::emit( - ref self, - EventEmitted { - event_selector, system_address: get_caller_address(), historical, keys, values, - } - ); + if let Resource::Event((_, _)) = self.resources.read(event_selector) { + self.assert_caller_permissions(event_selector, Permission::Writer); + + EventEmitter::emit( + ref self, + EventEmitted { + event_selector, + system_address: get_caller_address(), + historical, + keys, + values, + } + ); + } else { + panic_with_byte_array( + @errors::resource_conflict(@format!("{event_selector}"), @"event") + ); + } } /// Gets the values of a model record/entity/member. diff --git a/examples/dojo_simple/src/lib.cairo b/examples/dojo_simple/src/lib.cairo index 8d13f4b..649e656 100644 --- a/examples/dojo_simple/src/lib.cairo +++ b/examples/dojo_simple/src/lib.cairo @@ -22,7 +22,7 @@ pub mod models { pub mod events { use starknet::ContractAddress; - #[derive(Drop)] + #[derive(Drop, Serde)] #[dojo::event] pub struct PositionUpdated { #[key] @@ -58,8 +58,6 @@ pub mod actions { position.set(world); emit!(world, PositionUpdated { player: caller, new_x: 1, new_y: 2 }); - - } } } diff --git a/scripts/cairo_fmt.sh b/scripts/cairo_fmt.sh index 81aa71d..9c208f4 100644 --- a/scripts/cairo_fmt.sh +++ b/scripts/cairo_fmt.sh @@ -1,3 +1,7 @@ #!/bin/bash -scarb --manifest-path crates/contracts/Scarb.toml fmt --check +if [ "$1" == "--check" ]; then + scarb --manifest-path crates/contracts/Scarb.toml fmt --check +else + scarb --manifest-path crates/contracts/Scarb.toml fmt +fi diff --git a/scripts/rust_fmt.sh b/scripts/rust_fmt.sh index db5636d..b657392 100755 --- a/scripts/rust_fmt.sh +++ b/scripts/rust_fmt.sh @@ -1,3 +1,7 @@ #!/bin/bash -cargo +nightly-2024-08-28 fmt --check --all -- "$@" +if [ "$1" == "--check" ]; then + cargo +nightly-2024-08-28 fmt --check --all -- "$@" +else + cargo +nightly-2024-08-28 fmt --all -- "$@" +fi From 7e7f92b9964c57d2f5cc019256e57f35ff5722ba Mon Sep 17 00:00:00 2001 From: glihm Date: Tue, 8 Oct 2024 21:34:17 -0600 Subject: [PATCH 10/11] ci: add ci + fix abigen comparison --- .github/workflows/ci.yml | 45 + bins/abigen/src/main.rs | 4 +- .../src/compiler/scarb_internal/debug.rs | 2 +- .../src/compiler/scarb_internal/mod.rs | 4 +- .../src/plugin/attribute_macros/contract.rs | 2 +- .../src/plugin/attribute_macros/event.rs | 2 +- .../plugin/derive_macros/introspect/layout.rs | 2 +- .../plugin/derive_macros/introspect/utils.rs | 2 +- crates/types/src/world.rs | 814 ++++++++++++++---- scripts/cairo_fmt.sh | 0 scripts/docs.sh | 3 + scripts/tests.sh | 16 +- 12 files changed, 741 insertions(+), 155 deletions(-) create mode 100644 .github/workflows/ci.yml mode change 100644 => 100755 scripts/cairo_fmt.sh create mode 100755 scripts/docs.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..01616dc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,45 @@ +name: ci + +on: + push: + branches: + - main + pull_request: + +env: + CARGO_TERM_COLOR: always + RUST_VERSION: 1.80.0 + +jobs: + test: + runs-on: ubuntu-latest-4-cores + steps: + - uses: actions/checkout@v3 + - uses: Swatinem/rust-cache@v2 + - run: | + scripts/tests.sh + + cairofmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: software-mansion/setup-scarb@v1 + with: + scarb-version: "2.7.1" + - run: | + bash scripts/cairo_fmt.sh --check + + rustfmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: Swatinem/rust-cache@v2 + - run: scripts/rust_fmt.sh --check + + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: Swatinem/rust-cache@v2 + - run: > + scripts/docs.sh diff --git a/bins/abigen/src/main.rs b/bins/abigen/src/main.rs index c00b59e..c8bf601 100644 --- a/bins/abigen/src/main.rs +++ b/bins/abigen/src/main.rs @@ -87,7 +87,9 @@ fn generate_bindings( if Path::new(&out_path).exists() { let existing_bindings = fs::read_to_string(out_path)?; - if existing_bindings != generated_bindings { + if existing_bindings.replace(char::is_whitespace, "") + != generated_bindings.replace(char::is_whitespace, "") + { return Err(anyhow!( "{contract_name} ABI bindings are not up to date. Consider generating them \ running `cargo run -p dojo-abigen`" diff --git a/crates/compiler/src/compiler/scarb_internal/debug.rs b/crates/compiler/src/compiler/scarb_internal/debug.rs index 3b13833..df44693 100644 --- a/crates/compiler/src/compiler/scarb_internal/debug.rs +++ b/crates/compiler/src/compiler/scarb_internal/debug.rs @@ -33,7 +33,7 @@ pub fn compile_prepared_db_to_debug_info( /// Compile declared Starknet contract. /// /// The `contract` value **must** come from `db`, for example as a result of calling -/// [`find_contracts`]. Does not check diagnostics, it is expected that they are checked by caller +/// `find_contracts`. Does not check diagnostics, it is expected that they are checked by caller /// of this function. fn compile_contract_with_prepared_and_checked_db_to_debug_info( db: &RootDatabase, diff --git a/crates/compiler/src/compiler/scarb_internal/mod.rs b/crates/compiler/src/compiler/scarb_internal/mod.rs index 6061c06..c2c5ade 100644 --- a/crates/compiler/src/compiler/scarb_internal/mod.rs +++ b/crates/compiler/src/compiler/scarb_internal/mod.rs @@ -1,7 +1,7 @@ //! Scarb internal code used to compile Cairo contracts. //! -//! Copied from source code from https://github.com/software-mansion/scarb/blob/main/scarb/src/compiler/db.rs -//! since build_scarb_root_database is not public. +//! Copied from source code from +//! since `build_scarb_root_database` is not public. use anyhow::Result; use cairo_lang_compiler::db::RootDatabase; use cairo_lang_compiler::project::{ProjectConfig, ProjectConfigContent}; diff --git a/crates/compiler/src/plugin/attribute_macros/contract.rs b/crates/compiler/src/plugin/attribute_macros/contract.rs index 28ffc3e..27ddd51 100644 --- a/crates/compiler/src/plugin/attribute_macros/contract.rs +++ b/crates/compiler/src/plugin/attribute_macros/contract.rs @@ -464,7 +464,7 @@ impl DojoContract { /// * adding `let world = self.world_dispatcher.read();` statement at the beginning of the /// function to restore the removed `world` parameter. /// * if `has_generate_trait` is true, the implementation containing the function has the - /// #[generate_trait] attribute. + /// `#[generate_trait]` attribute. pub fn rewrite_function( &mut self, db: &dyn SyntaxGroup, diff --git a/crates/compiler/src/plugin/attribute_macros/event.rs b/crates/compiler/src/plugin/attribute_macros/event.rs index 36381bc..f235e4c 100644 --- a/crates/compiler/src/plugin/attribute_macros/event.rs +++ b/crates/compiler/src/plugin/attribute_macros/event.rs @@ -3,7 +3,7 @@ //! We append the event selector directly within the append_keys_and_data function. //! Without the need of the enum for all event variants. //! -//! https://github.com/starkware-libs/cairo/blob/main/crates/cairo-lang-starknet/src/plugin/derive/event.rs +//! use cairo_lang_defs::patcher::{PatchBuilder, RewriteNode}; use cairo_lang_defs::plugin::{ diff --git a/crates/compiler/src/plugin/derive_macros/introspect/layout.rs b/crates/compiler/src/plugin/derive_macros/introspect/layout.rs index de6623a..274a1c4 100644 --- a/crates/compiler/src/plugin/derive_macros/introspect/layout.rs +++ b/crates/compiler/src/plugin/derive_macros/introspect/layout.rs @@ -102,7 +102,7 @@ pub fn get_layout_from_type_clause( } /// Build the array layout describing the provided array type. -/// item_type could be something like Array for example. +/// item_type could be something like `Array` for example. pub fn build_array_layout_from_type( diagnostics: &mut Vec, diagnostic_item: ids::SyntaxStablePtrId, diff --git a/crates/compiler/src/plugin/derive_macros/introspect/utils.rs b/crates/compiler/src/plugin/derive_macros/introspect/utils.rs index f2f586c..7ee1ab3 100644 --- a/crates/compiler/src/plugin/derive_macros/introspect/utils.rs +++ b/crates/compiler/src/plugin/derive_macros/introspect/utils.rs @@ -20,7 +20,7 @@ pub fn primitive_type_introspection() -> HashMap { ]) } -/// Check if the provided type is an unsupported Option, +/// Check if the provided type is an unsupported `Option`, /// because tuples are not supported with Option. pub fn is_unsupported_option_type(ty: &str) -> bool { ty.starts_with("Option<(") diff --git a/crates/types/src/world.rs b/crates/types/src/world.rs index a63083a..5bb3605 100644 --- a/crates/types/src/world.rs +++ b/crates/types/src/world.rs @@ -233,6 +233,192 @@ impl cainome::cairo_serde::CairoSerde for DifferProgramHashUpdate { } } #[derive(Clone, serde::Serialize, serde::Deserialize, PartialEq, Debug)] +pub struct EventEmitted { + pub event_selector: starknet::core::types::Felt, + pub system_address: cainome::cairo_serde::ContractAddress, + pub historical: bool, + pub keys: Vec, + pub values: Vec, +} +impl cainome::cairo_serde::CairoSerde for EventEmitted { + type RustType = Self; + const SERIALIZED_SIZE: std::option::Option = None; + #[inline] + fn cairo_serialized_size(__rust: &Self::RustType) -> usize { + let mut __size = 0; + __size += starknet::core::types::Felt::cairo_serialized_size(&__rust.event_selector); + __size += + cainome::cairo_serde::ContractAddress::cairo_serialized_size(&__rust.system_address); + __size += bool::cairo_serialized_size(&__rust.historical); + __size += Vec::::cairo_serialized_size(&__rust.keys); + __size += Vec::::cairo_serialized_size(&__rust.values); + __size + } + fn cairo_serialize(__rust: &Self::RustType) -> Vec { + let mut __out: Vec = vec![]; + __out.extend(starknet::core::types::Felt::cairo_serialize( + &__rust.event_selector, + )); + __out.extend(cainome::cairo_serde::ContractAddress::cairo_serialize( + &__rust.system_address, + )); + __out.extend(bool::cairo_serialize(&__rust.historical)); + __out.extend(Vec::::cairo_serialize( + &__rust.keys, + )); + __out.extend(Vec::::cairo_serialize( + &__rust.values, + )); + __out + } + fn cairo_deserialize( + __felts: &[starknet::core::types::Felt], + __offset: usize, + ) -> cainome::cairo_serde::Result { + let mut __offset = __offset; + let event_selector = starknet::core::types::Felt::cairo_deserialize(__felts, __offset)?; + __offset += starknet::core::types::Felt::cairo_serialized_size(&event_selector); + let system_address = + cainome::cairo_serde::ContractAddress::cairo_deserialize(__felts, __offset)?; + __offset += cainome::cairo_serde::ContractAddress::cairo_serialized_size(&system_address); + let historical = bool::cairo_deserialize(__felts, __offset)?; + __offset += bool::cairo_serialized_size(&historical); + let keys = Vec::::cairo_deserialize(__felts, __offset)?; + __offset += Vec::::cairo_serialized_size(&keys); + let values = Vec::::cairo_deserialize(__felts, __offset)?; + __offset += Vec::::cairo_serialized_size(&values); + Ok(EventEmitted { + event_selector, + system_address, + historical, + keys, + values, + }) + } +} +#[derive(Clone, serde::Serialize, serde::Deserialize, PartialEq, Debug)] +pub struct EventRegistered { + pub name: cainome::cairo_serde::ByteArray, + pub namespace: cainome::cairo_serde::ByteArray, + pub class_hash: cainome::cairo_serde::ClassHash, + pub address: cainome::cairo_serde::ContractAddress, +} +impl cainome::cairo_serde::CairoSerde for EventRegistered { + type RustType = Self; + const SERIALIZED_SIZE: std::option::Option = None; + #[inline] + fn cairo_serialized_size(__rust: &Self::RustType) -> usize { + let mut __size = 0; + __size += cainome::cairo_serde::ByteArray::cairo_serialized_size(&__rust.name); + __size += cainome::cairo_serde::ByteArray::cairo_serialized_size(&__rust.namespace); + __size += cainome::cairo_serde::ClassHash::cairo_serialized_size(&__rust.class_hash); + __size += cainome::cairo_serde::ContractAddress::cairo_serialized_size(&__rust.address); + __size + } + fn cairo_serialize(__rust: &Self::RustType) -> Vec { + let mut __out: Vec = vec![]; + __out.extend(cainome::cairo_serde::ByteArray::cairo_serialize( + &__rust.name, + )); + __out.extend(cainome::cairo_serde::ByteArray::cairo_serialize( + &__rust.namespace, + )); + __out.extend(cainome::cairo_serde::ClassHash::cairo_serialize( + &__rust.class_hash, + )); + __out.extend(cainome::cairo_serde::ContractAddress::cairo_serialize( + &__rust.address, + )); + __out + } + fn cairo_deserialize( + __felts: &[starknet::core::types::Felt], + __offset: usize, + ) -> cainome::cairo_serde::Result { + let mut __offset = __offset; + let name = cainome::cairo_serde::ByteArray::cairo_deserialize(__felts, __offset)?; + __offset += cainome::cairo_serde::ByteArray::cairo_serialized_size(&name); + let namespace = cainome::cairo_serde::ByteArray::cairo_deserialize(__felts, __offset)?; + __offset += cainome::cairo_serde::ByteArray::cairo_serialized_size(&namespace); + let class_hash = cainome::cairo_serde::ClassHash::cairo_deserialize(__felts, __offset)?; + __offset += cainome::cairo_serde::ClassHash::cairo_serialized_size(&class_hash); + let address = cainome::cairo_serde::ContractAddress::cairo_deserialize(__felts, __offset)?; + __offset += cainome::cairo_serde::ContractAddress::cairo_serialized_size(&address); + Ok(EventRegistered { + name, + namespace, + class_hash, + address, + }) + } +} +#[derive(Clone, serde::Serialize, serde::Deserialize, PartialEq, Debug)] +pub struct EventUpgraded { + pub name: cainome::cairo_serde::ByteArray, + pub namespace: cainome::cairo_serde::ByteArray, + pub class_hash: cainome::cairo_serde::ClassHash, + pub address: cainome::cairo_serde::ContractAddress, + pub prev_address: cainome::cairo_serde::ContractAddress, +} +impl cainome::cairo_serde::CairoSerde for EventUpgraded { + type RustType = Self; + const SERIALIZED_SIZE: std::option::Option = None; + #[inline] + fn cairo_serialized_size(__rust: &Self::RustType) -> usize { + let mut __size = 0; + __size += cainome::cairo_serde::ByteArray::cairo_serialized_size(&__rust.name); + __size += cainome::cairo_serde::ByteArray::cairo_serialized_size(&__rust.namespace); + __size += cainome::cairo_serde::ClassHash::cairo_serialized_size(&__rust.class_hash); + __size += cainome::cairo_serde::ContractAddress::cairo_serialized_size(&__rust.address); + __size += + cainome::cairo_serde::ContractAddress::cairo_serialized_size(&__rust.prev_address); + __size + } + fn cairo_serialize(__rust: &Self::RustType) -> Vec { + let mut __out: Vec = vec![]; + __out.extend(cainome::cairo_serde::ByteArray::cairo_serialize( + &__rust.name, + )); + __out.extend(cainome::cairo_serde::ByteArray::cairo_serialize( + &__rust.namespace, + )); + __out.extend(cainome::cairo_serde::ClassHash::cairo_serialize( + &__rust.class_hash, + )); + __out.extend(cainome::cairo_serde::ContractAddress::cairo_serialize( + &__rust.address, + )); + __out.extend(cainome::cairo_serde::ContractAddress::cairo_serialize( + &__rust.prev_address, + )); + __out + } + fn cairo_deserialize( + __felts: &[starknet::core::types::Felt], + __offset: usize, + ) -> cainome::cairo_serde::Result { + let mut __offset = __offset; + let name = cainome::cairo_serde::ByteArray::cairo_deserialize(__felts, __offset)?; + __offset += cainome::cairo_serde::ByteArray::cairo_serialized_size(&name); + let namespace = cainome::cairo_serde::ByteArray::cairo_deserialize(__felts, __offset)?; + __offset += cainome::cairo_serde::ByteArray::cairo_serialized_size(&namespace); + let class_hash = cainome::cairo_serde::ClassHash::cairo_deserialize(__felts, __offset)?; + __offset += cainome::cairo_serde::ClassHash::cairo_serialized_size(&class_hash); + let address = cainome::cairo_serde::ContractAddress::cairo_deserialize(__felts, __offset)?; + __offset += cainome::cairo_serde::ContractAddress::cairo_serialized_size(&address); + let prev_address = + cainome::cairo_serde::ContractAddress::cairo_deserialize(__felts, __offset)?; + __offset += cainome::cairo_serde::ContractAddress::cairo_serialized_size(&prev_address); + Ok(EventUpgraded { + name, + namespace, + class_hash, + address, + prev_address, + }) + } +} +#[derive(Clone, serde::Serialize, serde::Deserialize, PartialEq, Debug)] pub struct FactsRegistryUpdate { pub address: cainome::cairo_serde::ContractAddress, } @@ -425,7 +611,6 @@ pub struct ModelUpgraded { pub name: cainome::cairo_serde::ByteArray, pub namespace: cainome::cairo_serde::ByteArray, pub class_hash: cainome::cairo_serde::ClassHash, - pub prev_class_hash: cainome::cairo_serde::ClassHash, pub address: cainome::cairo_serde::ContractAddress, pub prev_address: cainome::cairo_serde::ContractAddress, } @@ -438,7 +623,6 @@ impl cainome::cairo_serde::CairoSerde for ModelUpgraded { __size += cainome::cairo_serde::ByteArray::cairo_serialized_size(&__rust.name); __size += cainome::cairo_serde::ByteArray::cairo_serialized_size(&__rust.namespace); __size += cainome::cairo_serde::ClassHash::cairo_serialized_size(&__rust.class_hash); - __size += cainome::cairo_serde::ClassHash::cairo_serialized_size(&__rust.prev_class_hash); __size += cainome::cairo_serde::ContractAddress::cairo_serialized_size(&__rust.address); __size += cainome::cairo_serde::ContractAddress::cairo_serialized_size(&__rust.prev_address); @@ -455,9 +639,6 @@ impl cainome::cairo_serde::CairoSerde for ModelUpgraded { __out.extend(cainome::cairo_serde::ClassHash::cairo_serialize( &__rust.class_hash, )); - __out.extend(cainome::cairo_serde::ClassHash::cairo_serialize( - &__rust.prev_class_hash, - )); __out.extend(cainome::cairo_serde::ContractAddress::cairo_serialize( &__rust.address, )); @@ -477,9 +658,6 @@ impl cainome::cairo_serde::CairoSerde for ModelUpgraded { __offset += cainome::cairo_serde::ByteArray::cairo_serialized_size(&namespace); let class_hash = cainome::cairo_serde::ClassHash::cairo_deserialize(__felts, __offset)?; __offset += cainome::cairo_serde::ClassHash::cairo_serialized_size(&class_hash); - let prev_class_hash = - cainome::cairo_serde::ClassHash::cairo_deserialize(__felts, __offset)?; - __offset += cainome::cairo_serde::ClassHash::cairo_serialized_size(&prev_class_hash); let address = cainome::cairo_serde::ContractAddress::cairo_deserialize(__felts, __offset)?; __offset += cainome::cairo_serde::ContractAddress::cairo_serialized_size(&address); let prev_address = @@ -489,7 +667,6 @@ impl cainome::cairo_serde::CairoSerde for ModelUpgraded { name, namespace, class_hash, - prev_class_hash, address, prev_address, }) @@ -1241,6 +1418,8 @@ pub enum Event { NamespaceRegistered(NamespaceRegistered), ModelRegistered(ModelRegistered), ModelUpgraded(ModelUpgraded), + EventRegistered(EventRegistered), + EventUpgraded(EventUpgraded), StoreSetRecord(StoreSetRecord), StoreUpdateRecord(StoreUpdateRecord), StoreUpdateMember(StoreUpdateMember), @@ -1249,6 +1428,7 @@ pub enum Event { OwnerUpdated(OwnerUpdated), ConfigEvent(DojoConfigEvent), StateUpdated(StateUpdated), + EventEmitted(EventEmitted), } impl cainome::cairo_serde::CairoSerde for Event { type RustType = Self; @@ -1265,6 +1445,8 @@ impl cainome::cairo_serde::CairoSerde for Event { Event::NamespaceRegistered(val) => NamespaceRegistered::cairo_serialized_size(val) + 1, Event::ModelRegistered(val) => ModelRegistered::cairo_serialized_size(val) + 1, Event::ModelUpgraded(val) => ModelUpgraded::cairo_serialized_size(val) + 1, + Event::EventRegistered(val) => EventRegistered::cairo_serialized_size(val) + 1, + Event::EventUpgraded(val) => EventUpgraded::cairo_serialized_size(val) + 1, Event::StoreSetRecord(val) => StoreSetRecord::cairo_serialized_size(val) + 1, Event::StoreUpdateRecord(val) => StoreUpdateRecord::cairo_serialized_size(val) + 1, Event::StoreUpdateMember(val) => StoreUpdateMember::cairo_serialized_size(val) + 1, @@ -1273,6 +1455,7 @@ impl cainome::cairo_serde::CairoSerde for Event { Event::OwnerUpdated(val) => OwnerUpdated::cairo_serialized_size(val) + 1, Event::ConfigEvent(val) => DojoConfigEvent::cairo_serialized_size(val) + 1, Event::StateUpdated(val) => StateUpdated::cairo_serialized_size(val) + 1, + Event::EventEmitted(val) => EventEmitted::cairo_serialized_size(val) + 1, _ => 0, } } @@ -1332,54 +1515,72 @@ impl cainome::cairo_serde::CairoSerde for Event { temp.extend(ModelUpgraded::cairo_serialize(val)); temp } - Event::StoreSetRecord(val) => { + Event::EventRegistered(val) => { let mut temp = vec![]; temp.extend(usize::cairo_serialize(&9usize)); + temp.extend(EventRegistered::cairo_serialize(val)); + temp + } + Event::EventUpgraded(val) => { + let mut temp = vec![]; + temp.extend(usize::cairo_serialize(&10usize)); + temp.extend(EventUpgraded::cairo_serialize(val)); + temp + } + Event::StoreSetRecord(val) => { + let mut temp = vec![]; + temp.extend(usize::cairo_serialize(&11usize)); temp.extend(StoreSetRecord::cairo_serialize(val)); temp } Event::StoreUpdateRecord(val) => { let mut temp = vec![]; - temp.extend(usize::cairo_serialize(&10usize)); + temp.extend(usize::cairo_serialize(&12usize)); temp.extend(StoreUpdateRecord::cairo_serialize(val)); temp } Event::StoreUpdateMember(val) => { let mut temp = vec![]; - temp.extend(usize::cairo_serialize(&11usize)); + temp.extend(usize::cairo_serialize(&13usize)); temp.extend(StoreUpdateMember::cairo_serialize(val)); temp } Event::StoreDelRecord(val) => { let mut temp = vec![]; - temp.extend(usize::cairo_serialize(&12usize)); + temp.extend(usize::cairo_serialize(&14usize)); temp.extend(StoreDelRecord::cairo_serialize(val)); temp } Event::WriterUpdated(val) => { let mut temp = vec![]; - temp.extend(usize::cairo_serialize(&13usize)); + temp.extend(usize::cairo_serialize(&15usize)); temp.extend(WriterUpdated::cairo_serialize(val)); temp } Event::OwnerUpdated(val) => { let mut temp = vec![]; - temp.extend(usize::cairo_serialize(&14usize)); + temp.extend(usize::cairo_serialize(&16usize)); temp.extend(OwnerUpdated::cairo_serialize(val)); temp } Event::ConfigEvent(val) => { let mut temp = vec![]; - temp.extend(usize::cairo_serialize(&15usize)); + temp.extend(usize::cairo_serialize(&17usize)); temp.extend(DojoConfigEvent::cairo_serialize(val)); temp } Event::StateUpdated(val) => { let mut temp = vec![]; - temp.extend(usize::cairo_serialize(&16usize)); + temp.extend(usize::cairo_serialize(&18usize)); temp.extend(StateUpdated::cairo_serialize(val)); temp } + Event::EventEmitted(val) => { + let mut temp = vec![]; + temp.extend(usize::cairo_serialize(&19usize)); + temp.extend(EventEmitted::cairo_serialize(val)); + temp + } _ => vec![], } } @@ -1422,33 +1623,45 @@ impl cainome::cairo_serde::CairoSerde for Event { __felts, __offset + 1, )?)), - 9usize => Ok(Event::StoreSetRecord(StoreSetRecord::cairo_deserialize( + 9usize => Ok(Event::EventRegistered(EventRegistered::cairo_deserialize( + __felts, + __offset + 1, + )?)), + 10usize => Ok(Event::EventUpgraded(EventUpgraded::cairo_deserialize( + __felts, + __offset + 1, + )?)), + 11usize => Ok(Event::StoreSetRecord(StoreSetRecord::cairo_deserialize( __felts, __offset + 1, )?)), - 10usize => Ok(Event::StoreUpdateRecord( + 12usize => Ok(Event::StoreUpdateRecord( StoreUpdateRecord::cairo_deserialize(__felts, __offset + 1)?, )), - 11usize => Ok(Event::StoreUpdateMember( + 13usize => Ok(Event::StoreUpdateMember( StoreUpdateMember::cairo_deserialize(__felts, __offset + 1)?, )), - 12usize => Ok(Event::StoreDelRecord(StoreDelRecord::cairo_deserialize( + 14usize => Ok(Event::StoreDelRecord(StoreDelRecord::cairo_deserialize( __felts, __offset + 1, )?)), - 13usize => Ok(Event::WriterUpdated(WriterUpdated::cairo_deserialize( + 15usize => Ok(Event::WriterUpdated(WriterUpdated::cairo_deserialize( __felts, __offset + 1, )?)), - 14usize => Ok(Event::OwnerUpdated(OwnerUpdated::cairo_deserialize( + 16usize => Ok(Event::OwnerUpdated(OwnerUpdated::cairo_deserialize( __felts, __offset + 1, )?)), - 15usize => Ok(Event::ConfigEvent(DojoConfigEvent::cairo_deserialize( + 17usize => Ok(Event::ConfigEvent(DojoConfigEvent::cairo_deserialize( __felts, __offset + 1, )?)), - 16usize => Ok(Event::StateUpdated(StateUpdated::cairo_deserialize( + 18usize => Ok(Event::StateUpdated(StateUpdated::cairo_deserialize( + __felts, + __offset + 1, + )?)), + 19usize => Ok(Event::EventEmitted(EventEmitted::cairo_deserialize( __felts, __offset + 1, )?)), @@ -1859,19 +2072,6 @@ impl TryFrom for Event { } }; data_offset += cainome::cairo_serde::ClassHash::cairo_serialized_size(&class_hash); - let prev_class_hash = match cainome::cairo_serde::ClassHash::cairo_deserialize( - &event.data, - data_offset, - ) { - Ok(v) => v, - Err(e) => { - return Err(format!( - "Could not deserialize field {} for {}: {:?}", - "prev_class_hash", "ModelUpgraded", e - )); - } - }; - data_offset += cainome::cairo_serde::ClassHash::cairo_serialized_size(&prev_class_hash); let address = match cainome::cairo_serde::ContractAddress::cairo_deserialize( &event.data, data_offset, @@ -1903,41 +2103,18 @@ impl TryFrom for Event { name, namespace, class_hash, - prev_class_hash, address, prev_address, })); } let selector = event.keys[0]; if selector - == starknet::core::utils::get_selector_from_name("StoreSetRecord") - .unwrap_or_else(|_| panic!("Invalid selector for {}", "StoreSetRecord")) + == starknet::core::utils::get_selector_from_name("EventRegistered") + .unwrap_or_else(|_| panic!("Invalid selector for {}", "EventRegistered")) { let mut key_offset = 0 + 1; let mut data_offset = 0; - let table = - match starknet::core::types::Felt::cairo_deserialize(&event.data, data_offset) { - Ok(v) => v, - Err(e) => { - return Err(format!( - "Could not deserialize field {} for {}: {:?}", - "table", "StoreSetRecord", e - )); - } - }; - data_offset += starknet::core::types::Felt::cairo_serialized_size(&table); - let entity_id = - match starknet::core::types::Felt::cairo_deserialize(&event.data, data_offset) { - Ok(v) => v, - Err(e) => { - return Err(format!( - "Could not deserialize field {} for {}: {:?}", - "entity_id", "StoreSetRecord", e - )); - } - }; - data_offset += starknet::core::types::Felt::cairo_serialized_size(&entity_id); - let keys = match Vec::::cairo_deserialize( + let name = match cainome::cairo_serde::ByteArray::cairo_deserialize( &event.data, data_offset, ) { @@ -1945,12 +2122,12 @@ impl TryFrom for Event { Err(e) => { return Err(format!( "Could not deserialize field {} for {}: {:?}", - "keys", "StoreSetRecord", e + "name", "EventRegistered", e )); } }; - data_offset += Vec::::cairo_serialized_size(&keys); - let values = match Vec::::cairo_deserialize( + data_offset += cainome::cairo_serde::ByteArray::cairo_serialized_size(&name); + let namespace = match cainome::cairo_serde::ByteArray::cairo_deserialize( &event.data, data_offset, ) { @@ -1958,29 +2135,198 @@ impl TryFrom for Event { Err(e) => { return Err(format!( "Could not deserialize field {} for {}: {:?}", - "values", "StoreSetRecord", e + "namespace", "EventRegistered", e )); } }; - data_offset += Vec::::cairo_serialized_size(&values); - return Ok(Event::StoreSetRecord(StoreSetRecord { - table, - entity_id, - keys, - values, - })); - } - let selector = event.keys[0]; - if selector - == starknet::core::utils::get_selector_from_name("StoreUpdateRecord") - .unwrap_or_else(|_| panic!("Invalid selector for {}", "StoreUpdateRecord")) - { - let mut key_offset = 0 + 1; - let mut data_offset = 0; - let table = - match starknet::core::types::Felt::cairo_deserialize(&event.data, data_offset) { - Ok(v) => v, - Err(e) => { + data_offset += cainome::cairo_serde::ByteArray::cairo_serialized_size(&namespace); + let class_hash = match cainome::cairo_serde::ClassHash::cairo_deserialize( + &event.data, + data_offset, + ) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "class_hash", "EventRegistered", e + )); + } + }; + data_offset += cainome::cairo_serde::ClassHash::cairo_serialized_size(&class_hash); + let address = match cainome::cairo_serde::ContractAddress::cairo_deserialize( + &event.data, + data_offset, + ) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "address", "EventRegistered", e + )); + } + }; + data_offset += cainome::cairo_serde::ContractAddress::cairo_serialized_size(&address); + return Ok(Event::EventRegistered(EventRegistered { + name, + namespace, + class_hash, + address, + })); + } + let selector = event.keys[0]; + if selector + == starknet::core::utils::get_selector_from_name("EventUpgraded") + .unwrap_or_else(|_| panic!("Invalid selector for {}", "EventUpgraded")) + { + let mut key_offset = 0 + 1; + let mut data_offset = 0; + let name = match cainome::cairo_serde::ByteArray::cairo_deserialize( + &event.data, + data_offset, + ) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "name", "EventUpgraded", e + )); + } + }; + data_offset += cainome::cairo_serde::ByteArray::cairo_serialized_size(&name); + let namespace = match cainome::cairo_serde::ByteArray::cairo_deserialize( + &event.data, + data_offset, + ) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "namespace", "EventUpgraded", e + )); + } + }; + data_offset += cainome::cairo_serde::ByteArray::cairo_serialized_size(&namespace); + let class_hash = match cainome::cairo_serde::ClassHash::cairo_deserialize( + &event.data, + data_offset, + ) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "class_hash", "EventUpgraded", e + )); + } + }; + data_offset += cainome::cairo_serde::ClassHash::cairo_serialized_size(&class_hash); + let address = match cainome::cairo_serde::ContractAddress::cairo_deserialize( + &event.data, + data_offset, + ) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "address", "EventUpgraded", e + )); + } + }; + data_offset += cainome::cairo_serde::ContractAddress::cairo_serialized_size(&address); + let prev_address = match cainome::cairo_serde::ContractAddress::cairo_deserialize( + &event.data, + data_offset, + ) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "prev_address", "EventUpgraded", e + )); + } + }; + data_offset += + cainome::cairo_serde::ContractAddress::cairo_serialized_size(&prev_address); + return Ok(Event::EventUpgraded(EventUpgraded { + name, + namespace, + class_hash, + address, + prev_address, + })); + } + let selector = event.keys[0]; + if selector + == starknet::core::utils::get_selector_from_name("StoreSetRecord") + .unwrap_or_else(|_| panic!("Invalid selector for {}", "StoreSetRecord")) + { + let mut key_offset = 0 + 1; + let mut data_offset = 0; + let table = + match starknet::core::types::Felt::cairo_deserialize(&event.data, data_offset) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "table", "StoreSetRecord", e + )); + } + }; + data_offset += starknet::core::types::Felt::cairo_serialized_size(&table); + let entity_id = + match starknet::core::types::Felt::cairo_deserialize(&event.data, data_offset) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "entity_id", "StoreSetRecord", e + )); + } + }; + data_offset += starknet::core::types::Felt::cairo_serialized_size(&entity_id); + let keys = match Vec::::cairo_deserialize( + &event.data, + data_offset, + ) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "keys", "StoreSetRecord", e + )); + } + }; + data_offset += Vec::::cairo_serialized_size(&keys); + let values = match Vec::::cairo_deserialize( + &event.data, + data_offset, + ) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "values", "StoreSetRecord", e + )); + } + }; + data_offset += Vec::::cairo_serialized_size(&values); + return Ok(Event::StoreSetRecord(StoreSetRecord { + table, + entity_id, + keys, + values, + })); + } + let selector = event.keys[0]; + if selector + == starknet::core::utils::get_selector_from_name("StoreUpdateRecord") + .unwrap_or_else(|_| panic!("Invalid selector for {}", "StoreUpdateRecord")) + { + let mut key_offset = 0 + 1; + let mut data_offset = 0; + let table = + match starknet::core::types::Felt::cairo_deserialize(&event.data, data_offset) { + Ok(v) => v, + Err(e) => { return Err(format!( "Could not deserialize field {} for {}: {:?}", "table", "StoreUpdateRecord", e @@ -2310,6 +2656,82 @@ impl TryFrom for Event { data_offset += starknet::core::types::Felt::cairo_serialized_size(&da_hash); return Ok(Event::StateUpdated(StateUpdated { da_hash })); } + let selector = event.keys[0]; + if selector + == starknet::core::utils::get_selector_from_name("EventEmitted") + .unwrap_or_else(|_| panic!("Invalid selector for {}", "EventEmitted")) + { + let mut key_offset = 0 + 1; + let mut data_offset = 0; + let event_selector = + match starknet::core::types::Felt::cairo_deserialize(&event.keys, key_offset) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "event_selector", "EventEmitted", e + )); + } + }; + key_offset += starknet::core::types::Felt::cairo_serialized_size(&event_selector); + let system_address = match cainome::cairo_serde::ContractAddress::cairo_deserialize( + &event.keys, + key_offset, + ) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "system_address", "EventEmitted", e + )); + } + }; + key_offset += + cainome::cairo_serde::ContractAddress::cairo_serialized_size(&system_address); + let historical = match bool::cairo_deserialize(&event.keys, key_offset) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "historical", "EventEmitted", e + )); + } + }; + key_offset += bool::cairo_serialized_size(&historical); + let keys = match Vec::::cairo_deserialize( + &event.data, + data_offset, + ) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "keys", "EventEmitted", e + )); + } + }; + data_offset += Vec::::cairo_serialized_size(&keys); + let values = match Vec::::cairo_deserialize( + &event.data, + data_offset, + ) { + Ok(v) => v, + Err(e) => { + return Err(format!( + "Could not deserialize field {} for {}: {:?}", + "values", "EventEmitted", e + )); + } + }; + data_offset += Vec::::cairo_serialized_size(&values); + return Ok(Event::EventEmitted(EventEmitted { + event_selector, + system_address, + historical, + keys, + values, + })); + } Err(format!( "Could not match any event from keys {:?}", event.keys @@ -2496,17 +2918,23 @@ impl cainome::cairo_serde::CairoSerde for ModelIndex { pub enum Resource { Model( ( - cainome::cairo_serde::ClassHash, cainome::cairo_serde::ContractAddress, + starknet::core::types::Felt, + ), + ), + Event( + ( + cainome::cairo_serde::ContractAddress, + starknet::core::types::Felt, ), ), Contract( ( - cainome::cairo_serde::ClassHash, cainome::cairo_serde::ContractAddress, + starknet::core::types::Felt, ), ), - Namespace, + Namespace(cainome::cairo_serde::ByteArray), World, Unregistered, } @@ -2518,19 +2946,28 @@ impl cainome::cairo_serde::CairoSerde for Resource { match __rust { Resource::Model(val) => { <( - cainome::cairo_serde::ClassHash, cainome::cairo_serde::ContractAddress, + starknet::core::types::Felt, + )>::cairo_serialized_size(val) + + 1 + } + Resource::Event(val) => { + <( + cainome::cairo_serde::ContractAddress, + starknet::core::types::Felt, )>::cairo_serialized_size(val) + 1 } Resource::Contract(val) => { <( - cainome::cairo_serde::ClassHash, cainome::cairo_serde::ContractAddress, + starknet::core::types::Felt, )>::cairo_serialized_size(val) + 1 } - Resource::Namespace => 1, + Resource::Namespace(val) => { + cainome::cairo_serde::ByteArray::cairo_serialized_size(val) + 1 + } Resource::World => 1, Resource::Unregistered => 1, _ => 0, @@ -2542,23 +2979,37 @@ impl cainome::cairo_serde::CairoSerde for Resource { let mut temp = vec![]; temp.extend(usize::cairo_serialize(&0usize)); temp.extend(<( - cainome::cairo_serde::ClassHash, cainome::cairo_serde::ContractAddress, + starknet::core::types::Felt, )>::cairo_serialize(val)); temp } - Resource::Contract(val) => { + Resource::Event(val) => { let mut temp = vec![]; temp.extend(usize::cairo_serialize(&1usize)); temp.extend(<( - cainome::cairo_serde::ClassHash, cainome::cairo_serde::ContractAddress, + starknet::core::types::Felt, + )>::cairo_serialize(val)); + temp + } + Resource::Contract(val) => { + let mut temp = vec![]; + temp.extend(usize::cairo_serialize(&2usize)); + temp.extend(<( + cainome::cairo_serde::ContractAddress, + starknet::core::types::Felt, )>::cairo_serialize(val)); temp } - Resource::Namespace => usize::cairo_serialize(&2usize), - Resource::World => usize::cairo_serialize(&3usize), - Resource::Unregistered => usize::cairo_serialize(&4usize), + Resource::Namespace(val) => { + let mut temp = vec![]; + temp.extend(usize::cairo_serialize(&3usize)); + temp.extend(cainome::cairo_serde::ByteArray::cairo_serialize(val)); + temp + } + Resource::World => usize::cairo_serialize(&4usize), + Resource::Unregistered => usize::cairo_serialize(&5usize), _ => vec![], } } @@ -2570,20 +3021,28 @@ impl cainome::cairo_serde::CairoSerde for Resource { let __index = u128::from_be_bytes(__f.to_bytes_be()[16..].try_into().unwrap()); match __index as usize { 0usize => Ok(Resource::Model(<( - cainome::cairo_serde::ClassHash, cainome::cairo_serde::ContractAddress, + starknet::core::types::Felt, + )>::cairo_deserialize( + __felts, __offset + 1 + )?)), + 1usize => Ok(Resource::Event(<( + cainome::cairo_serde::ContractAddress, + starknet::core::types::Felt, )>::cairo_deserialize( __felts, __offset + 1 )?)), - 1usize => Ok(Resource::Contract(<( - cainome::cairo_serde::ClassHash, + 2usize => Ok(Resource::Contract(<( cainome::cairo_serde::ContractAddress, + starknet::core::types::Felt, )>::cairo_deserialize( __felts, __offset + 1 )?)), - 2usize => Ok(Resource::Namespace), - 3usize => Ok(Resource::World), - 4usize => Ok(Resource::Unregistered), + 3usize => Ok(Resource::Namespace( + cainome::cairo_serde::ByteArray::cairo_deserialize(__felts, __offset + 1)?, + )), + 4usize => Ok(Resource::World), + 5usize => Ok(Resource::Unregistered), _ => { return Err(cainome::cairo_serde::Error::Deserialize(format!( "Index not handle for enum {}", @@ -2610,24 +3069,6 @@ impl WorldContract { } #[allow(clippy::ptr_arg)] #[allow(clippy::too_many_arguments)] - pub fn emit( - &self, - keys: &Vec, - values: &Vec, - ) -> cainome::cairo_serde::call::FCall { - use cainome::cairo_serde::CairoSerde; - let mut __calldata = vec![]; - __calldata.extend(Vec::::cairo_serialize(keys)); - __calldata.extend(Vec::::cairo_serialize(values)); - let __call = starknet::core::types::FunctionCall { - contract_address: self.address, - entry_point_selector: starknet::macros::selector!("emit"), - calldata: __calldata, - }; - cainome::cairo_serde::call::FCall::new(__call, self.provider()) - } - #[allow(clippy::ptr_arg)] - #[allow(clippy::too_many_arguments)] pub fn entity( &self, model_selector: &starknet::core::types::Felt, @@ -2838,6 +3279,49 @@ impl WorldContract { } #[allow(clippy::ptr_arg)] #[allow(clippy::too_many_arguments)] + pub fn emit_getcall( + &self, + event_selector: &starknet::core::types::Felt, + keys: &Vec, + values: &Vec, + historical: &bool, + ) -> starknet::core::types::Call { + use cainome::cairo_serde::CairoSerde; + let mut __calldata = vec![]; + __calldata.extend(starknet::core::types::Felt::cairo_serialize(event_selector)); + __calldata.extend(Vec::::cairo_serialize(keys)); + __calldata.extend(Vec::::cairo_serialize(values)); + __calldata.extend(bool::cairo_serialize(historical)); + starknet::core::types::Call { + to: self.address, + selector: starknet::macros::selector!("emit"), + calldata: __calldata, + } + } + #[allow(clippy::ptr_arg)] + #[allow(clippy::too_many_arguments)] + pub fn emit( + &self, + event_selector: &starknet::core::types::Felt, + keys: &Vec, + values: &Vec, + historical: &bool, + ) -> starknet::accounts::ExecutionV1 { + use cainome::cairo_serde::CairoSerde; + let mut __calldata = vec![]; + __calldata.extend(starknet::core::types::Felt::cairo_serialize(event_selector)); + __calldata.extend(Vec::::cairo_serialize(keys)); + __calldata.extend(Vec::::cairo_serialize(values)); + __calldata.extend(bool::cairo_serialize(historical)); + let __call = starknet::core::types::Call { + to: self.address, + selector: starknet::macros::selector!("emit"), + calldata: __calldata, + }; + self.account.execute_v1(vec![__call]) + } + #[allow(clippy::ptr_arg)] + #[allow(clippy::too_many_arguments)] pub fn grant_owner_getcall( &self, resource: &starknet::core::types::Felt, @@ -2955,6 +3439,37 @@ impl WorldContract { } #[allow(clippy::ptr_arg)] #[allow(clippy::too_many_arguments)] + pub fn register_event_getcall( + &self, + class_hash: &cainome::cairo_serde::ClassHash, + ) -> starknet::core::types::Call { + use cainome::cairo_serde::CairoSerde; + let mut __calldata = vec![]; + __calldata.extend(cainome::cairo_serde::ClassHash::cairo_serialize(class_hash)); + starknet::core::types::Call { + to: self.address, + selector: starknet::macros::selector!("register_event"), + calldata: __calldata, + } + } + #[allow(clippy::ptr_arg)] + #[allow(clippy::too_many_arguments)] + pub fn register_event( + &self, + class_hash: &cainome::cairo_serde::ClassHash, + ) -> starknet::accounts::ExecutionV1 { + use cainome::cairo_serde::CairoSerde; + let mut __calldata = vec![]; + __calldata.extend(cainome::cairo_serde::ClassHash::cairo_serialize(class_hash)); + let __call = starknet::core::types::Call { + to: self.address, + selector: starknet::macros::selector!("register_event"), + calldata: __calldata, + }; + self.account.execute_v1(vec![__call]) + } + #[allow(clippy::ptr_arg)] + #[allow(clippy::too_many_arguments)] pub fn register_model_getcall( &self, class_hash: &cainome::cairo_serde::ClassHash, @@ -3297,12 +3812,10 @@ impl WorldContract { #[allow(clippy::too_many_arguments)] pub fn upgrade_contract_getcall( &self, - selector: &starknet::core::types::Felt, class_hash: &cainome::cairo_serde::ClassHash, ) -> starknet::core::types::Call { use cainome::cairo_serde::CairoSerde; let mut __calldata = vec![]; - __calldata.extend(starknet::core::types::Felt::cairo_serialize(selector)); __calldata.extend(cainome::cairo_serde::ClassHash::cairo_serialize(class_hash)); starknet::core::types::Call { to: self.address, @@ -3314,12 +3827,10 @@ impl WorldContract { #[allow(clippy::too_many_arguments)] pub fn upgrade_contract( &self, - selector: &starknet::core::types::Felt, class_hash: &cainome::cairo_serde::ClassHash, ) -> starknet::accounts::ExecutionV1 { use cainome::cairo_serde::CairoSerde; let mut __calldata = vec![]; - __calldata.extend(starknet::core::types::Felt::cairo_serialize(selector)); __calldata.extend(cainome::cairo_serde::ClassHash::cairo_serialize(class_hash)); let __call = starknet::core::types::Call { to: self.address, @@ -3330,6 +3841,37 @@ impl WorldContract { } #[allow(clippy::ptr_arg)] #[allow(clippy::too_many_arguments)] + pub fn upgrade_event_getcall( + &self, + class_hash: &cainome::cairo_serde::ClassHash, + ) -> starknet::core::types::Call { + use cainome::cairo_serde::CairoSerde; + let mut __calldata = vec![]; + __calldata.extend(cainome::cairo_serde::ClassHash::cairo_serialize(class_hash)); + starknet::core::types::Call { + to: self.address, + selector: starknet::macros::selector!("upgrade_event"), + calldata: __calldata, + } + } + #[allow(clippy::ptr_arg)] + #[allow(clippy::too_many_arguments)] + pub fn upgrade_event( + &self, + class_hash: &cainome::cairo_serde::ClassHash, + ) -> starknet::accounts::ExecutionV1 { + use cainome::cairo_serde::CairoSerde; + let mut __calldata = vec![]; + __calldata.extend(cainome::cairo_serde::ClassHash::cairo_serialize(class_hash)); + let __call = starknet::core::types::Call { + to: self.address, + selector: starknet::macros::selector!("upgrade_event"), + calldata: __calldata, + }; + self.account.execute_v1(vec![__call]) + } + #[allow(clippy::ptr_arg)] + #[allow(clippy::too_many_arguments)] pub fn upgrade_model_getcall( &self, class_hash: &cainome::cairo_serde::ClassHash, @@ -3437,24 +3979,6 @@ impl WorldContractReader

{ } #[allow(clippy::ptr_arg)] #[allow(clippy::too_many_arguments)] - pub fn emit( - &self, - keys: &Vec, - values: &Vec, - ) -> cainome::cairo_serde::call::FCall { - use cainome::cairo_serde::CairoSerde; - let mut __calldata = vec![]; - __calldata.extend(Vec::::cairo_serialize(keys)); - __calldata.extend(Vec::::cairo_serialize(values)); - let __call = starknet::core::types::FunctionCall { - contract_address: self.address, - entry_point_selector: starknet::macros::selector!("emit"), - calldata: __calldata, - }; - cainome::cairo_serde::call::FCall::new(__call, self.provider()) - } - #[allow(clippy::ptr_arg)] - #[allow(clippy::too_many_arguments)] pub fn entity( &self, model_selector: &starknet::core::types::Felt, diff --git a/scripts/cairo_fmt.sh b/scripts/cairo_fmt.sh old mode 100644 new mode 100755 diff --git a/scripts/docs.sh b/scripts/docs.sh new file mode 100755 index 0000000..1ee0622 --- /dev/null +++ b/scripts/docs.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +RUSTDOCFLAGS="-Dwarnings" cargo doc --document-private-items --no-deps --all-features --workspace diff --git a/scripts/tests.sh b/scripts/tests.sh index 851b1b6..1e92e04 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -1,13 +1,25 @@ # Cargo testing. +# To output the Cairo fix tests, use the `--fix` argument. + +# Testing the dojo compiler. cargo test -p dojo-compiler # Testing abigen content, which also builds the core contracts. # Need to check because the formatting of the generated code is then different from the one # generated on the fly. -# cargo run -r --bin dojo-abigen -- --check +if [ "$1" == "--fix" ]; then + cargo run -r --bin dojo-abigen +else + cargo run -r --bin dojo-abigen -- --check +fi # Testing with the demo compiler. -cargo build -r --bin demo-compiler +if [ "$1" == "--fix" ]; then + CAIRO_FIX_TESTS=1 cargo build -r --bin demo-compiler +else + cargo build -r --bin demo-compiler +fi + ./target/release/demo-compiler test --manifest-path crates/contracts/Scarb.toml ./target/release/demo-compiler build --manifest-path examples/dojo_simple/Scarb.toml From c0b54128e8eb0133bfafe08c6762d59ec726adbb Mon Sep 17 00:00:00 2001 From: glihm Date: Tue, 8 Oct 2024 22:01:15 -0600 Subject: [PATCH 11/11] ci: fix abigen --- .github/workflows/ci.yml | 3 +++ bins/abigen/src/main.rs | 20 +++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01616dc..1d64647 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,7 @@ jobs: steps: - uses: actions/checkout@v3 - uses: Swatinem/rust-cache@v2 + - uses: dtolnay/rust-toolchain@1.80.0 - run: | scripts/tests.sh @@ -34,6 +35,7 @@ jobs: steps: - uses: actions/checkout@v3 - uses: Swatinem/rust-cache@v2 + - uses: dtolnay/rust-toolchain@1.80.0 - run: scripts/rust_fmt.sh --check docs: @@ -41,5 +43,6 @@ jobs: steps: - uses: actions/checkout@v3 - uses: Swatinem/rust-cache@v2 + - uses: dtolnay/rust-toolchain@1.80.0 - run: > scripts/docs.sh diff --git a/bins/abigen/src/main.rs b/bins/abigen/src/main.rs index c8bf601..6253a72 100644 --- a/bins/abigen/src/main.rs +++ b/bins/abigen/src/main.rs @@ -12,6 +12,7 @@ use std::collections::HashMap; use std::fs; use std::path::Path; +use std::process::Command; use anyhow::{anyhow, Result}; use cainome::rs::Abigen; @@ -82,21 +83,26 @@ fn generate_bindings( let out_path = format!("{OUT_DIR}/{bindings_filename}"); if is_check_only { - let generated_bindings = fs::read_to_string(tmp_file)?; + Command::new("rustfmt") + .arg(&tmp_file) + .status() + .expect("Failed to run rustfmt on generated bindings"); + + let generated_bindings = fs::read_to_string(tmp_file)?.replace(char::is_whitespace, ""); if Path::new(&out_path).exists() { - let existing_bindings = fs::read_to_string(out_path)?; + let existing_bindings = fs::read_to_string(out_path)?.replace(char::is_whitespace, ""); - if existing_bindings.replace(char::is_whitespace, "") - != generated_bindings.replace(char::is_whitespace, "") - { + if existing_bindings != generated_bindings { return Err(anyhow!( "{contract_name} ABI bindings are not up to date. Consider generating them \ - running `cargo run -p dojo-abigen`" + running `cargo run -p dojo-abigen`.", )); } } else { - println!("No bindings found for {contract_name}, check skipped"); + return Err(anyhow!( + "No bindings found for {contract_name}, expected at {out_path}." + )); } } else { // Rename the temporary file to the output file is enough to update the bindings.