├── .github └── workflows │ ├── main.yml │ └── publish.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── codama-attributes ├── .gitignore ├── Cargo.toml └── src │ ├── attribute.rs │ ├── attribute_context.rs │ ├── attributes.rs │ ├── codama_attribute.rs │ ├── codama_directives │ ├── account_directive.rs │ ├── codama_directive.rs │ ├── default_value_directive.rs │ ├── encoding_directive.rs │ ├── error_directive.rs │ ├── fixed_size_directive.rs │ ├── mod.rs │ ├── size_prefix_directive.rs │ ├── type_directive.rs │ ├── type_nodes │ │ ├── boolean_type_node.rs │ │ ├── fixed_size_type_node.rs │ │ ├── mod.rs │ │ ├── number_type_node.rs │ │ ├── public_key_type_node.rs │ │ ├── string_type_node.rs │ │ └── type_node.rs │ └── value_nodes │ │ ├── boolean_value_node.rs │ │ ├── instruction_input_value_node.rs │ │ ├── mod.rs │ │ ├── number_value_node.rs │ │ ├── payer_value_node.rs │ │ ├── public_key_value_node.rs │ │ ├── string_value_node.rs │ │ ├── sysvar.rs │ │ └── value_node.rs │ ├── derive_attribute.rs │ ├── lib.rs │ ├── repr_attribute.rs │ ├── try_from_filter.rs │ ├── unsupported_attribute.rs │ └── utils │ ├── from_meta.rs │ ├── macros.rs │ ├── mod.rs │ └── set_once.rs ├── codama-errors ├── .gitignore ├── Cargo.toml ├── src │ ├── combine_errors.rs │ ├── errors.rs │ └── lib.rs └── tests │ ├── compilation.rs │ ├── filesystem.rs │ ├── invalid_node_conversion.rs │ └── manifest.rs ├── codama-korok-plugins ├── .gitignore ├── Cargo.toml └── src │ ├── default_plugin.rs │ ├── lib.rs │ └── plugin.rs ├── codama-korok-visitors ├── .gitignore ├── Cargo.toml ├── src │ ├── apply_codama_type_attributes_visitor.rs │ ├── combine_modules_visitor.rs │ ├── combine_types_visitor.rs │ ├── compose_visitor.rs │ ├── filter_items_visitor.rs │ ├── lib.rs │ ├── set_accounts_visitor.rs │ ├── set_borsh_types_visitor.rs │ ├── set_defined_types_visitor.rs │ ├── set_errors_visitor.rs │ ├── set_instructions_visitors.rs │ ├── set_link_types_visitor.rs │ ├── set_program_metadata_visitor.rs │ ├── uniform_visitor.rs │ ├── visitable.rs │ └── visitor.rs └── tests │ ├── apply_codama_type_attributes_visitor │ ├── encoding_directive.rs │ ├── fixed_size_directive.rs │ ├── mod.rs │ ├── size_prefix_directive.rs │ └── type_directive.rs │ ├── combine_modules_visitor │ ├── defined_type_node.rs │ ├── mod.rs │ ├── program_node.rs │ ├── root_node.rs │ └── utils.rs │ ├── combine_types_visitor │ ├── enum_korok.rs │ ├── enum_variant_korok.rs │ ├── fields_korok.rs │ ├── mod.rs │ └── struct_korok.rs │ ├── compose_visitor.rs │ ├── filter_items_visitor.rs │ ├── lib.rs │ ├── set_accounts_visitor │ ├── from_codama_account.rs │ ├── from_codama_accounts.rs │ └── mod.rs │ ├── set_borsh_types_visitor │ ├── array_type_node.rs │ ├── boolean_type_node.rs │ ├── enum_empty_variant_type_node.rs │ ├── enum_struct_variant_type_node.rs │ ├── enum_tuple_variant_type_node.rs │ ├── enum_type_node.rs │ ├── field_korok.rs │ ├── map_type_node.rs │ ├── mod.rs │ ├── no_override.rs │ ├── number_type_node.rs │ ├── option_type_node.rs │ ├── public_key_type_node.rs │ ├── set_type_node.rs │ ├── string_type_node.rs │ ├── struct_type_node.rs │ ├── tuple_type_node.rs │ └── utils.rs │ ├── set_defined_types_visitor.rs │ ├── set_errors_visitor │ ├── from_codama_errors.rs │ └── mod.rs │ ├── set_instructions_visitor │ ├── from_codama_instruction.rs │ ├── from_codama_instructions.rs │ └── mod.rs │ ├── set_link_types_visitor.rs │ ├── set_program_metadata_visitor │ ├── fixtures │ │ └── full_metadata.toml │ └── mod.rs │ └── uniform_visitor.rs ├── codama-koroks ├── .gitignore ├── Cargo.toml ├── src │ ├── crate_korok.rs │ ├── enum_korok.rs │ ├── enum_variant_korok.rs │ ├── field_korok.rs │ ├── fields_korok.rs │ ├── file_module_korok.rs │ ├── item_korok.rs │ ├── korok.rs │ ├── lib.rs │ ├── module_korok.rs │ ├── root_korok.rs │ ├── struct_korok.rs │ └── unsupported_item_korok.rs └── tests │ ├── from_tokens │ └── mod.rs │ ├── lib.rs │ ├── nested_modules │ ├── crate │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── lib.rs │ │ │ ├── membership.rs │ │ │ └── person.rs │ └── mod.rs │ └── single_crate │ ├── crate │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ ├── membership.rs │ │ └── person.rs │ └── mod.rs ├── codama-macros ├── Cargo.toml ├── src │ └── lib.rs └── tests │ ├── codama_account_derive │ ├── _pass.rs │ ├── multiple_types.fail.rs │ └── multiple_types.fail.stderr │ ├── codama_accounts_derive │ └── _pass.rs │ ├── codama_attribute │ ├── attribute_directive │ │ ├── _pass.rs │ │ ├── invalid_optional.fail.rs │ │ ├── invalid_optional.fail.stderr │ │ ├── invalid_signer.fail.rs │ │ ├── invalid_signer.fail.stderr │ │ ├── invalid_writable.fail.rs │ │ ├── invalid_writable.fail.stderr │ │ ├── name_missing.fail.rs │ │ └── name_missing.fail.stderr │ ├── encoding_directive │ │ ├── _pass.rs │ │ ├── invalid_encoding.fail.rs │ │ └── invalid_encoding.fail.stderr │ ├── error_directive │ │ ├── _pass.rs │ │ ├── invalid_code.fail.rs │ │ ├── invalid_code.fail.stderr │ │ ├── invalid_message.fail.rs │ │ ├── invalid_message.fail.stderr │ │ ├── nothing_provided.fail.rs │ │ ├── nothing_provided.fail.stderr │ │ ├── too_many_codes.fail.rs │ │ ├── too_many_codes.fail.stderr │ │ ├── too_many_messages.fail.rs │ │ └── too_many_messages.fail.stderr │ ├── explicit_path.pass.rs │ ├── fixed_size_directive │ │ ├── _pass.rs │ │ ├── invalid_size.fail.rs │ │ └── invalid_size.fail.stderr │ ├── implicit_path.pass.rs │ ├── on_any_item.fail.rs │ ├── on_any_item.fail.stderr │ ├── on_any_item.pass.rs │ ├── on_fields.fail.rs │ ├── on_fields.fail.stderr │ ├── on_fields.pass.rs │ ├── size_prefix_directive │ │ ├── _pass.rs │ │ ├── invalid_size.fail.rs │ │ └── invalid_size.fail.stderr │ ├── type_directive │ │ ├── double_type.fail.rs │ │ ├── double_type.fail.stderr │ │ ├── no_type.fail.rs │ │ ├── no_type.fail.stderr │ │ ├── unrecognized_type.fail.rs │ │ └── unrecognized_type.fail.stderr │ ├── type_nodes │ │ ├── boolean_type_node │ │ │ ├── _pass.rs │ │ │ ├── size_already_set.fail.rs │ │ │ ├── size_already_set.fail.stderr │ │ │ ├── unrecognized_attribute.fail.rs │ │ │ ├── unrecognized_attribute.fail.stderr │ │ │ ├── unrecognized_type.fail.rs │ │ │ └── unrecognized_type.fail.stderr │ │ ├── fixed_size_type_node │ │ │ ├── _pass.rs │ │ │ ├── size_already_set.fail.rs │ │ │ ├── size_already_set.fail.stderr │ │ │ ├── size_missing.fail.rs │ │ │ ├── size_missing.fail.stderr │ │ │ ├── type_already_set.fail.rs │ │ │ ├── type_already_set.fail.stderr │ │ │ ├── type_missing.fail.rs │ │ │ └── type_missing.fail.stderr │ │ ├── number_type_node │ │ │ ├── _pass.rs │ │ │ ├── endian_already_set.fail.rs │ │ │ ├── endian_already_set.fail.stderr │ │ │ ├── format_already_set.fail.rs │ │ │ ├── format_already_set.fail.stderr │ │ │ ├── format_missing.fail.rs │ │ │ ├── format_missing.fail.stderr │ │ │ ├── invalid_endian.fail.rs │ │ │ ├── invalid_endian.fail.stderr │ │ │ ├── invalid_format.fail.rs │ │ │ ├── invalid_format.fail.stderr │ │ │ ├── unrecognized_attribute.fail.rs │ │ │ └── unrecognized_attribute.fail.stderr │ │ ├── public_key_type_node │ │ │ ├── _pass.rs │ │ │ ├── with_input.fail.rs │ │ │ └── with_input.fail.stderr │ │ └── string_type_node │ │ │ ├── _pass.rs │ │ │ ├── encoding_already_set.fail.rs │ │ │ ├── encoding_already_set.fail.stderr │ │ │ ├── invalid_encoding.fail.rs │ │ │ ├── invalid_encoding.fail.stderr │ │ │ ├── unrecognized_attribute.fail.rs │ │ │ └── unrecognized_attribute.fail.stderr │ └── values_nodes │ │ ├── boolean_value_node │ │ └── _pass.rs │ │ ├── number_value_node │ │ └── _pass.rs │ │ ├── payer_value_node │ │ ├── _pass.rs │ │ ├── with_input.fail.rs │ │ └── with_input.fail.stderr │ │ ├── public_key_value_node │ │ ├── _pass.rs │ │ ├── invalid_input.fail.rs │ │ ├── invalid_input.fail.stderr │ │ ├── no_input.fail.rs │ │ ├── no_input.fail.stderr │ │ ├── too_many_inputs.fail.rs │ │ └── too_many_inputs.fail.stderr │ │ ├── string_value_node │ │ └── _pass.rs │ │ └── sysvar │ │ ├── _pass.rs │ │ ├── invalid_input.fail.rs │ │ ├── invalid_input.fail.stderr │ │ ├── no_input.fail.rs │ │ ├── no_input.fail.stderr │ │ ├── too_many_inputs.fail.rs │ │ ├── too_many_inputs.fail.stderr │ │ ├── unrecognized_sysvar.fail.rs │ │ └── unrecognized_sysvar.fail.stderr │ ├── codama_errors_derive │ └── _pass.rs │ ├── codama_instruction_derive │ ├── _pass.rs │ ├── multiple_types.fail.rs │ └── multiple_types.fail.stderr │ ├── codama_instructions_derive │ └── _pass.rs │ ├── codama_type_derive │ ├── _pass.rs │ ├── multiple_types.fail.rs │ └── multiple_types.fail.stderr │ └── mod.rs ├── codama-nodes ├── .gitignore ├── Cargo.toml ├── derive │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ ├── nestable_type_node.rs │ │ ├── node.rs │ │ ├── node_union.rs │ │ ├── registered_nodes.rs │ │ ├── type_node.rs │ │ └── utils.rs ├── src │ ├── account_node.rs │ ├── contextual_value_nodes │ │ ├── account_bump_value_node.rs │ │ ├── account_value_node.rs │ │ ├── argument_value_node.rs │ │ ├── conditional_value_node.rs │ │ ├── contextual_value_node.rs │ │ ├── identity_value_node.rs │ │ ├── mod.rs │ │ ├── payer_value_node.rs │ │ ├── pda_seed_value_node.rs │ │ ├── pda_value_node.rs │ │ ├── program_id_value_node.rs │ │ └── resolver_value_node.rs │ ├── count_nodes │ │ ├── count_node.rs │ │ ├── fixed_count_node.rs │ │ ├── mod.rs │ │ ├── prefixed_count_node.rs │ │ └── remainder_count_node.rs │ ├── defined_type_node.rs │ ├── discriminator_nodes │ │ ├── constant_discriminator_node.rs │ │ ├── discriminator_node.rs │ │ ├── field_discriminator_node.rs │ │ ├── mod.rs │ │ └── size_discriminator_node.rs │ ├── error_node.rs │ ├── instruction_account_node.rs │ ├── instruction_argument_node.rs │ ├── instruction_byte_delta_node.rs │ ├── instruction_node.rs │ ├── instruction_remaining_accounts_node.rs │ ├── lib.rs │ ├── link_nodes │ │ ├── account_link_node.rs │ │ ├── defined_type_link_node.rs │ │ ├── instruction_account_link_node.rs │ │ ├── instruction_argument_link_node.rs │ │ ├── instruction_link_node.rs │ │ ├── link_node.rs │ │ ├── mod.rs │ │ ├── pda_link_node.rs │ │ └── program_link_node.rs │ ├── node.rs │ ├── pda_node.rs │ ├── pda_seed_nodes │ │ ├── constant_pda_seed_node.rs │ │ ├── mod.rs │ │ ├── pda_seed_node.rs │ │ └── variable_pda_seed_node.rs │ ├── program_node.rs │ ├── root_node.rs │ ├── shared │ │ ├── bytes_encoding.rs │ │ ├── camel_case_string.rs │ │ ├── default_value_strategy.rs │ │ ├── docs.rs │ │ ├── instruction_input_value_node.rs │ │ ├── is_account_signer.rs │ │ └── mod.rs │ ├── traits.rs │ ├── type_nodes │ │ ├── amount_type_node.rs │ │ ├── array_type_node.rs │ │ ├── boolean_type_node.rs │ │ ├── bytes_type_node.rs │ │ ├── date_time_type_node.rs │ │ ├── enum_empty_variant_type_node.rs │ │ ├── enum_struct_variant_type_node.rs │ │ ├── enum_tuple_variant_type_node.rs │ │ ├── enum_type_node.rs │ │ ├── enum_variant_type_node.rs │ │ ├── fixed_size_type_node.rs │ │ ├── hidden_prefix_type_node.rs │ │ ├── hidden_suffix_type_node.rs │ │ ├── map_type_node.rs │ │ ├── mod.rs │ │ ├── nested_type_leaf.rs │ │ ├── nested_type_node.rs │ │ ├── number_type_node.rs │ │ ├── option_type_node.rs │ │ ├── post_offset_type_node.rs │ │ ├── pre_offset_type_node.rs │ │ ├── public_key_type_node.rs │ │ ├── remainder_option_type_node.rs │ │ ├── sentinel_type_node.rs │ │ ├── set_type_node.rs │ │ ├── size_prefix_type_node.rs │ │ ├── sol_amount_type_node.rs │ │ ├── string_type_node.rs │ │ ├── struct_field_type_node.rs │ │ ├── struct_type_node.rs │ │ ├── traits.rs │ │ ├── tuple_type_node.rs │ │ ├── type_node.rs │ │ └── zeroable_option_type_node.rs │ └── value_nodes │ │ ├── array_value_node.rs │ │ ├── boolean_value_node.rs │ │ ├── bytes_value_node.rs │ │ ├── constant_value_node.rs │ │ ├── enum_value_node.rs │ │ ├── map_entry_value_node.rs │ │ ├── map_value_node.rs │ │ ├── mod.rs │ │ ├── none_value_node.rs │ │ ├── number_value_node.rs │ │ ├── public_key_value_node.rs │ │ ├── set_value_node.rs │ │ ├── some_value_node.rs │ │ ├── string_value_node.rs │ │ ├── struct_field_value_node.rs │ │ ├── struct_value_node.rs │ │ ├── tuple_value_node.rs │ │ └── value_node.rs └── tests-derive │ ├── Cargo.toml │ └── tests │ ├── mod.rs │ ├── node │ ├── generic.rs │ └── simple.rs │ ├── node_union │ ├── boxed.rs │ ├── generic.rs │ └── simple.rs │ └── registered_nodes │ ├── from_registered.pass.rs │ ├── from_standalone.pass.rs │ ├── simple.fail.rs │ ├── simple.fail.stderr │ └── simple.pass.rs ├── codama-stores ├── .gitignore ├── Cargo.toml ├── src │ ├── crate_store.rs │ ├── file_module_store.rs │ ├── lib.rs │ └── root_store.rs └── tests │ ├── from_tokens │ └── mod.rs │ ├── lib.rs │ ├── nested_modules │ ├── crate │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── lib.rs │ │ │ ├── membership.rs │ │ │ └── person.rs │ └── mod.rs │ └── single_crate │ ├── crate │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ ├── membership.rs │ │ └── person.rs │ └── mod.rs ├── codama-syn-helpers ├── .gitignore ├── Cargo.toml ├── src │ ├── extensions │ │ ├── attribute.rs │ │ ├── derive_input.rs │ │ ├── expr.rs │ │ ├── fields.rs │ │ ├── file.rs │ │ ├── generics.rs │ │ ├── item.rs │ │ ├── meta_list.rs │ │ ├── mod.rs │ │ ├── parse_buffer.rs │ │ ├── path.rs │ │ ├── to_tokens.rs │ │ └── type.rs │ ├── lib.rs │ └── meta.rs └── tests-macros │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── src │ └── lib.rs │ └── tests │ ├── as_expr │ ├── _pass.rs │ ├── from_path_list.fail.rs │ ├── from_path_list.fail.stderr │ ├── from_path_value.fail.rs │ ├── from_path_value.fail.stderr │ ├── from_verbatim.fail.rs │ └── from_verbatim.fail.stderr │ ├── as_path │ ├── _pass.rs │ ├── from_expr.fail.rs │ ├── from_expr.fail.stderr │ ├── from_path_list.fail.rs │ ├── from_path_list.fail.stderr │ ├── from_path_value.fail.rs │ ├── from_path_value.fail.stderr │ ├── from_verbatim.fail.rs │ └── from_verbatim.fail.stderr │ ├── as_path_list │ ├── _pass.rs │ ├── from_expr.fail.rs │ ├── from_expr.fail.stderr │ ├── from_path.fail.rs │ ├── from_path.fail.stderr │ ├── from_path_value.fail.rs │ ├── from_path_value.fail.stderr │ ├── from_verbatim.fail.rs │ └── from_verbatim.fail.stderr │ ├── as_path_value │ ├── _pass.rs │ ├── from_expr.fail.rs │ ├── from_expr.fail.stderr │ ├── from_path.fail.rs │ ├── from_path.fail.stderr │ ├── from_path_list.fail.rs │ ├── from_path_list.fail.stderr │ ├── from_verbatim.fail.rs │ └── from_verbatim.fail.stderr │ ├── as_verbatim │ ├── _pass.rs │ ├── from_expr.fail.rs │ ├── from_expr.fail.stderr │ ├── from_path.fail.rs │ ├── from_path.fail.stderr │ ├── from_path_list.fail.rs │ ├── from_path_list.fail.stderr │ ├── from_path_value.fail.rs │ └── from_path_value.fail.stderr │ └── mod.rs └── codama ├── .gitignore ├── Cargo.toml ├── src ├── codama.rs └── lib.rs └── tests ├── lib.rs ├── membership ├── crate │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ ├── membership.rs │ │ └── person.rs └── mod.rs └── system ├── crate ├── .gitignore ├── Cargo.toml └── src │ ├── errors.rs │ ├── instructions.rs │ ├── lib.rs │ └── state.rs └── mod.rs /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Main 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | pull_request: 7 | 8 | env: 9 | RUSTFLAGS: "-Dwarnings" 10 | 11 | jobs: 12 | lint: 13 | name: Format and Lint Crates 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Git Checkout 17 | uses: actions/checkout@v4 18 | 19 | - name: Cache Dependencies 20 | uses: Swatinem/rust-cache@v2 21 | 22 | - name: Rustup install nightly 23 | run: rustup toolchain install nightly 24 | 25 | - name: Rustup install rustfmt 26 | run: rustup component add rustfmt --toolchain nightly 27 | 28 | - name: Run Cargo fmt 29 | run: cargo +nightly fmt --all -- --check 30 | 31 | - name: Run Cargo clippy 32 | run: cargo clippy --all-targets --all-features 33 | 34 | test: 35 | name: Test Crates 36 | runs-on: ubuntu-latest 37 | steps: 38 | - name: Git Checkout 39 | uses: actions/checkout@v4 40 | 41 | - name: Cache Dependencies 42 | uses: Swatinem/rust-cache@v2 43 | 44 | - name: Run Cargo test 45 | run: cargo test --all-features 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = [ 4 | "codama", 5 | "codama-attributes", 6 | "codama-errors", 7 | "codama-koroks", 8 | "codama-korok-plugins", 9 | "codama-korok-visitors", 10 | "codama-macros", 11 | "codama-nodes", 12 | "codama-nodes/derive", 13 | "codama-nodes/tests-derive", 14 | "codama-stores", 15 | "codama-syn-helpers", 16 | "codama-syn-helpers/tests-macros", 17 | ] 18 | 19 | [workspace.package] 20 | edition = "2021" 21 | license = "Apache-2.0" 22 | repository = "https://github.com/codama-idl/codama-rs" 23 | -------------------------------------------------------------------------------- /codama-attributes/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-attributes/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama-attributes" 3 | description = "Codama attributes definitions and parsers" 4 | version = "0.4.0" 5 | repository = { workspace = true } 6 | edition = { workspace = true } 7 | license = { workspace = true } 8 | 9 | [dependencies] 10 | codama-errors = { version = "0.4.0", path = "../codama-errors" } 11 | codama-nodes = { version = "0.4.0", path = "../codama-nodes" } 12 | codama-syn-helpers = { version = "0.4.0", path = "../codama-syn-helpers" } 13 | derive_more = { version = "1.0", features = ["from"] } 14 | proc-macro2 = "1.0" 15 | quote = "1.0" 16 | syn = { version = "2.0", features = ["extra-traits", "full"] } 17 | -------------------------------------------------------------------------------- /codama-attributes/src/attribute_context.rs: -------------------------------------------------------------------------------- 1 | use derive_more::derive::From; 2 | 3 | #[derive(Debug, PartialEq, From)] 4 | pub enum AttributeContext<'a> { 5 | File(&'a syn::File), 6 | Item(&'a syn::Item), 7 | Variant(&'a syn::Variant), 8 | Field(&'a syn::Field), 9 | } 10 | -------------------------------------------------------------------------------- /codama-attributes/src/codama_directives/mod.rs: -------------------------------------------------------------------------------- 1 | mod type_nodes; 2 | mod value_nodes; 3 | 4 | mod account_directive; 5 | mod codama_directive; 6 | mod default_value_directive; 7 | mod encoding_directive; 8 | mod error_directive; 9 | mod fixed_size_directive; 10 | mod size_prefix_directive; 11 | mod type_directive; 12 | 13 | pub use account_directive::*; 14 | pub use codama_directive::*; 15 | pub use default_value_directive::*; 16 | pub use encoding_directive::*; 17 | pub use error_directive::*; 18 | pub use fixed_size_directive::*; 19 | pub use size_prefix_directive::*; 20 | pub use type_directive::*; 21 | -------------------------------------------------------------------------------- /codama-attributes/src/codama_directives/type_nodes/mod.rs: -------------------------------------------------------------------------------- 1 | mod boolean_type_node; 2 | mod fixed_size_type_node; 3 | mod number_type_node; 4 | mod public_key_type_node; 5 | mod string_type_node; 6 | mod type_node; 7 | -------------------------------------------------------------------------------- /codama-attributes/src/codama_directives/type_nodes/public_key_type_node.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::FromMeta; 2 | use codama_nodes::PublicKeyTypeNode; 3 | use codama_syn_helpers::{extensions::*, Meta}; 4 | 5 | impl FromMeta for PublicKeyTypeNode { 6 | fn from_meta(meta: &Meta) -> syn::Result { 7 | if !meta.is_path_or_empty_list() { 8 | return Err(meta.error("public_key does not accept any input")); 9 | } 10 | Ok(Self::new()) 11 | } 12 | } 13 | 14 | #[cfg(test)] 15 | mod tests { 16 | use super::*; 17 | use crate::{assert_type, assert_type_err}; 18 | 19 | #[test] 20 | fn ok() { 21 | assert_type!({ public_key }, PublicKeyTypeNode::new().into()); 22 | assert_type!({ public_key() }, PublicKeyTypeNode::new().into()); 23 | } 24 | 25 | #[test] 26 | fn unexpected_input() { 27 | assert_type_err!( 28 | { public_key(unexpected) }, 29 | "public_key does not accept any input" 30 | ); 31 | assert_type_err!( 32 | { public_key(foo = 42) }, 33 | "public_key does not accept any input" 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /codama-attributes/src/codama_directives/type_nodes/type_node.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::FromMeta; 2 | use codama_nodes::{ 3 | BooleanTypeNode, FixedSizeTypeNode, NumberTypeNode, PublicKeyTypeNode, StringTypeNode, TypeNode, 4 | }; 5 | use codama_syn_helpers::{extensions::*, Meta}; 6 | 7 | impl FromMeta for TypeNode { 8 | fn from_meta(meta: &Meta) -> syn::Result { 9 | match meta.path_str().as_str() { 10 | "boolean" => BooleanTypeNode::from_meta(meta).map(Self::from), 11 | "fixed_size" => FixedSizeTypeNode::from_meta(meta).map(Self::from), 12 | "number" => NumberTypeNode::from_meta(meta).map(Self::from), 13 | "public_key" => PublicKeyTypeNode::from_meta(meta).map(Self::from), 14 | "string" => StringTypeNode::from_meta(meta).map(Self::from), 15 | _ => Err(meta.error("unrecognized type")), 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /codama-attributes/src/codama_directives/value_nodes/boolean_value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::FromMeta; 2 | use codama_nodes::BooleanValueNode; 3 | use codama_syn_helpers::{extensions::*, Meta}; 4 | 5 | impl FromMeta for BooleanValueNode { 6 | fn from_meta(meta: &Meta) -> syn::Result { 7 | let value = meta.as_expr()?.as_bool()?; 8 | Ok(BooleanValueNode::new(value)) 9 | } 10 | } 11 | 12 | #[cfg(test)] 13 | mod tests { 14 | use super::*; 15 | use crate::assert_value; 16 | 17 | #[test] 18 | fn ok() { 19 | assert_value!({ true }, BooleanValueNode::new(true).into()); 20 | assert_value!({ false }, BooleanValueNode::new(false).into()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /codama-attributes/src/codama_directives/value_nodes/instruction_input_value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::FromMeta; 2 | use codama_nodes::{InstructionInputValueNode, PayerValueNode, ValueNode}; 3 | use codama_syn_helpers::Meta; 4 | 5 | impl FromMeta for InstructionInputValueNode { 6 | fn from_meta(meta: &Meta) -> syn::Result { 7 | match meta.path_str().as_str() { 8 | "payer" => PayerValueNode::from_meta(meta).map(Self::from), 9 | _ => ValueNode::from_meta(meta).map(Self::from), 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /codama-attributes/src/codama_directives/value_nodes/mod.rs: -------------------------------------------------------------------------------- 1 | mod boolean_value_node; 2 | mod instruction_input_value_node; 3 | mod number_value_node; 4 | mod payer_value_node; 5 | mod public_key_value_node; 6 | mod string_value_node; 7 | mod sysvar; 8 | mod value_node; 9 | -------------------------------------------------------------------------------- /codama-attributes/src/codama_directives/value_nodes/number_value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::FromMeta; 2 | use codama_nodes::{Number, NumberValueNode}; 3 | use codama_syn_helpers::{extensions::*, Meta}; 4 | 5 | impl FromMeta for NumberValueNode { 6 | fn from_meta(meta: &Meta) -> syn::Result { 7 | let expr = meta.as_expr()?; 8 | let value = expr 9 | .as_unsigned_integer::() 10 | .map(Number::from) 11 | .or(expr.as_signed_integer::().map(Number::from)) 12 | .or(expr.as_float::().map(Number::from))?; 13 | Ok(NumberValueNode::new(value)) 14 | } 15 | } 16 | 17 | #[cfg(test)] 18 | mod tests { 19 | use super::*; 20 | use crate::assert_value; 21 | 22 | #[test] 23 | fn ok() { 24 | assert_value!({ 42 }, NumberValueNode::new(42u64).into()); 25 | assert_value!({ -42 }, NumberValueNode::new(-42i64).into()); 26 | assert_value!({ 1.5 }, NumberValueNode::new(1.5f64).into()); 27 | assert_value!({ -1.5 }, NumberValueNode::new(-1.5f64).into()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /codama-attributes/src/codama_directives/value_nodes/payer_value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::FromMeta; 2 | use codama_nodes::PayerValueNode; 3 | use codama_syn_helpers::{extensions::*, Meta}; 4 | 5 | impl FromMeta for PayerValueNode { 6 | fn from_meta(meta: &Meta) -> syn::Result { 7 | if !meta.is_path_or_empty_list() { 8 | return Err(meta.error("payer value does not accept any input")); 9 | } 10 | Ok(Self::new()) 11 | } 12 | } 13 | 14 | #[cfg(test)] 15 | mod tests { 16 | use super::*; 17 | use crate::{assert_value, assert_value_err}; 18 | 19 | #[test] 20 | fn ok() { 21 | assert_value!({ payer }, PayerValueNode::new().into()); 22 | assert_value!({ payer() }, PayerValueNode::new().into()); 23 | } 24 | 25 | #[test] 26 | fn unexpected_input() { 27 | assert_value_err!( 28 | { payer(unexpected) }, 29 | "payer value does not accept any input" 30 | ); 31 | assert_value_err!({ payer(foo = 42) }, "payer value does not accept any input"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /codama-attributes/src/codama_directives/value_nodes/public_key_value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::{FromMeta, SetOnce}; 2 | use codama_nodes::PublicKeyValueNode; 3 | use codama_syn_helpers::{extensions::*, Meta}; 4 | 5 | impl FromMeta for PublicKeyValueNode { 6 | fn from_meta(meta: &Meta) -> syn::Result { 7 | let pv = meta.as_path_list()?; 8 | let mut public_key = SetOnce::::new("public_key"); 9 | pv.each(|ref meta| { 10 | let value = meta.as_expr()?.as_string()?; 11 | public_key.set(value, meta) 12 | })?; 13 | Ok(Self::new(public_key.take(meta)?)) 14 | } 15 | } 16 | 17 | #[cfg(test)] 18 | mod tests { 19 | use super::*; 20 | use crate::{assert_value, assert_value_err}; 21 | 22 | #[test] 23 | fn ok() { 24 | assert_value!( 25 | { public_key("1111") }, 26 | PublicKeyValueNode::new("1111").into() 27 | ); 28 | assert_value!( 29 | { public_key("2222") }, 30 | PublicKeyValueNode::new("2222").into() 31 | ); 32 | } 33 | 34 | #[test] 35 | fn invalid_input() { 36 | assert_value_err!({ public_key(unexpected) }, "expected a string"); 37 | assert_value_err!({ public_key(foo = 42) }, "expected a valid expression"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /codama-attributes/src/codama_directives/value_nodes/string_value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::FromMeta; 2 | use codama_nodes::StringValueNode; 3 | use codama_syn_helpers::{extensions::*, Meta}; 4 | 5 | impl FromMeta for StringValueNode { 6 | fn from_meta(meta: &Meta) -> syn::Result { 7 | let value = meta.as_expr()?.as_string()?; 8 | Ok(StringValueNode::new(value)) 9 | } 10 | } 11 | 12 | #[cfg(test)] 13 | mod tests { 14 | use super::*; 15 | use crate::assert_value; 16 | 17 | #[test] 18 | fn ok() { 19 | assert_value!({ "hello" }, StringValueNode::new("hello").into()); 20 | assert_value!({ "world" }, StringValueNode::new("world").into()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /codama-attributes/src/codama_directives/value_nodes/value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::codama_directives::value_nodes::sysvar::public_key_value_node_from_sysvar; 2 | use crate::utils::FromMeta; 3 | use codama_nodes::{ 4 | BooleanValueNode, NumberValueNode, PublicKeyValueNode, StringValueNode, ValueNode, 5 | }; 6 | use codama_syn_helpers::{extensions::*, Meta}; 7 | 8 | impl FromMeta for ValueNode { 9 | fn from_meta(meta: &Meta) -> syn::Result { 10 | match meta.path_str().as_str() { 11 | "public_key" => PublicKeyValueNode::from_meta(meta).map(Self::from), 12 | "sysvar" => public_key_value_node_from_sysvar(meta).map(Self::from), 13 | _ => BooleanValueNode::from_meta(meta) 14 | .map(Self::from) 15 | .or(StringValueNode::from_meta(meta).map(Self::from)) 16 | .or(NumberValueNode::from_meta(meta).map(Self::from)) 17 | .map_err(|_| meta.error("unrecognized value")), 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /codama-attributes/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod utils; 2 | 3 | mod attribute; 4 | mod attribute_context; 5 | mod attributes; 6 | mod codama_attribute; 7 | mod codama_directives; 8 | mod derive_attribute; 9 | mod repr_attribute; 10 | mod try_from_filter; 11 | mod unsupported_attribute; 12 | 13 | pub use attribute::*; 14 | pub use attribute_context::*; 15 | pub use attributes::*; 16 | pub use codama_attribute::*; 17 | pub use codama_directives::*; 18 | pub use derive_attribute::*; 19 | pub use repr_attribute::*; 20 | pub use try_from_filter::*; 21 | pub use unsupported_attribute::*; 22 | -------------------------------------------------------------------------------- /codama-attributes/src/try_from_filter.rs: -------------------------------------------------------------------------------- 1 | pub trait TryFromFilter<'a, T>: Sized { 2 | fn filter(t: T) -> Option<&'a Self>; 3 | } 4 | 5 | impl<'a, T: 'a, U> TryFromFilter<'a, U> for T 6 | where 7 | &'a T: TryFrom, 8 | { 9 | fn filter(u: U) -> Option<&'a T> { 10 | <&'a T>::try_from(u).ok() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /codama-attributes/src/unsupported_attribute.rs: -------------------------------------------------------------------------------- 1 | use crate::Attribute; 2 | use codama_errors::CodamaError; 3 | 4 | #[derive(Debug, PartialEq)] 5 | pub struct UnsupportedAttribute<'a> { 6 | pub ast: &'a syn::Attribute, 7 | } 8 | 9 | impl<'a> UnsupportedAttribute<'a> { 10 | pub fn new(ast: &'a syn::Attribute) -> Self { 11 | Self { ast } 12 | } 13 | } 14 | 15 | impl<'a> TryFrom<&'a Attribute<'a>> for &'a UnsupportedAttribute<'a> { 16 | type Error = CodamaError; 17 | 18 | fn try_from(attribute: &'a Attribute) -> Result { 19 | match attribute { 20 | Attribute::Unsupported(a) => Ok(a), 21 | _ => Err(CodamaError::InvalidAttribute { 22 | expected: "unsupported".to_string(), 23 | actual: attribute.name(), 24 | }), 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /codama-attributes/src/utils/from_meta.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes::IsAccountSigner; 2 | use codama_syn_helpers::{extensions::*, Meta}; 3 | use syn::Expr; 4 | 5 | pub trait FromMeta 6 | where 7 | Self: Sized, 8 | { 9 | fn from_meta(meta: &Meta) -> syn::Result; 10 | } 11 | 12 | impl FromMeta for String { 13 | fn from_meta(meta: &Meta) -> syn::Result { 14 | meta.as_path_value()?.value.as_expr()?.as_string() 15 | } 16 | } 17 | 18 | impl FromMeta for bool { 19 | fn from_meta(meta: &Meta) -> syn::Result { 20 | match meta { 21 | Meta::Expr(Expr::Path(_)) => Ok(true), 22 | _ => meta.as_path_value()?.value.as_expr()?.as_bool(), 23 | } 24 | } 25 | } 26 | 27 | impl FromMeta for IsAccountSigner { 28 | fn from_meta(meta: &Meta) -> syn::Result { 29 | match meta { 30 | Meta::Expr(Expr::Path(_)) => Ok(Self::True), 31 | _ => { 32 | let expr = meta.as_path_value()?.value.as_expr()?; 33 | if let Ok(value) = expr.as_bool() { 34 | return Ok(value.into()); 35 | } 36 | match expr.as_string() { 37 | Ok(value) if value == "either" => Ok(Self::Either), 38 | _ => Err(expr.error("expected boolean or `\"either\"`")), 39 | } 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /codama-attributes/src/utils/macros.rs: -------------------------------------------------------------------------------- 1 | #[macro_export] 2 | macro_rules! assert_type { 3 | ({$($attr:tt)*}, $expected:expr) => { 4 | { 5 | let meta: codama_syn_helpers::Meta = syn::parse_quote! { type = $($attr)* }; 6 | let node = $crate::TypeDirective::parse(&meta).unwrap().node; 7 | assert_eq!(node, $expected); 8 | } 9 | }; 10 | } 11 | 12 | #[macro_export] 13 | macro_rules! assert_type_err { 14 | ({$($attr:tt)*}, $expected:expr) => { 15 | { 16 | let meta: codama_syn_helpers::Meta = syn::parse_quote! { type = $($attr)* }; 17 | let message = $crate::TypeDirective::parse(&meta).unwrap_err().to_string(); 18 | assert_eq!(message, $expected); 19 | } 20 | }; 21 | } 22 | 23 | #[macro_export] 24 | macro_rules! assert_value { 25 | ({$($attr:tt)*}, $expected:expr) => { 26 | { 27 | let meta: codama_syn_helpers::Meta = syn::parse_quote! { default_value = $($attr)* }; 28 | let node = $crate::DefaultValueDirective::parse(&meta).unwrap().node; 29 | assert_eq!(node, $expected); 30 | } 31 | }; 32 | } 33 | 34 | #[macro_export] 35 | macro_rules! assert_value_err { 36 | ({$($attr:tt)*}, $expected:expr) => { 37 | { 38 | let meta: codama_syn_helpers::Meta = syn::parse_quote! { default_value = $($attr)* }; 39 | let message = $crate::DefaultValueDirective::parse(&meta).unwrap_err().to_string(); 40 | assert_eq!(message, $expected); 41 | } 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /codama-attributes/src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | mod from_meta; 2 | mod macros; 3 | mod set_once; 4 | 5 | pub use from_meta::*; 6 | pub use set_once::*; 7 | -------------------------------------------------------------------------------- /codama-attributes/src/utils/set_once.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers::extensions::*; 2 | use quote::ToTokens; 3 | 4 | pub struct SetOnce { 5 | value: Option, 6 | ident: &'static str, 7 | is_set: bool, 8 | } 9 | 10 | impl SetOnce { 11 | pub fn new(ident: &'static str) -> Self { 12 | Self { 13 | value: None, 14 | ident, 15 | is_set: false, 16 | } 17 | } 18 | 19 | pub fn initial_value(mut self, value: T) -> Self { 20 | self.value = Some(value); 21 | self 22 | } 23 | 24 | pub fn set(&mut self, value: T, tokens: U) -> syn::Result<()> { 25 | if self.is_set { 26 | return Err(tokens.error(format!("{} is already set", self.ident))); 27 | } 28 | self.is_set = true; 29 | self.value = Some(value); 30 | Ok(()) 31 | } 32 | 33 | pub fn option(self) -> Option { 34 | self.value 35 | } 36 | 37 | pub fn take(mut self, tokens: U) -> syn::Result { 38 | match self.value.take() { 39 | Some(value) => Ok(value), 40 | None => Err(tokens.error(format!("{} is missing", self.ident))), 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /codama-errors/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-errors/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama-errors" 3 | description = "Errors and result types for Codama" 4 | version = "0.4.0" 5 | repository = { workspace = true } 6 | edition = { workspace = true } 7 | license = { workspace = true } 8 | 9 | [dependencies] 10 | cargo_toml = "0.20" 11 | proc-macro2 = "1.0" 12 | serde_json = "1.0" 13 | syn = { version = "2.0", features = ["extra-traits", "full"] } 14 | thiserror = "2.0" 15 | -------------------------------------------------------------------------------- /codama-errors/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod combine_errors; 2 | mod errors; 3 | 4 | pub use combine_errors::*; 5 | pub use errors::*; 6 | -------------------------------------------------------------------------------- /codama-errors/tests/compilation.rs: -------------------------------------------------------------------------------- 1 | use codama_errors::CodamaError; 2 | use proc_macro2::TokenStream; 3 | 4 | #[test] 5 | fn from_syn_error() { 6 | let error: CodamaError = 7 | syn::Error::new_spanned(TokenStream::new(), "Could not parse Rust code").into(); 8 | assert!(matches!(error, CodamaError::Compilation(_))); 9 | } 10 | 11 | #[test] 12 | fn display() { 13 | let error: CodamaError = 14 | syn::Error::new_spanned(TokenStream::new(), "Could not parse Rust code").into(); 15 | assert_eq!(error.to_string(), "Could not parse Rust code"); 16 | } 17 | -------------------------------------------------------------------------------- /codama-errors/tests/filesystem.rs: -------------------------------------------------------------------------------- 1 | use codama_errors::CodamaError; 2 | use std::io::ErrorKind::NotFound; 3 | 4 | #[test] 5 | fn from_io_error() { 6 | let error: CodamaError = std::io::Error::new(NotFound, "Could not find file `foo.rs`").into(); 7 | assert!(matches!(error, CodamaError::Filesystem(_))); 8 | } 9 | 10 | #[test] 11 | fn display() { 12 | let error: CodamaError = std::io::Error::new(NotFound, "Could not find file `foo.rs`").into(); 13 | assert_eq!(error.to_string(), "Could not find file `foo.rs`"); 14 | } 15 | -------------------------------------------------------------------------------- /codama-errors/tests/invalid_node_conversion.rs: -------------------------------------------------------------------------------- 1 | use codama_errors::CodamaError; 2 | 3 | #[test] 4 | fn display() { 5 | let error = CodamaError::InvalidNodeConversion { 6 | from: "registeredTypeNode".to_string(), 7 | into: "typeNode".to_string(), 8 | }; 9 | assert_eq!( 10 | error.to_string(), 11 | "Could not convert node from `registeredTypeNode` into `typeNode`" 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /codama-errors/tests/manifest.rs: -------------------------------------------------------------------------------- 1 | use codama_errors::CodamaError; 2 | 3 | #[test] 4 | fn from_manifest_error() { 5 | let error: CodamaError = cargo_toml::Error::Other("Your Cargo.toml file is invalid").into(); 6 | assert!(matches!(error, CodamaError::Manifest(_))); 7 | } 8 | 9 | #[test] 10 | fn display() { 11 | let error: CodamaError = cargo_toml::Error::Other("Your Cargo.toml file is invalid").into(); 12 | assert_eq!( 13 | error.to_string(), 14 | "Could not parse Cargo.toml files: Your Cargo.toml file is invalid" 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /codama-korok-plugins/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-korok-plugins/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama-korok-plugins" 3 | description = "Korok plugins definitions" 4 | version = "0.4.0" 5 | repository = { workspace = true } 6 | edition = { workspace = true } 7 | license = { workspace = true } 8 | 9 | [dependencies] 10 | codama-errors = { version = "0.4.0", path = "../codama-errors" } 11 | codama-korok-visitors = { version = "0.4.0", path = "../codama-korok-visitors" } 12 | codama-koroks = { version = "0.4.0", path = "../codama-koroks" } 13 | -------------------------------------------------------------------------------- /codama-korok-plugins/src/default_plugin.rs: -------------------------------------------------------------------------------- 1 | use crate::KorokPlugin; 2 | use codama_errors::CodamaResult; 3 | use codama_korok_visitors::{ 4 | ApplyCodamaTypeAttributesVisitor, CombineModulesVisitor, ComposeVisitor, FilterItemsVisitor, 5 | KorokVisitable, SetAccountsVisitor, SetBorshTypesVisitor, SetDefinedTypesVisitor, 6 | SetErrorsVisitor, SetInstructionsVisitor, SetLinkTypesVisitor, SetProgramMetadataVisitor, 7 | }; 8 | use codama_koroks::KorokTrait; 9 | 10 | pub struct DefaultPlugin; 11 | impl KorokPlugin for DefaultPlugin { 12 | fn run( 13 | &self, 14 | visitable: &mut dyn KorokVisitable, 15 | next: &dyn Fn(&mut dyn KorokVisitable) -> CodamaResult<()>, 16 | ) -> CodamaResult<()> { 17 | next(visitable)?; 18 | visitable.accept(&mut get_default_visitor())?; 19 | Ok(()) 20 | } 21 | } 22 | 23 | pub fn get_default_visitor<'a>() -> ComposeVisitor<'a> { 24 | ComposeVisitor::new() 25 | .with(FilterItemsVisitor::new( 26 | |item| item.attributes().unwrap().has_any_codama_derive(), 27 | ComposeVisitor::new() 28 | .with(SetBorshTypesVisitor::new()) 29 | .with(SetLinkTypesVisitor::new()), 30 | )) 31 | .with(SetProgramMetadataVisitor::new()) 32 | .with(ApplyCodamaTypeAttributesVisitor::new()) 33 | .with(SetDefinedTypesVisitor::new()) 34 | .with(SetAccountsVisitor::new()) 35 | .with(SetInstructionsVisitor::new()) 36 | .with(SetErrorsVisitor::new()) 37 | .with(CombineModulesVisitor::new()) 38 | } 39 | -------------------------------------------------------------------------------- /codama-korok-plugins/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod default_plugin; 2 | mod plugin; 3 | 4 | pub use default_plugin::*; 5 | pub use plugin::*; 6 | -------------------------------------------------------------------------------- /codama-korok-visitors/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-korok-visitors/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama-korok-visitors" 3 | description = "Visitors for Korok trees" 4 | version = "0.4.0" 5 | repository = { workspace = true } 6 | edition = { workspace = true } 7 | license = { workspace = true } 8 | 9 | [dev-dependencies] 10 | proc-macro2 = "1.0" 11 | quote = "1.0" 12 | codama-stores = { path = "../codama-stores", version = "0.4.0" } 13 | 14 | [dependencies] 15 | cargo_toml = "0.20" 16 | codama-attributes = { version = "0.4.0", path = "../codama-attributes" } 17 | codama-errors = { version = "0.4.0", path = "../codama-errors" } 18 | codama-koroks = { version = "0.4.0", path = "../codama-koroks" } 19 | codama-nodes = { version = "0.4.0", path = "../codama-nodes" } 20 | codama-syn-helpers = { version = "0.4.0", path = "../codama-syn-helpers" } 21 | syn = { version = "2.0", features = ["extra-traits", "full"] } 22 | -------------------------------------------------------------------------------- /codama-korok-visitors/src/filter_items_visitor.rs: -------------------------------------------------------------------------------- 1 | use crate::KorokVisitor; 2 | use codama_errors::CodamaResult; 3 | use codama_koroks::ItemKorok; 4 | 5 | pub struct FilterItemsVisitor<'a, F> 6 | where 7 | F: Fn(&ItemKorok) -> bool, 8 | { 9 | pub filter: F, 10 | pub visitor: Box, 11 | } 12 | 13 | impl<'a, F> FilterItemsVisitor<'a, F> 14 | where 15 | F: Fn(&ItemKorok) -> bool, 16 | { 17 | pub fn new(filter: F, visitor: T) -> Self { 18 | Self { 19 | filter, 20 | visitor: Box::new(visitor), 21 | } 22 | } 23 | } 24 | 25 | impl KorokVisitor for FilterItemsVisitor<'_, F> 26 | where 27 | F: Fn(&ItemKorok) -> bool, 28 | { 29 | fn visit_item(&mut self, korok: &mut codama_koroks::ItemKorok) -> CodamaResult<()> { 30 | if (self.filter)(korok) { 31 | self.visitor.visit_item(korok) 32 | } else { 33 | self.visit_children(korok) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /codama-korok-visitors/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod apply_codama_type_attributes_visitor; 2 | mod combine_modules_visitor; 3 | mod combine_types_visitor; 4 | mod compose_visitor; 5 | mod filter_items_visitor; 6 | mod set_accounts_visitor; 7 | mod set_borsh_types_visitor; 8 | mod set_defined_types_visitor; 9 | mod set_errors_visitor; 10 | mod set_instructions_visitors; 11 | mod set_link_types_visitor; 12 | mod set_program_metadata_visitor; 13 | mod uniform_visitor; 14 | mod visitable; 15 | mod visitor; 16 | 17 | pub use apply_codama_type_attributes_visitor::*; 18 | pub use combine_modules_visitor::*; 19 | pub use combine_types_visitor::*; 20 | pub use compose_visitor::*; 21 | pub use filter_items_visitor::*; 22 | pub use set_accounts_visitor::*; 23 | pub use set_borsh_types_visitor::*; 24 | pub use set_defined_types_visitor::*; 25 | pub use set_errors_visitor::*; 26 | pub use set_instructions_visitors::*; 27 | pub use set_link_types_visitor::*; 28 | pub use set_program_metadata_visitor::*; 29 | pub use uniform_visitor::*; 30 | pub use visitable::*; 31 | pub use visitor::*; 32 | -------------------------------------------------------------------------------- /codama-korok-visitors/src/set_defined_types_visitor.rs: -------------------------------------------------------------------------------- 1 | use crate::{CombineTypesVisitor, KorokVisitor}; 2 | use codama_errors::CodamaResult; 3 | 4 | pub struct SetDefinedTypesVisitor { 5 | combine_types: CombineTypesVisitor, 6 | } 7 | 8 | impl Default for SetDefinedTypesVisitor { 9 | fn default() -> Self { 10 | Self { 11 | combine_types: CombineTypesVisitor::strict(), 12 | } 13 | } 14 | } 15 | 16 | impl SetDefinedTypesVisitor { 17 | pub fn new() -> Self { 18 | Self::default() 19 | } 20 | } 21 | 22 | impl KorokVisitor for SetDefinedTypesVisitor { 23 | fn visit_struct(&mut self, korok: &mut codama_koroks::StructKorok) -> CodamaResult<()> { 24 | // Ensure the struct has the `CodamaType` attribute. 25 | if !korok.attributes.has_codama_derive("CodamaType") { 26 | return Ok(()); 27 | }; 28 | 29 | // Create a `DefinedTypeNode` from the struct, if it doesn't already exist. 30 | self.combine_types.visit_struct(korok)?; 31 | 32 | Ok(()) 33 | } 34 | 35 | fn visit_enum(&mut self, korok: &mut codama_koroks::EnumKorok) -> CodamaResult<()> { 36 | // Ensure the enum has the `CodamaType` attribute. 37 | if !korok.attributes.has_codama_derive("CodamaType") { 38 | return Ok(()); 39 | }; 40 | 41 | // Create a `DefinedTypeNode` from the enum, if it doesn't already exist. 42 | self.combine_types.visit_enum(korok)?; 43 | 44 | Ok(()) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /codama-korok-visitors/src/set_link_types_visitor.rs: -------------------------------------------------------------------------------- 1 | use crate::KorokVisitor; 2 | use codama_errors::CodamaResult; 3 | use codama_nodes::DefinedTypeLinkNode; 4 | use codama_syn_helpers::extensions::*; 5 | 6 | #[derive(Default)] 7 | pub struct SetLinkTypesVisitor; 8 | 9 | impl SetLinkTypesVisitor { 10 | pub fn new() -> Self { 11 | Self {} 12 | } 13 | } 14 | 15 | impl KorokVisitor for SetLinkTypesVisitor { 16 | fn visit_field(&mut self, korok: &mut codama_koroks::FieldKorok) -> CodamaResult<()> { 17 | if korok.node.is_some() { 18 | return Ok(()); 19 | } 20 | if let syn::Type::Path(tp) = &korok.ast.ty { 21 | korok.set_type_node(DefinedTypeLinkNode::new(tp.path.last_str()).into()) 22 | } 23 | Ok(()) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/apply_codama_type_attributes_visitor/mod.rs: -------------------------------------------------------------------------------- 1 | mod encoding_directive; 2 | mod fixed_size_directive; 3 | mod size_prefix_directive; 4 | mod type_directive; 5 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/apply_codama_type_attributes_visitor/type_directive.rs: -------------------------------------------------------------------------------- 1 | use codama_errors::CodamaResult; 2 | use codama_korok_visitors::{ApplyCodamaTypeAttributesVisitor, KorokVisitable}; 3 | use codama_koroks::{FieldKorok, StructKorok}; 4 | use codama_nodes::{BooleanTypeNode, StructFieldTypeNode}; 5 | 6 | #[test] 7 | fn it_set_the_node_on_the_korok() -> CodamaResult<()> { 8 | let item: syn::Item = syn::parse_quote! { 9 | #[codama(type = boolean)] 10 | pub struct Membership; 11 | }; 12 | let mut korok = StructKorok::parse(&item)?; 13 | 14 | assert_eq!(korok.node, None); 15 | korok.accept(&mut ApplyCodamaTypeAttributesVisitor::new())?; 16 | assert_eq!(korok.node, Some(BooleanTypeNode::default().into())); 17 | Ok(()) 18 | } 19 | 20 | #[test] 21 | fn it_wraps_the_node_in_a_struct_field_for_named_field_koroks() -> CodamaResult<()> { 22 | let item: syn::Field = syn::parse_quote! { 23 | #[codama(type = boolean)] 24 | pub is_valid: u8 25 | }; 26 | let mut korok = FieldKorok::parse(&item)?; 27 | 28 | assert_eq!(korok.node, None); 29 | korok.accept(&mut ApplyCodamaTypeAttributesVisitor::new())?; 30 | assert_eq!( 31 | korok.node, 32 | Some(StructFieldTypeNode::new("isValid", BooleanTypeNode::default()).into()) 33 | ); 34 | Ok(()) 35 | } 36 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/combine_modules_visitor/mod.rs: -------------------------------------------------------------------------------- 1 | mod defined_type_node; 2 | mod program_node; 3 | mod root_node; 4 | mod utils; 5 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/combine_types_visitor/mod.rs: -------------------------------------------------------------------------------- 1 | mod enum_korok; 2 | mod enum_variant_korok; 3 | mod fields_korok; 4 | mod struct_korok; 5 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/compose_visitor.rs: -------------------------------------------------------------------------------- 1 | use codama_errors::CodamaResult; 2 | use codama_korok_visitors::{ComposeVisitor, KorokVisitable, KorokVisitor, UniformVisitor}; 3 | use codama_koroks::{FieldKorok, KorokTrait, StructKorok}; 4 | use codama_nodes::PublicKeyTypeNode; 5 | 6 | #[test] 7 | fn it_returns_a_single_visitor_from_multiple_visitors() -> CodamaResult<()> { 8 | let item: syn::Item = syn::parse_quote! { struct Foo(u32); }; 9 | let mut korok = StructKorok::parse(&item)?; 10 | 11 | struct ResetStructAndFieldKoroksVisitor; 12 | impl KorokVisitor for ResetStructAndFieldKoroksVisitor { 13 | fn visit_struct(&mut self, korok: &mut StructKorok) -> CodamaResult<()> { 14 | self.visit_children(korok)?; 15 | korok.node = None; 16 | Ok(()) 17 | } 18 | fn visit_field(&mut self, korok: &mut FieldKorok) -> CodamaResult<()> { 19 | self.visit_children(korok)?; 20 | korok.node = None; 21 | Ok(()) 22 | } 23 | } 24 | 25 | korok.accept( 26 | &mut ComposeVisitor::new() 27 | .with(UniformVisitor::new(|mut k, visitor| { 28 | visitor.visit_children(&mut k)?; 29 | k.set_node(Some(PublicKeyTypeNode::new().into())); 30 | Ok(()) 31 | })) 32 | .with(ResetStructAndFieldKoroksVisitor {}), 33 | )?; 34 | 35 | assert_eq!(korok.node, None); 36 | assert_eq!(korok.fields.node, Some(PublicKeyTypeNode::new().into())); 37 | assert_eq!(korok.fields.all[0].node, None); 38 | Ok(()) 39 | } 40 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/lib.rs: -------------------------------------------------------------------------------- 1 | mod apply_codama_type_attributes_visitor; 2 | mod combine_modules_visitor; 3 | mod combine_types_visitor; 4 | mod set_accounts_visitor; 5 | mod set_borsh_types_visitor; 6 | mod set_errors_visitor; 7 | mod set_instructions_visitor; 8 | mod set_program_metadata_visitor; 9 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_accounts_visitor/mod.rs: -------------------------------------------------------------------------------- 1 | mod from_codama_account; 2 | mod from_codama_accounts; 3 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/boolean_type_node.rs: -------------------------------------------------------------------------------- 1 | use crate::set_borsh_types_visitor::utils::get_node_from_type; 2 | use codama_nodes::{BooleanTypeNode, Node}; 3 | use quote::quote; 4 | 5 | #[test] 6 | fn it_identifies_boolean_types() { 7 | let expected: Option = Some(BooleanTypeNode::default().into()); 8 | assert_eq!(get_node_from_type(quote! { bool }), expected); 9 | assert_eq!( 10 | get_node_from_type(quote! { std::primitive::bool }), 11 | expected 12 | ); 13 | assert_eq!(get_node_from_type(quote! { some::wrong::bool }), None); 14 | assert_eq!(get_node_from_type(quote! { bool }), None); 15 | } 16 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/enum_empty_variant_type_node.rs: -------------------------------------------------------------------------------- 1 | use crate::set_borsh_types_visitor::utils::get_node_from_enum_variant; 2 | use codama_nodes::{EnumEmptyVariantTypeNode, Node}; 3 | use quote::quote; 4 | 5 | #[test] 6 | fn it_identifies_empty_variants() { 7 | assert_eq!( 8 | get_node_from_enum_variant(quote! { Banana }), 9 | Some(Node::Type(EnumEmptyVariantTypeNode::new("banana").into())) 10 | ); 11 | } 12 | 13 | #[test] 14 | fn it_identifies_literal_discriminators() { 15 | assert_eq!( 16 | get_node_from_enum_variant(quote! { Banana = 42 }), 17 | Some(Node::Type( 18 | EnumEmptyVariantTypeNode { 19 | name: "banana".into(), 20 | discriminator: Some(42), 21 | } 22 | .into() 23 | )) 24 | ); 25 | } 26 | 27 | #[test] 28 | fn it_does_not_identify_discriminators_from_complex_expressions() { 29 | assert_eq!( 30 | get_node_from_enum_variant(quote! { Banana = 1 + 3 * 42 }), 31 | Some(Node::Type(EnumEmptyVariantTypeNode::new("banana").into())) 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/field_korok.rs: -------------------------------------------------------------------------------- 1 | use codama_errors::CodamaResult; 2 | use codama_korok_visitors::{KorokVisitable, SetBorshTypesVisitor}; 3 | use codama_koroks::FieldKorok; 4 | use codama_nodes::{NumberTypeNode, StructFieldTypeNode, U64}; 5 | 6 | #[test] 7 | fn it_create_a_struct_field_type_node_when_nammed() -> CodamaResult<()> { 8 | let ast = syn::parse_quote! { foo: u64 }; 9 | let mut korok = FieldKorok::parse(&ast)?; 10 | 11 | assert_eq!(korok.node, None); 12 | korok.accept(&mut SetBorshTypesVisitor::new())?; 13 | assert_eq!( 14 | korok.node, 15 | Some(StructFieldTypeNode::new("foo", NumberTypeNode::le(U64)).into()) 16 | ); 17 | Ok(()) 18 | } 19 | 20 | #[test] 21 | fn it_forwards_the_type_when_unnamed() -> CodamaResult<()> { 22 | let ast = syn::parse_quote! { u64 }; 23 | let mut korok = FieldKorok::parse(&ast)?; 24 | 25 | assert_eq!(korok.node, None); 26 | korok.accept(&mut SetBorshTypesVisitor::new())?; 27 | assert_eq!(korok.node, Some(NumberTypeNode::le(U64).into())); 28 | Ok(()) 29 | } 30 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/map_type_node.rs: -------------------------------------------------------------------------------- 1 | use crate::set_borsh_types_visitor::utils::get_node_from_type; 2 | use codama_nodes::{ 3 | BooleanTypeNode, MapTypeNode, Node, NumberTypeNode, PrefixedCountNode, U32, U64, 4 | }; 5 | use quote::quote; 6 | 7 | #[test] 8 | fn it_identifies_map_types() { 9 | assert_eq!( 10 | get_node_from_type(quote! { HashMap }), 11 | Some(Node::Type( 12 | MapTypeNode::new( 13 | NumberTypeNode::le(U64), 14 | BooleanTypeNode::default(), 15 | PrefixedCountNode::new(NumberTypeNode::le(U32)) 16 | ) 17 | .into() 18 | )) 19 | ); 20 | assert!(get_node_from_type(quote! { std::collections::HashMap }).is_some()); 21 | assert!(get_node_from_type(quote! { BTreeMap }).is_some()); 22 | assert!(get_node_from_type(quote! { std::collections::BTreeMap }).is_some()); 23 | assert_eq!( 24 | get_node_from_type(quote! { some::wrong::HashMap }), 25 | None 26 | ); 27 | assert_eq!(get_node_from_type(quote! { HashMap }), None); 28 | assert_eq!(get_node_from_type(quote! { HashMap<'a> }), None); 29 | assert_eq!(get_node_from_type(quote! { HashMap }), None); 30 | } 31 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/mod.rs: -------------------------------------------------------------------------------- 1 | mod array_type_node; 2 | mod boolean_type_node; 3 | mod enum_empty_variant_type_node; 4 | mod enum_struct_variant_type_node; 5 | mod enum_tuple_variant_type_node; 6 | mod enum_type_node; 7 | mod field_korok; 8 | mod map_type_node; 9 | mod no_override; 10 | mod number_type_node; 11 | mod option_type_node; 12 | mod public_key_type_node; 13 | mod set_type_node; 14 | mod string_type_node; 15 | mod struct_type_node; 16 | mod tuple_type_node; 17 | mod utils; 18 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/no_override.rs: -------------------------------------------------------------------------------- 1 | use codama_errors::CodamaResult; 2 | use codama_korok_visitors::{KorokVisitable, SetBorshTypesVisitor}; 3 | use codama_koroks::FieldKorok; 4 | use codama_nodes::BooleanTypeNode; 5 | 6 | #[test] 7 | fn it_does_not_override_existing_nodes() -> CodamaResult<()> { 8 | let ast: syn::Field = syn::parse_quote! { u32 }; 9 | let mut korok = FieldKorok::parse(&ast)?; 10 | korok.node = Some(BooleanTypeNode::default().into()); 11 | korok.accept(&mut SetBorshTypesVisitor::new())?; 12 | assert_eq!(korok.node, Some(BooleanTypeNode::default().into())); 13 | Ok(()) 14 | } 15 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/option_type_node.rs: -------------------------------------------------------------------------------- 1 | use crate::set_borsh_types_visitor::utils::get_node_from_type; 2 | use codama_nodes::{BooleanTypeNode, Node, NumberFormat::U64, NumberTypeNode, OptionTypeNode}; 3 | use quote::quote; 4 | 5 | #[test] 6 | fn it_identifies_option_types() { 7 | assert_eq!( 8 | get_node_from_type(quote! { Option }), 9 | Some(Node::Type( 10 | OptionTypeNode::new(NumberTypeNode::le(U64)).into() 11 | )) 12 | ); 13 | assert_eq!( 14 | get_node_from_type(quote! { std::option::Option }), 15 | Some(Node::Type( 16 | OptionTypeNode::new(BooleanTypeNode::default()).into() 17 | )) 18 | ); 19 | assert_eq!( 20 | get_node_from_type(quote! { some::wrong::Option }), 21 | None 22 | ); 23 | assert_eq!(get_node_from_type(quote! { Option }), None); 24 | assert_eq!(get_node_from_type(quote! { Option<'a> }), None); 25 | } 26 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/public_key_type_node.rs: -------------------------------------------------------------------------------- 1 | use crate::set_borsh_types_visitor::utils::get_node_from_type; 2 | use codama_nodes::PublicKeyTypeNode; 3 | use quote::quote; 4 | 5 | #[test] 6 | fn it_identifies_pubkey_types() { 7 | assert_eq!( 8 | get_node_from_type(quote! { Pubkey }), 9 | Some(PublicKeyTypeNode::new().into()) 10 | ); 11 | assert_eq!( 12 | get_node_from_type(quote! { solana_sdk::pubkey::Pubkey }), 13 | Some(PublicKeyTypeNode::new().into()) 14 | ); 15 | assert_eq!( 16 | get_node_from_type(quote! { solana_pubkey::Pubkey }), 17 | Some(PublicKeyTypeNode::new().into()) 18 | ); 19 | assert_eq!( 20 | get_node_from_type(quote! { solana_program::Pubkey }), 21 | Some(PublicKeyTypeNode::new().into()) 22 | ); 23 | assert_eq!(get_node_from_type(quote! { some::wrong::Pubkey }), None); 24 | assert_eq!(get_node_from_type(quote! { Pubkey }), None); 25 | } 26 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/set_type_node.rs: -------------------------------------------------------------------------------- 1 | use crate::set_borsh_types_visitor::utils::get_node_from_type; 2 | use codama_nodes::{Node, NumberTypeNode, PrefixedCountNode, SetTypeNode, U32, U64}; 3 | use quote::quote; 4 | 5 | #[test] 6 | fn it_identifies_set_types() { 7 | assert_eq!( 8 | get_node_from_type(quote! { HashSet }), 9 | Some(Node::Type( 10 | SetTypeNode::new( 11 | NumberTypeNode::le(U64), 12 | PrefixedCountNode::new(NumberTypeNode::le(U32)) 13 | ) 14 | .into() 15 | )) 16 | ); 17 | assert!(get_node_from_type(quote! { std::collections::HashSet }).is_some()); 18 | assert!(get_node_from_type(quote! { BTreeSet }).is_some()); 19 | assert!(get_node_from_type(quote! { std::collections::BTreeSet }).is_some()); 20 | assert_eq!( 21 | get_node_from_type(quote! { some::wrong::HashSet }), 22 | None 23 | ); 24 | assert_eq!(get_node_from_type(quote! { HashSet }), None); 25 | assert_eq!(get_node_from_type(quote! { HashSet<'a> }), None); 26 | assert_eq!(get_node_from_type(quote! { HashSet }), None); 27 | } 28 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/string_type_node.rs: -------------------------------------------------------------------------------- 1 | use crate::set_borsh_types_visitor::utils::get_node_from_type; 2 | use codama_nodes::{Node, NumberTypeNode, SizePrefixTypeNode, StringTypeNode, U32}; 3 | use quote::quote; 4 | 5 | #[test] 6 | fn it_identifies_string_types() { 7 | let expected: Option = 8 | Some(SizePrefixTypeNode::new(StringTypeNode::utf8(), NumberTypeNode::le(U32)).into()); 9 | assert_eq!(get_node_from_type(quote! { String }), expected); 10 | assert_eq!(get_node_from_type(quote! { std::string::String }), expected); 11 | assert_eq!(get_node_from_type(quote! { some::wrong::String }), None); 12 | assert_eq!(get_node_from_type(quote! { String }), None); 13 | } 14 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/struct_type_node.rs: -------------------------------------------------------------------------------- 1 | use crate::set_borsh_types_visitor::utils::get_node_from_item; 2 | use codama_nodes::{ 3 | BooleanTypeNode, DefinedTypeNode, Node, NumberTypeNode, SizePrefixTypeNode, StringTypeNode, 4 | StructFieldTypeNode, StructTypeNode, U32, U8, 5 | }; 6 | use quote::quote; 7 | 8 | #[test] 9 | fn it_wraps_all_named_fields_in_a_defined_struct() { 10 | assert_eq!( 11 | get_node_from_item(quote! { 12 | pub struct Person { 13 | pub name: String, 14 | pub age: u8, 15 | pub member: bool, 16 | } 17 | }), 18 | Some(Node::DefinedType(DefinedTypeNode::new( 19 | "person", 20 | StructTypeNode::new(vec![ 21 | StructFieldTypeNode::new( 22 | "name", 23 | SizePrefixTypeNode::new(StringTypeNode::utf8(), NumberTypeNode::le(U32)) 24 | ), 25 | StructFieldTypeNode::new("age", NumberTypeNode::le(U8)), 26 | StructFieldTypeNode::new("member", BooleanTypeNode::default()), 27 | ]) 28 | ))) 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/tuple_type_node.rs: -------------------------------------------------------------------------------- 1 | use crate::set_borsh_types_visitor::utils::get_node_from_item; 2 | use codama_nodes::{ 3 | BooleanTypeNode, DefinedTypeNode, Node, NumberFormat::U64, NumberTypeNode, SizePrefixTypeNode, 4 | StringTypeNode, TupleTypeNode, U32, U8, 5 | }; 6 | use quote::quote; 7 | 8 | #[test] 9 | fn it_wraps_all_unnamed_fields_in_a_defined_tuple() { 10 | assert_eq!( 11 | get_node_from_item(quote! { 12 | pub struct Person(String, u8, bool); 13 | }), 14 | Some(Node::DefinedType(DefinedTypeNode::new( 15 | "person", 16 | TupleTypeNode::new(vec![ 17 | SizePrefixTypeNode::new(StringTypeNode::utf8(), NumberTypeNode::le(U32)).into(), 18 | NumberTypeNode::le(U8).into(), 19 | BooleanTypeNode::default().into(), 20 | ]) 21 | ))) 22 | ); 23 | } 24 | 25 | #[test] 26 | fn it_uses_the_inner_type_directly_on_single_unnamed_fields() { 27 | assert_eq!( 28 | get_node_from_item(quote! { struct Slot(u64); }), 29 | Some(DefinedTypeNode::new("slot", NumberTypeNode::le(U64)).into()) 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_borsh_types_visitor/utils.rs: -------------------------------------------------------------------------------- 1 | use codama_korok_visitors::{CombineTypesVisitor, KorokVisitable, SetBorshTypesVisitor}; 2 | use codama_koroks::{ItemKorok, KorokTrait, RootKorok}; 3 | use codama_nodes::Node; 4 | use codama_stores::RootStore; 5 | use proc_macro2::TokenStream; 6 | use quote::quote; 7 | 8 | pub fn get_node(tt: TokenStream, node_getter: fn(RootKorok) -> Option) -> Option { 9 | let store = RootStore::hydrate(tt).unwrap(); 10 | let mut korok = RootKorok::parse(&store).unwrap(); 11 | korok.accept(&mut SetBorshTypesVisitor::new()).unwrap(); 12 | korok.accept(&mut CombineTypesVisitor::new()).unwrap(); 13 | node_getter(korok) 14 | } 15 | 16 | pub fn get_node_from_item(tt: TokenStream) -> Option { 17 | get_node(tt, |k| k.crates[0].items[0].node().clone()) 18 | } 19 | 20 | pub fn get_node_from_enum_variant(tt: TokenStream) -> Option { 21 | get_node(quote! { pub enum Foo { #tt } }, |k| { 22 | match &k.crates[0].items[0] { 23 | ItemKorok::Enum(k) => k.variants[0].node.clone(), 24 | _ => None, 25 | } 26 | }) 27 | } 28 | 29 | pub fn get_node_from_type(tt: TokenStream) -> Option { 30 | get_node(quote! { pub struct Foo(#tt); }, |k| { 31 | match &k.crates[0].items[0] { 32 | ItemKorok::Struct(k) => k.fields.all[0].node.clone(), 33 | _ => None, 34 | } 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_errors_visitor/mod.rs: -------------------------------------------------------------------------------- 1 | mod from_codama_errors; 2 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_instructions_visitor/mod.rs: -------------------------------------------------------------------------------- 1 | mod from_codama_instruction; 2 | mod from_codama_instructions; 3 | -------------------------------------------------------------------------------- /codama-korok-visitors/tests/set_program_metadata_visitor/fixtures/full_metadata.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "my-crate-name" 3 | version = "1.2.3" 4 | edition = "2021" 5 | publish = false 6 | 7 | [package.metadata.solana] 8 | program-id = "MyProgramAddress1111111111111111111111111" 9 | -------------------------------------------------------------------------------- /codama-koroks/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-koroks/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama-koroks" 3 | description = "Intermediate tree structure for collecting nodes" 4 | version = "0.4.0" 5 | repository = { workspace = true } 6 | edition = { workspace = true } 7 | license = { workspace = true } 8 | 9 | [dev-dependencies] 10 | quote = "1.0" 11 | 12 | [dependencies] 13 | codama-attributes = { version = "0.4.0", path = "../codama-attributes" } 14 | codama-errors = { version = "0.4.0", path = "../codama-errors" } 15 | codama-nodes = { version = "0.4.0", path = "../codama-nodes" } 16 | codama-stores = { version = "0.4.0", path = "../codama-stores" } 17 | codama-syn-helpers = { version = "0.4.0", path = "../codama-syn-helpers" } 18 | derive_more = { version = "1.0", features = ["from"] } 19 | proc-macro2 = "1.0" 20 | syn = { version = "2.0", features = ["extra-traits", "full"] } 21 | -------------------------------------------------------------------------------- /codama-koroks/src/crate_korok.rs: -------------------------------------------------------------------------------- 1 | use crate::{ItemKorok, KorokTrait}; 2 | use codama_attributes::Attributes; 3 | use codama_errors::{combine_errors, CodamaError, CodamaResult}; 4 | use codama_nodes::Node; 5 | use codama_stores::CrateStore; 6 | 7 | #[derive(Debug, PartialEq)] 8 | pub struct CrateKorok<'a> { 9 | pub attributes: Attributes<'a>, 10 | pub items: Vec>, 11 | pub node: Option, 12 | pub store: &'a CrateStore, 13 | } 14 | 15 | impl<'a> CrateKorok<'a> { 16 | pub fn parse(store: &'a CrateStore) -> CodamaResult { 17 | let (attributes, items) = combine_errors!( 18 | Attributes::parse(&store.file.attrs, (&store.file).into()).map_err(CodamaError::from), 19 | ItemKorok::parse_all(&store.file.items, &store.file_modules, &mut 0,), 20 | )?; 21 | Ok(Self { 22 | attributes, 23 | items, 24 | node: None, 25 | store, 26 | }) 27 | } 28 | } 29 | 30 | impl KorokTrait for CrateKorok<'_> { 31 | fn node(&self) -> &Option { 32 | &self.node 33 | } 34 | 35 | fn set_node(&mut self, node: Option) { 36 | self.node = node; 37 | } 38 | 39 | fn attributes(&self) -> Option<&Attributes> { 40 | Some(&self.attributes) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /codama-koroks/src/enum_korok.rs: -------------------------------------------------------------------------------- 1 | use crate::{EnumVariantKorok, KorokTrait}; 2 | use codama_attributes::Attributes; 3 | use codama_errors::{combine_errors, CodamaError, CodamaResult}; 4 | use codama_nodes::Node; 5 | use codama_syn_helpers::extensions::*; 6 | 7 | #[derive(Debug, PartialEq)] 8 | pub struct EnumKorok<'a> { 9 | pub ast: &'a syn::ItemEnum, 10 | pub attributes: Attributes<'a>, 11 | pub node: Option, 12 | pub variants: Vec>, 13 | } 14 | 15 | impl<'a> EnumKorok<'a> { 16 | pub fn parse(item: &'a syn::Item) -> CodamaResult { 17 | let syn::Item::Enum(ast) = item else { 18 | return Err(item.error("Expected an enum").into()); 19 | }; 20 | let (attributes, variants) = combine_errors!( 21 | Attributes::parse(&ast.attrs, item.into()).map_err(CodamaError::from), 22 | EnumVariantKorok::parse_all(&ast.variants), 23 | )?; 24 | Ok(Self { 25 | ast, 26 | attributes, 27 | node: None, 28 | variants, 29 | }) 30 | } 31 | } 32 | 33 | impl KorokTrait for EnumKorok<'_> { 34 | fn node(&self) -> &Option { 35 | &self.node 36 | } 37 | 38 | fn set_node(&mut self, node: Option) { 39 | self.node = node; 40 | } 41 | 42 | fn attributes(&self) -> Option<&Attributes> { 43 | Some(&self.attributes) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /codama-koroks/src/enum_variant_korok.rs: -------------------------------------------------------------------------------- 1 | use crate::{FieldsKorok, KorokTrait}; 2 | use codama_attributes::Attributes; 3 | use codama_errors::{combine_errors, CodamaError, CodamaResult, IteratorCombineErrors}; 4 | use codama_nodes::Node; 5 | 6 | #[derive(Debug, PartialEq)] 7 | pub struct EnumVariantKorok<'a> { 8 | pub ast: &'a syn::Variant, 9 | pub attributes: Attributes<'a>, 10 | pub fields: FieldsKorok<'a>, 11 | pub node: Option, 12 | } 13 | 14 | impl<'a> EnumVariantKorok<'a> { 15 | pub fn parse(ast: &'a syn::Variant) -> CodamaResult { 16 | let (attributes, fields) = combine_errors!( 17 | Attributes::parse(&ast.attrs, ast.into()).map_err(CodamaError::from), 18 | FieldsKorok::parse(&ast.fields), 19 | )?; 20 | Ok(Self { 21 | ast, 22 | attributes, 23 | fields, 24 | node: None, 25 | }) 26 | } 27 | 28 | pub fn parse_all( 29 | variants: &'a syn::punctuated::Punctuated, 30 | ) -> CodamaResult> { 31 | variants 32 | .iter() 33 | .map(Self::parse) 34 | .collect_and_combine_errors() 35 | } 36 | } 37 | 38 | impl KorokTrait for EnumVariantKorok<'_> { 39 | fn node(&self) -> &Option { 40 | &self.node 41 | } 42 | 43 | fn set_node(&mut self, node: Option) { 44 | self.node = node; 45 | } 46 | 47 | fn attributes(&self) -> Option<&Attributes> { 48 | Some(&self.attributes) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /codama-koroks/src/field_korok.rs: -------------------------------------------------------------------------------- 1 | use crate::KorokTrait; 2 | use codama_attributes::Attributes; 3 | use codama_errors::CodamaResult; 4 | use codama_nodes::{Node, StructFieldTypeNode, TypeNode}; 5 | 6 | #[derive(Debug, PartialEq)] 7 | pub struct FieldKorok<'a> { 8 | pub ast: &'a syn::Field, 9 | pub attributes: Attributes<'a>, 10 | pub node: Option, 11 | } 12 | 13 | impl<'a> FieldKorok<'a> { 14 | pub fn parse(ast: &'a syn::Field) -> CodamaResult { 15 | let attributes = Attributes::parse(&ast.attrs, ast.into())?; 16 | Ok(Self { 17 | ast, 18 | attributes, 19 | node: None, 20 | }) 21 | } 22 | 23 | pub fn set_type_node(&mut self, node: TypeNode) { 24 | self.node = match &self.ast.ident { 25 | Some(ident) => Some(StructFieldTypeNode::new(ident.to_string(), node).into()), 26 | None => Some(node.into()), 27 | } 28 | } 29 | } 30 | 31 | impl KorokTrait for FieldKorok<'_> { 32 | fn node(&self) -> &Option { 33 | &self.node 34 | } 35 | 36 | fn set_node(&mut self, node: Option) { 37 | self.node = node; 38 | } 39 | 40 | fn attributes(&self) -> Option<&Attributes> { 41 | Some(&self.attributes) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /codama-koroks/src/fields_korok.rs: -------------------------------------------------------------------------------- 1 | use crate::{FieldKorok, KorokTrait}; 2 | use codama_errors::{CodamaResult, IteratorCombineErrors}; 3 | use codama_nodes::Node; 4 | 5 | #[derive(Debug, PartialEq)] 6 | pub struct FieldsKorok<'a> { 7 | pub ast: &'a syn::Fields, 8 | pub all: Vec>, 9 | pub node: Option, 10 | } 11 | 12 | impl<'a> FieldsKorok<'a> { 13 | pub fn parse(ast: &'a syn::Fields) -> CodamaResult { 14 | Ok(Self { 15 | ast, 16 | all: match ast { 17 | syn::Fields::Named(f) => f 18 | .named 19 | .iter() 20 | .map(FieldKorok::parse) 21 | .collect_and_combine_errors(), 22 | syn::Fields::Unnamed(f) => f 23 | .unnamed 24 | .iter() 25 | .map(FieldKorok::parse) 26 | .collect_and_combine_errors(), 27 | syn::Fields::Unit => Ok(vec![]), 28 | }?, 29 | node: None, 30 | }) 31 | } 32 | } 33 | 34 | impl KorokTrait for FieldsKorok<'_> { 35 | fn node(&self) -> &Option { 36 | &self.node 37 | } 38 | 39 | fn set_node(&mut self, node: Option) { 40 | self.node = node; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /codama-koroks/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod crate_korok; 2 | mod enum_korok; 3 | mod enum_variant_korok; 4 | mod field_korok; 5 | mod fields_korok; 6 | mod file_module_korok; 7 | mod item_korok; 8 | mod korok; 9 | mod module_korok; 10 | mod root_korok; 11 | mod struct_korok; 12 | mod unsupported_item_korok; 13 | 14 | pub use crate_korok::*; 15 | pub use enum_korok::*; 16 | pub use enum_variant_korok::*; 17 | pub use field_korok::*; 18 | pub use fields_korok::*; 19 | pub use file_module_korok::*; 20 | pub use item_korok::*; 21 | pub use korok::*; 22 | pub use module_korok::*; 23 | pub use root_korok::*; 24 | pub use struct_korok::*; 25 | pub use unsupported_item_korok::*; 26 | -------------------------------------------------------------------------------- /codama-koroks/src/root_korok.rs: -------------------------------------------------------------------------------- 1 | use crate::{CrateKorok, KorokTrait}; 2 | use codama_errors::{CodamaResult, IteratorCombineErrors}; 3 | use codama_nodes::Node; 4 | use codama_stores::RootStore; 5 | 6 | #[derive(Debug, PartialEq)] 7 | pub struct RootKorok<'a> { 8 | pub crates: Vec>, 9 | pub node: Option, 10 | pub store: &'a RootStore, 11 | } 12 | 13 | impl<'a> RootKorok<'a> { 14 | pub fn parse(root_store: &'a RootStore) -> CodamaResult { 15 | Ok(Self { 16 | crates: root_store 17 | .crates 18 | .iter() 19 | .map(CrateKorok::parse) 20 | .collect_and_combine_errors()?, 21 | node: None, 22 | store: root_store, 23 | }) 24 | } 25 | } 26 | 27 | impl KorokTrait for RootKorok<'_> { 28 | fn node(&self) -> &Option { 29 | &self.node 30 | } 31 | 32 | fn set_node(&mut self, node: Option) { 33 | self.node = node; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /codama-koroks/src/struct_korok.rs: -------------------------------------------------------------------------------- 1 | use crate::{FieldsKorok, KorokTrait}; 2 | use codama_attributes::Attributes; 3 | use codama_errors::{combine_errors, CodamaError, CodamaResult}; 4 | use codama_nodes::Node; 5 | use codama_syn_helpers::extensions::*; 6 | 7 | #[derive(Debug, PartialEq)] 8 | pub struct StructKorok<'a> { 9 | pub ast: &'a syn::ItemStruct, 10 | pub attributes: Attributes<'a>, 11 | pub fields: FieldsKorok<'a>, 12 | pub node: Option, 13 | } 14 | 15 | impl<'a> StructKorok<'a> { 16 | pub fn parse(item: &'a syn::Item) -> CodamaResult { 17 | let syn::Item::Struct(ast) = item else { 18 | return Err(item.error("Expected a struct").into()); 19 | }; 20 | let (attributes, fields) = combine_errors!( 21 | Attributes::parse(&ast.attrs, item.into()).map_err(CodamaError::from), 22 | FieldsKorok::parse(&ast.fields), 23 | )?; 24 | Ok(Self { 25 | ast, 26 | attributes, 27 | fields, 28 | node: None, 29 | }) 30 | } 31 | } 32 | 33 | impl KorokTrait for StructKorok<'_> { 34 | fn node(&self) -> &Option { 35 | &self.node 36 | } 37 | 38 | fn set_node(&mut self, node: Option) { 39 | self.node = node; 40 | } 41 | 42 | fn attributes(&self) -> Option<&Attributes> { 43 | Some(&self.attributes) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /codama-koroks/src/unsupported_item_korok.rs: -------------------------------------------------------------------------------- 1 | use crate::KorokTrait; 2 | use codama_attributes::Attributes; 3 | use codama_errors::CodamaResult; 4 | use codama_nodes::Node; 5 | use codama_syn_helpers::extensions::*; 6 | 7 | #[derive(Debug, PartialEq)] 8 | pub struct UnsupportedItemKorok<'a> { 9 | pub ast: &'a syn::Item, 10 | pub attributes: Attributes<'a>, 11 | pub node: Option, 12 | } 13 | 14 | impl<'a> UnsupportedItemKorok<'a> { 15 | pub fn parse(ast: &'a syn::Item) -> CodamaResult { 16 | let attributes = match ast.attributes() { 17 | Some(attrs) => Attributes::parse(attrs, ast.into())?, 18 | None => Attributes(Vec::new()), 19 | }; 20 | Ok(Self { 21 | ast, 22 | attributes, 23 | node: None, 24 | }) 25 | } 26 | } 27 | 28 | impl KorokTrait for UnsupportedItemKorok<'_> { 29 | fn node(&self) -> &Option { 30 | &self.node 31 | } 32 | 33 | fn set_node(&mut self, node: Option) { 34 | self.node = node; 35 | } 36 | 37 | fn attributes(&self) -> Option<&Attributes> { 38 | Some(&self.attributes) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /codama-koroks/tests/from_tokens/mod.rs: -------------------------------------------------------------------------------- 1 | use codama_koroks::{CrateKorok, ItemKorok, RootKorok}; 2 | use codama_stores::{CrateStore, RootStore}; 3 | use quote::quote; 4 | 5 | #[test] 6 | fn root_from_tokens() { 7 | let tt = quote! { 8 | enum Membership { None, Basic, Premium } 9 | struct Person { 10 | name: String, 11 | age: u8, 12 | member: Membership, 13 | } 14 | }; 15 | 16 | let store = RootStore::hydrate(tt).unwrap(); 17 | let korok = RootKorok::parse(&store).unwrap(); 18 | assert_eq!(korok.store, &store); 19 | assert_eq!(korok.crates.len(), 1); 20 | } 21 | 22 | #[test] 23 | fn crate_from_tokens() { 24 | let tt = quote! { 25 | enum Membership { None, Basic, Premium } 26 | struct Person { 27 | name: String, 28 | age: u8, 29 | member: Membership, 30 | } 31 | }; 32 | 33 | let store = CrateStore::hydrate(tt).unwrap(); 34 | let korok = CrateKorok::parse(&store).unwrap(); 35 | assert_eq!(korok.store, &store); 36 | assert_eq!(korok.node, None); 37 | assert!(matches!( 38 | korok.items.as_slice(), 39 | [ItemKorok::Enum(_), ItemKorok::Struct(_),] 40 | )); 41 | } 42 | -------------------------------------------------------------------------------- /codama-koroks/tests/lib.rs: -------------------------------------------------------------------------------- 1 | mod from_tokens; 2 | mod nested_modules; 3 | mod single_crate; 4 | 5 | pub fn get_path(relative_path: &str) -> std::path::PathBuf { 6 | let project_dir = env!("CARGO_MANIFEST_DIR"); 7 | std::path::Path::new(project_dir) 8 | .join("tests") 9 | .join(relative_path) 10 | } 11 | -------------------------------------------------------------------------------- /codama-koroks/tests/nested_modules/crate/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-koroks/tests/nested_modules/crate/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nested-modules" 3 | version = "0.0.0" 4 | edition = "2021" 5 | publish = false 6 | -------------------------------------------------------------------------------- /codama-koroks/tests/nested_modules/crate/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Item index: 0 2 | pub type Foo = (); 3 | 4 | // Item index: 1 5 | pub mod nested_1 { 6 | // Item index: 0 7 | pub mod nested_2 { 8 | // Item index: 0 9 | pub mod person; 10 | } 11 | 12 | // Item index: 1 13 | pub type Foo = (); 14 | 15 | // Item index: 2 16 | pub mod membership; 17 | } 18 | -------------------------------------------------------------------------------- /codama-koroks/tests/nested_modules/crate/src/membership.rs: -------------------------------------------------------------------------------- 1 | pub enum Membership { 2 | None, 3 | Basic, 4 | Premium, 5 | } 6 | -------------------------------------------------------------------------------- /codama-koroks/tests/nested_modules/crate/src/person.rs: -------------------------------------------------------------------------------- 1 | use crate::membership::Membership; 2 | 3 | pub struct Person { 4 | pub name: String, 5 | pub age: u8, 6 | pub membership: Membership, 7 | } 8 | -------------------------------------------------------------------------------- /codama-koroks/tests/single_crate/crate/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-koroks/tests/single_crate/crate/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "single-crate" 3 | version = "0.0.0" 4 | edition = "2021" 5 | publish = false 6 | -------------------------------------------------------------------------------- /codama-koroks/tests/single_crate/crate/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod membership; 2 | mod person; 3 | 4 | pub use membership::*; 5 | pub use person::*; 6 | -------------------------------------------------------------------------------- /codama-koroks/tests/single_crate/crate/src/membership.rs: -------------------------------------------------------------------------------- 1 | pub enum Membership { 2 | None, 3 | Basic, 4 | Premium, 5 | } 6 | -------------------------------------------------------------------------------- /codama-koroks/tests/single_crate/crate/src/person.rs: -------------------------------------------------------------------------------- 1 | use crate::membership::Membership; 2 | 3 | pub struct Person { 4 | pub name: String, 5 | pub age: u8, 6 | pub membership: Membership, 7 | } 8 | -------------------------------------------------------------------------------- /codama-koroks/tests/single_crate/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::get_path; 2 | use codama_koroks::{ItemKorok, RootKorok}; 3 | use codama_stores::RootStore; 4 | 5 | #[test] 6 | fn load_single_crate() { 7 | let path = get_path("single_crate/crate"); 8 | let root_store: RootStore = RootStore::load_all(&[&path]).unwrap(); 9 | let root_korok = RootKorok::parse(&root_store).unwrap(); 10 | 11 | // Check the root korok. 12 | let [crate_korok] = &root_korok.crates.as_slice() else { 13 | panic!("Unexpected number of crates"); 14 | }; 15 | 16 | // Check the crate korok. 17 | assert_eq!( 18 | crate_korok.store.path, 19 | get_path("single_crate/crate/src/lib.rs") 20 | ); 21 | let [ItemKorok::FileModule(membership), ItemKorok::FileModule(person), ItemKorok::Unsupported(_), ItemKorok::Unsupported(_)] = 22 | &crate_korok.items.as_slice() 23 | else { 24 | panic!("Unexpected items in lib.rs"); 25 | }; 26 | 27 | // Check the membership module. 28 | assert_eq!( 29 | membership.store.path, 30 | get_path("single_crate/crate/src/membership.rs") 31 | ); 32 | let [ItemKorok::Enum(_)] = &membership.items.as_slice() else { 33 | panic!("Unexpected items in membership.rs"); 34 | }; 35 | 36 | // Check the person module. 37 | assert_eq!( 38 | person.store.path, 39 | get_path("single_crate/crate/src/person.rs") 40 | ); 41 | let [ItemKorok::Unsupported(_), ItemKorok::Struct(_)] = &person.items.as_slice() else { 42 | panic!("Unexpected items in person.rs"); 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /codama-macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama-macros" 3 | description = "Procedural macros for the Codama standard" 4 | version = "0.4.0" 5 | repository = { workspace = true } 6 | edition = { workspace = true } 7 | license = { workspace = true } 8 | 9 | [lib] 10 | proc-macro = true 11 | 12 | [[test]] 13 | name = "tests" 14 | path = "tests/mod.rs" 15 | 16 | [dev-dependencies] 17 | trybuild = { version = "1.0.49", features = ["diff"] } 18 | 19 | [dependencies] 20 | codama-attributes = { version = "0.4.0", path = "../codama-attributes" } 21 | codama-errors = { version = "0.4.0", path = "../codama-errors" } 22 | codama-koroks = { version = "0.4.0", path = "../codama-koroks" } 23 | codama-stores = { version = "0.4.0", path = "../codama-stores" } 24 | proc-macro2 = "1.0" 25 | quote = "1.0" 26 | syn = { version = "2.0", features = ["extra-traits"] } 27 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_account_derive/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::CodamaAccount; 2 | 3 | #[derive(CodamaAccount)] 4 | pub struct StructTest; 5 | 6 | #[derive(CodamaAccount)] 7 | pub enum EnumTest {} 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_account_derive/multiple_types.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::{codama, CodamaAccount}; 2 | 3 | #[derive(CodamaAccount)] 4 | #[codama(type = boolean)] 5 | #[derive(PartialEq)] 6 | #[codama(type = public_key)] 7 | #[derive(Debug)] 8 | #[codama(type = number(u32))] 9 | pub struct StructTest { 10 | #[codama(type = boolean)] 11 | #[codama(type = public_key)] 12 | pub field: u32, 13 | } 14 | 15 | #[derive(CodamaAccount)] 16 | #[codama(type = boolean)] 17 | #[codama(type = public_key)] 18 | pub enum EnumTest { 19 | #[codama(type = boolean)] 20 | #[codama(type = public_key)] 21 | Variant { 22 | #[codama(type = boolean)] 23 | #[codama(type = public_key)] 24 | field: u32, 25 | }, 26 | } 27 | 28 | fn main() {} 29 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_account_derive/multiple_types.fail.stderr: -------------------------------------------------------------------------------- 1 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 2 | --> tests/codama_account_derive/multiple_types.fail.rs:6:1 3 | | 4 | 6 | #[codama(type = public_key)] 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | 7 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 8 | --> tests/codama_account_derive/multiple_types.fail.rs:4:1 9 | | 10 | 4 | #[codama(type = boolean)] 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 12 | 13 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 14 | --> tests/codama_account_derive/multiple_types.fail.rs:10:5 15 | | 16 | 10 | #[codama(type = boolean)] 17 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 18 | 19 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 20 | --> tests/codama_account_derive/multiple_types.fail.rs:16:1 21 | | 22 | 16 | #[codama(type = boolean)] 23 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 24 | 25 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 26 | --> tests/codama_account_derive/multiple_types.fail.rs:19:5 27 | | 28 | 19 | #[codama(type = boolean)] 29 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 30 | 31 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 32 | --> tests/codama_account_derive/multiple_types.fail.rs:22:9 33 | | 34 | 22 | #[codama(type = boolean)] 35 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 36 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_accounts_derive/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::CodamaAccounts; 2 | 3 | #[derive(CodamaAccounts)] 4 | pub enum TokenAccounts { 5 | Token {}, 6 | Mint {}, 7 | } 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/attribute_directive/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::{codama, CodamaInstruction}; 2 | 3 | pub struct AccountMeta; 4 | 5 | #[derive(CodamaInstruction)] 6 | pub struct MyInstruction { 7 | #[codama(account(signer))] 8 | pub authority: AccountMeta, 9 | #[codama(account(signer, writable))] 10 | pub payer: AccountMeta, 11 | #[codama(account)] 12 | pub owner: AccountMeta, 13 | #[codama(account(signer = "either", optional))] 14 | pub delegate: AccountMeta, 15 | } 16 | 17 | #[derive(CodamaInstruction)] 18 | pub struct MyInstructionWithExplicitValues { 19 | #[codama(account(signer = true, writable = false))] 20 | pub authority: AccountMeta, 21 | #[codama(account(signer = true, writable = true))] 22 | pub payer: AccountMeta, 23 | #[codama(account(signer = false, writable = false))] 24 | pub owner: AccountMeta, 25 | #[codama(account(signer = "either", writable = false, optional = true))] 26 | pub delegate: AccountMeta, 27 | } 28 | 29 | #[codama(account(name = "authority", signer))] 30 | #[codama(account(name = "payer", signer, writable))] 31 | #[codama(account(name = "owner"))] 32 | #[codama(account(name = "delegate", signer = "either", optional))] 33 | pub struct MyInstructionWithoutAccountFields; 34 | 35 | fn main() {} 36 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/attribute_directive/invalid_optional.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(account(optional = invalid))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/attribute_directive/invalid_optional.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a boolean 2 | --> tests/codama_attribute/attribute_directive/invalid_optional.fail.rs:3:29 3 | | 4 | 3 | #[codama(account(optional = invalid))] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/attribute_directive/invalid_signer.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(account(signer = invalid))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/attribute_directive/invalid_signer.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected boolean or `"either"` 2 | --> tests/codama_attribute/attribute_directive/invalid_signer.fail.rs:3:27 3 | | 4 | 3 | #[codama(account(signer = invalid))] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/attribute_directive/invalid_writable.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(account(writable = invalid))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/attribute_directive/invalid_writable.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a boolean 2 | --> tests/codama_attribute/attribute_directive/invalid_writable.fail.rs:3:29 3 | | 4 | 3 | #[codama(account(writable = invalid))] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/attribute_directive/name_missing.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(account)] 4 | pub struct Test; 5 | 6 | #[codama(account(signer, writable))] 7 | pub struct TestWithBooleans; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/attribute_directive/name_missing.fail.stderr: -------------------------------------------------------------------------------- 1 | error: name is missing 2 | --> tests/codama_attribute/attribute_directive/name_missing.fail.rs:3:10 3 | | 4 | 3 | #[codama(account)] 5 | | ^^^^^^^ 6 | 7 | error: name is missing 8 | --> tests/codama_attribute/attribute_directive/name_missing.fail.rs:6:10 9 | | 10 | 6 | #[codama(account(signer, writable))] 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/encoding_directive/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(encoding = utf8)] 4 | #[codama(encoding = base16)] 5 | #[codama(encoding = base58)] 6 | #[codama(encoding = base64)] 7 | pub struct Test; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/encoding_directive/invalid_encoding.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(encoding = invalid)] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/encoding_directive/invalid_encoding.fail.stderr: -------------------------------------------------------------------------------- 1 | error: invalid encoding 2 | --> tests/codama_attribute/encoding_directive/invalid_encoding.fail.rs:3:21 3 | | 4 | 3 | #[codama(encoding = invalid)] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/error_directive/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(error(42, "my message"))] 4 | #[codama(error("my message", 42))] 5 | #[codama(error(code = 42, message = "my message"))] 6 | #[codama(error(message = "my message", code = 42))] 7 | #[codama(error("my message", code = 42))] 8 | pub struct Test; 9 | 10 | fn main() {} 11 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/error_directive/invalid_code.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(error(code = "42"))] 4 | pub struct TestString; 5 | 6 | #[codama(error(code = foo(bar)))] 7 | pub struct TestMeta; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/error_directive/invalid_code.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected an unsigned integer 2 | --> tests/codama_attribute/error_directive/invalid_code.fail.rs:3:23 3 | | 4 | 3 | #[codama(error(code = "42"))] 5 | | ^^^^ 6 | 7 | error: expected a valid expression 8 | --> tests/codama_attribute/error_directive/invalid_code.fail.rs:6:23 9 | | 10 | 6 | #[codama(error(code = foo(bar)))] 11 | | ^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/error_directive/invalid_message.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(error(message = 42))] 4 | pub struct TestInteger; 5 | 6 | #[codama(error(message = foo(bar)))] 7 | pub struct TestMeta; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/error_directive/invalid_message.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a string 2 | --> tests/codama_attribute/error_directive/invalid_message.fail.rs:3:26 3 | | 4 | 3 | #[codama(error(message = 42))] 5 | | ^^ 6 | 7 | error: expected a valid expression 8 | --> tests/codama_attribute/error_directive/invalid_message.fail.rs:6:26 9 | | 10 | 6 | #[codama(error(message = foo(bar)))] 11 | | ^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/error_directive/nothing_provided.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(error())] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/error_directive/nothing_provided.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected at least one `code` or `message` attribute 2 | --> tests/codama_attribute/error_directive/nothing_provided.fail.rs:3:10 3 | | 4 | 3 | #[codama(error())] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/error_directive/too_many_codes.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(error(42, 100))] 4 | pub struct Test; 5 | 6 | #[codama(error(code = 42, code = 100))] 7 | pub struct TestExplicit; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/error_directive/too_many_codes.fail.stderr: -------------------------------------------------------------------------------- 1 | error: code is already set 2 | --> tests/codama_attribute/error_directive/too_many_codes.fail.rs:3:20 3 | | 4 | 3 | #[codama(error(42, 100))] 5 | | ^^^ 6 | 7 | error: code is already set 8 | --> tests/codama_attribute/error_directive/too_many_codes.fail.rs:6:27 9 | | 10 | 6 | #[codama(error(code = 42, code = 100))] 11 | | ^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/error_directive/too_many_messages.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(error("hello", "world"))] 4 | pub struct Test; 5 | 6 | #[codama(error(message = "hello", message = "world"))] 7 | pub struct TestExplicit; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/error_directive/too_many_messages.fail.stderr: -------------------------------------------------------------------------------- 1 | error: message is already set 2 | --> tests/codama_attribute/error_directive/too_many_messages.fail.rs:3:25 3 | | 4 | 3 | #[codama(error("hello", "world"))] 5 | | ^^^^^^^ 6 | 7 | error: message is already set 8 | --> tests/codama_attribute/error_directive/too_many_messages.fail.rs:6:35 9 | | 10 | 6 | #[codama(error(message = "hello", message = "world"))] 11 | | ^^^^^^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/explicit_path.pass.rs: -------------------------------------------------------------------------------- 1 | #[codama_macros::codama(type = boolean)] 2 | pub struct Test; 3 | 4 | fn main() {} 5 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/fixed_size_directive/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(fixed_size = 42)] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/fixed_size_directive/invalid_size.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(fixed_size = invalid(1, 2, 3))] 4 | pub struct Test; 5 | 6 | #[codama(fixed_size = invalid)] 7 | pub struct TestWithExpr; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/fixed_size_directive/invalid_size.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a valid expression 2 | --> tests/codama_attribute/fixed_size_directive/invalid_size.fail.rs:3:23 3 | | 4 | 3 | #[codama(fixed_size = invalid(1, 2, 3))] 5 | | ^^^^^^^^^^^^^^^^ 6 | 7 | error: expected an unsigned integer 8 | --> tests/codama_attribute/fixed_size_directive/invalid_size.fail.rs:6:23 9 | | 10 | 6 | #[codama(fixed_size = invalid)] 11 | | ^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/implicit_path.pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = boolean)] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/on_any_item.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = invalid)] 4 | pub struct StructTest; 5 | 6 | #[codama(type = invalid)] 7 | pub enum EnumTest {} 8 | 9 | #[codama(type = invalid)] 10 | pub trait TraitTest {} 11 | 12 | #[codama(type = invalid)] 13 | pub type TypeTest = (); 14 | 15 | #[codama(type = invalid)] 16 | pub mod mod_test {} 17 | 18 | #[codama(type = invalid)] 19 | pub fn fn_test() {} 20 | 21 | #[codama(type = invalid)] 22 | pub const CONST_TEST: () = (); 23 | 24 | #[codama(type = invalid)] 25 | pub static STATIC_TEST: () = (); 26 | 27 | #[codama(type = invalid)] 28 | pub union UnionTest { 29 | _field: (), 30 | } 31 | 32 | #[codama(type = invalid)] 33 | pub extern "C" fn extern_fn_test() {} 34 | 35 | fn main() {} 36 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/on_any_item.pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = boolean)] 4 | pub struct StructTest; 5 | 6 | #[codama(type = boolean)] 7 | pub enum EnumTest {} 8 | 9 | #[codama(type = boolean)] 10 | pub trait TraitTest {} 11 | 12 | #[codama(type = boolean)] 13 | pub type TypeTest = (); 14 | 15 | #[codama(type = boolean)] 16 | pub mod mod_test {} 17 | 18 | #[codama(type = boolean)] 19 | pub fn fn_test() {} 20 | 21 | #[codama(type = boolean)] 22 | pub const CONST_TEST: () = (); 23 | 24 | #[codama(type = boolean)] 25 | pub static STATIC_TEST: () = (); 26 | 27 | #[codama(type = boolean)] 28 | pub union UnionTest { 29 | _field: (), 30 | } 31 | 32 | #[codama(type = boolean)] 33 | pub extern "C" fn extern_fn_test() {} 34 | 35 | fn main() {} 36 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/on_fields.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::{codama, CodamaType}; 2 | 3 | #[derive(CodamaType)] 4 | pub struct StructTest { 5 | #[codama(type = invalid)] 6 | pub public_field: u8, 7 | #[codama(type = invalid)] 8 | private_field: u8, 9 | } 10 | 11 | #[derive(CodamaType)] 12 | pub struct TupleTest(#[codama(type = invalid)] u8); 13 | 14 | #[derive(CodamaType)] 15 | pub enum EnumTest { 16 | Struct { 17 | #[codama(type = invalid)] 18 | field: u8, 19 | }, 20 | Tuple(#[codama(type = invalid)] u8), 21 | } 22 | 23 | fn main() {} 24 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/on_fields.fail.stderr: -------------------------------------------------------------------------------- 1 | error: unrecognized type 2 | --> tests/codama_attribute/on_fields.fail.rs:5:21 3 | | 4 | 5 | #[codama(type = invalid)] 5 | | ^^^^^^^ 6 | 7 | error: unrecognized type 8 | --> tests/codama_attribute/on_fields.fail.rs:7:21 9 | | 10 | 7 | #[codama(type = invalid)] 11 | | ^^^^^^^ 12 | 13 | error: unrecognized type 14 | --> tests/codama_attribute/on_fields.fail.rs:12:38 15 | | 16 | 12 | pub struct TupleTest(#[codama(type = invalid)] u8); 17 | | ^^^^^^^ 18 | 19 | error: unrecognized type 20 | --> tests/codama_attribute/on_fields.fail.rs:17:25 21 | | 22 | 17 | #[codama(type = invalid)] 23 | | ^^^^^^^ 24 | 25 | error: unrecognized type 26 | --> tests/codama_attribute/on_fields.fail.rs:20:27 27 | | 28 | 20 | Tuple(#[codama(type = invalid)] u8), 29 | | ^^^^^^^ 30 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/on_fields.pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::{codama, CodamaType}; 2 | 3 | #[derive(CodamaType)] 4 | pub struct StructTest { 5 | #[codama(type = boolean)] 6 | pub public_field: u8, 7 | #[codama(type = boolean)] 8 | private_field: u8, 9 | } 10 | 11 | #[derive(CodamaType)] 12 | pub struct TupleTest(#[codama(type = boolean)] u8); 13 | 14 | #[derive(CodamaType)] 15 | pub enum EnumTest { 16 | Struct { 17 | #[codama(type = boolean)] 18 | field: u8, 19 | }, 20 | Tuple(#[codama(type = boolean)] u8), 21 | } 22 | 23 | fn main() {} 24 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/size_prefix_directive/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(size_prefix = number(u32))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/size_prefix_directive/invalid_size.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(size_prefix = string)] 4 | pub struct TestWithNonNumberTypeNode; 5 | 6 | #[codama(size_prefix = invalid(1, 2, 3))] 7 | pub struct TestWithInvalidValue; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/size_prefix_directive/invalid_size.fail.stderr: -------------------------------------------------------------------------------- 1 | error: prefix must be a NumberTypeNode 2 | --> tests/codama_attribute/size_prefix_directive/invalid_size.fail.rs:3:24 3 | | 4 | 3 | #[codama(size_prefix = string)] 5 | | ^^^^^^ 6 | 7 | error: unrecognized type 8 | --> tests/codama_attribute/size_prefix_directive/invalid_size.fail.rs:6:24 9 | | 10 | 6 | #[codama(size_prefix = invalid(1, 2, 3))] 11 | | ^^^^^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_directive/double_type.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = (number(u32), public_key))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_directive/double_type.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a single value, found a list 2 | --> tests/codama_attribute/type_directive/double_type.fail.rs:3:18 3 | | 4 | 3 | #[codama(type = (number(u32), public_key))] 5 | | ^^^^^^^^^^^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_directive/no_type.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = )] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_directive/no_type.fail.stderr: -------------------------------------------------------------------------------- 1 | error: unrecognized type 2 | --> tests/codama_attribute/type_directive/no_type.fail.rs:3:1 3 | | 4 | 3 | #[codama(type = )] 5 | | ^^^^^^^^^^^^^^^^^^ 6 | | 7 | = note: this error originates in the attribute macro `codama` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_directive/unrecognized_type.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = unrecognized_type(foo = 42))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_directive/unrecognized_type.fail.stderr: -------------------------------------------------------------------------------- 1 | error: unrecognized type 2 | --> tests/codama_attribute/type_directive/unrecognized_type.fail.rs:3:17 3 | | 4 | 3 | #[codama(type = unrecognized_type(foo = 42))] 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/boolean_type_node/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = boolean)] 4 | #[codama(type = boolean())] 5 | #[codama(type = boolean(number(u32)))] 6 | #[codama(type = boolean(size = number(u32)))] 7 | pub struct Test; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/boolean_type_node/size_already_set.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = boolean(number(u32), number(u32)))] 4 | pub struct Test; 5 | 6 | #[codama(type = boolean(size = number(u32), size = number(u32)))] 7 | pub struct TestExplicit; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/boolean_type_node/size_already_set.fail.stderr: -------------------------------------------------------------------------------- 1 | error: size is already set 2 | --> tests/codama_attribute/type_nodes/boolean_type_node/size_already_set.fail.rs:3:38 3 | | 4 | 3 | #[codama(type = boolean(number(u32), number(u32)))] 5 | | ^^^^^^^^^^^ 6 | 7 | error: size is already set 8 | --> tests/codama_attribute/type_nodes/boolean_type_node/size_already_set.fail.rs:6:45 9 | | 10 | 6 | #[codama(type = boolean(size = number(u32), size = number(u32)))] 11 | | ^^^^^^^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/boolean_type_node/unrecognized_attribute.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = boolean(foo = 42))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/boolean_type_node/unrecognized_attribute.fail.stderr: -------------------------------------------------------------------------------- 1 | error: unrecognized attribute 2 | --> tests/codama_attribute/type_nodes/boolean_type_node/unrecognized_attribute.fail.rs:3:25 3 | | 4 | 3 | #[codama(type = boolean(foo = 42))] 5 | | ^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/boolean_type_node/unrecognized_type.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = boolean(unrecognized))] 4 | pub struct Test; 5 | 6 | #[codama(type = boolean(size = unrecognized))] 7 | pub struct Test; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/boolean_type_node/unrecognized_type.fail.stderr: -------------------------------------------------------------------------------- 1 | error: unrecognized type 2 | --> tests/codama_attribute/type_nodes/boolean_type_node/unrecognized_type.fail.rs:3:25 3 | | 4 | 3 | #[codama(type = boolean(unrecognized))] 5 | | ^^^^^^^^^^^^ 6 | 7 | error: unrecognized type 8 | --> tests/codama_attribute/type_nodes/boolean_type_node/unrecognized_type.fail.rs:6:32 9 | | 10 | 6 | #[codama(type = boolean(size = unrecognized))] 11 | | ^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/fixed_size_type_node/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = fixed_size(boolean, 42))] 4 | #[codama(type = fixed_size(type = boolean, size = 42))] 5 | pub struct Test; 6 | 7 | fn main() {} 8 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/fixed_size_type_node/size_already_set.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = fixed_size(42, boolean, 100))] 4 | pub struct Test; 5 | 6 | #[codama(type = fixed_size(size = 42, type = boolean, size = 100))] 7 | pub struct TestExplicit; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/fixed_size_type_node/size_already_set.fail.stderr: -------------------------------------------------------------------------------- 1 | error: size is already set 2 | --> tests/codama_attribute/type_nodes/fixed_size_type_node/size_already_set.fail.rs:3:41 3 | | 4 | 3 | #[codama(type = fixed_size(42, boolean, 100))] 5 | | ^^^ 6 | 7 | error: size is already set 8 | --> tests/codama_attribute/type_nodes/fixed_size_type_node/size_already_set.fail.rs:6:55 9 | | 10 | 6 | #[codama(type = fixed_size(size = 42, type = boolean, size = 100))] 11 | | ^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/fixed_size_type_node/size_missing.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = fixed_size(boolean))] 4 | pub struct Test; 5 | 6 | #[codama(type = fixed_size(type = boolean))] 7 | pub struct TestExplicit; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/fixed_size_type_node/size_missing.fail.stderr: -------------------------------------------------------------------------------- 1 | error: size is missing 2 | --> tests/codama_attribute/type_nodes/fixed_size_type_node/size_missing.fail.rs:3:17 3 | | 4 | 3 | #[codama(type = fixed_size(boolean))] 5 | | ^^^^^^^^^^^^^^^^^^^ 6 | 7 | error: size is missing 8 | --> tests/codama_attribute/type_nodes/fixed_size_type_node/size_missing.fail.rs:6:17 9 | | 10 | 6 | #[codama(type = fixed_size(type = boolean))] 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/fixed_size_type_node/type_already_set.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = fixed_size(boolean, 42, number(u32)))] 4 | pub struct Test; 5 | 6 | #[codama(type = fixed_size(type = boolean, size = 42, type = number(u32)))] 7 | pub struct TestExplicit; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/fixed_size_type_node/type_already_set.fail.stderr: -------------------------------------------------------------------------------- 1 | error: type is already set 2 | --> tests/codama_attribute/type_nodes/fixed_size_type_node/type_already_set.fail.rs:3:41 3 | | 4 | 3 | #[codama(type = fixed_size(boolean, 42, number(u32)))] 5 | | ^^^^^^^^^^^ 6 | 7 | error: type is already set 8 | --> tests/codama_attribute/type_nodes/fixed_size_type_node/type_already_set.fail.rs:6:55 9 | | 10 | 6 | #[codama(type = fixed_size(type = boolean, size = 42, type = number(u32)))] 11 | | ^^^^^^^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/fixed_size_type_node/type_missing.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = fixed_size(42))] 4 | pub struct Test; 5 | 6 | #[codama(type = fixed_size(size = 42))] 7 | pub struct TestExplicit; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/fixed_size_type_node/type_missing.fail.stderr: -------------------------------------------------------------------------------- 1 | error: type is missing 2 | --> tests/codama_attribute/type_nodes/fixed_size_type_node/type_missing.fail.rs:3:17 3 | | 4 | 3 | #[codama(type = fixed_size(42))] 5 | | ^^^^^^^^^^^^^^ 6 | 7 | error: type is missing 8 | --> tests/codama_attribute/type_nodes/fixed_size_type_node/type_missing.fail.rs:6:17 9 | | 10 | 6 | #[codama(type = fixed_size(size = 42))] 11 | | ^^^^^^^^^^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = number(u32))] 4 | #[codama(type = number(u32, be))] 5 | #[codama(type = number(u32, le))] 6 | #[codama(type = number(le, u32))] 7 | #[codama(type = number(format = u32, endian = le))] 8 | #[codama(type = number(endian = le, format = u32))] 9 | pub struct Test; 10 | 11 | fn main() {} 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/endian_already_set.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = number(be, le, u32))] 4 | pub struct Test; 5 | 6 | #[codama(type = number(endian = be, endian = le, format = u32))] 7 | pub struct TestExplicit; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/endian_already_set.fail.stderr: -------------------------------------------------------------------------------- 1 | error: endian is already set 2 | --> tests/codama_attribute/type_nodes/number_type_node/endian_already_set.fail.rs:3:28 3 | | 4 | 3 | #[codama(type = number(be, le, u32))] 5 | | ^^ 6 | 7 | error: endian is already set 8 | --> tests/codama_attribute/type_nodes/number_type_node/endian_already_set.fail.rs:6:37 9 | | 10 | 6 | #[codama(type = number(endian = be, endian = le, format = u32))] 11 | | ^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/format_already_set.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = number(u32, u64))] 4 | pub struct Test; 5 | 6 | #[codama(type = number(format = u32, format = u64))] 7 | pub struct TestExplicit; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/format_already_set.fail.stderr: -------------------------------------------------------------------------------- 1 | error: format is already set 2 | --> tests/codama_attribute/type_nodes/number_type_node/format_already_set.fail.rs:3:29 3 | | 4 | 3 | #[codama(type = number(u32, u64))] 5 | | ^^^ 6 | 7 | error: format is already set 8 | --> tests/codama_attribute/type_nodes/number_type_node/format_already_set.fail.rs:6:38 9 | | 10 | 6 | #[codama(type = number(format = u32, format = u64))] 11 | | ^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/format_missing.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = number(le))] 4 | pub struct Test; 5 | 6 | #[codama(type = number(endian = le))] 7 | pub struct TestExplicit; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/format_missing.fail.stderr: -------------------------------------------------------------------------------- 1 | error: format is missing 2 | --> tests/codama_attribute/type_nodes/number_type_node/format_missing.fail.rs:3:17 3 | | 4 | 3 | #[codama(type = number(le))] 5 | | ^^^^^^^^^^ 6 | 7 | error: format is missing 8 | --> tests/codama_attribute/type_nodes/number_type_node/format_missing.fail.rs:6:17 9 | | 10 | 6 | #[codama(type = number(endian = le))] 11 | | ^^^^^^^^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/invalid_endian.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = number(u32, endian = invalid))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/invalid_endian.fail.stderr: -------------------------------------------------------------------------------- 1 | error: invalid endian 2 | --> tests/codama_attribute/type_nodes/number_type_node/invalid_endian.fail.rs:3:38 3 | | 4 | 3 | #[codama(type = number(u32, endian = invalid))] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/invalid_format.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = number(format = invalid))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/invalid_format.fail.stderr: -------------------------------------------------------------------------------- 1 | error: invalid format 2 | --> tests/codama_attribute/type_nodes/number_type_node/invalid_format.fail.rs:3:33 3 | | 4 | 3 | #[codama(type = number(format = invalid))] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/unrecognized_attribute.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = number(u32, unrecognized = 42, le))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/number_type_node/unrecognized_attribute.fail.stderr: -------------------------------------------------------------------------------- 1 | error: unrecognized attribute 2 | --> tests/codama_attribute/type_nodes/number_type_node/unrecognized_attribute.fail.rs:3:29 3 | | 4 | 3 | #[codama(type = number(u32, unrecognized = 42, le))] 5 | | ^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/public_key_type_node/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = public_key)] 4 | #[codama(type = public_key())] 5 | pub struct Test; 6 | 7 | fn main() {} 8 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/public_key_type_node/with_input.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = public_key(foo = 42))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/public_key_type_node/with_input.fail.stderr: -------------------------------------------------------------------------------- 1 | error: public_key does not accept any input 2 | --> tests/codama_attribute/type_nodes/public_key_type_node/with_input.fail.rs:3:17 3 | | 4 | 3 | #[codama(type = public_key(foo = 42))] 5 | | ^^^^^^^^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/string_type_node/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = string)] 4 | #[codama(type = string())] 5 | #[codama(type = string(utf8))] 6 | #[codama(type = string(base58))] 7 | #[codama(type = string(encoding = base58))] 8 | pub struct Test; 9 | 10 | fn main() {} 11 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/string_type_node/encoding_already_set.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = string(utf8, base64))] 4 | pub struct Test; 5 | 6 | #[codama(type = string(encoding = utf8, encoding = base64))] 7 | pub struct TestExplicit; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/string_type_node/encoding_already_set.fail.stderr: -------------------------------------------------------------------------------- 1 | error: encoding is already set 2 | --> tests/codama_attribute/type_nodes/string_type_node/encoding_already_set.fail.rs:3:30 3 | | 4 | 3 | #[codama(type = string(utf8, base64))] 5 | | ^^^^^^ 6 | 7 | error: encoding is already set 8 | --> tests/codama_attribute/type_nodes/string_type_node/encoding_already_set.fail.rs:6:41 9 | | 10 | 6 | #[codama(type = string(encoding = utf8, encoding = base64))] 11 | | ^^^^^^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/string_type_node/invalid_encoding.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = string(encoding = invalid))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/string_type_node/invalid_encoding.fail.stderr: -------------------------------------------------------------------------------- 1 | error: invalid encoding 2 | --> tests/codama_attribute/type_nodes/string_type_node/invalid_encoding.fail.rs:3:35 3 | | 4 | 3 | #[codama(type = string(encoding = invalid))] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/string_type_node/unrecognized_attribute.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(type = string(unrecognized))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/type_nodes/string_type_node/unrecognized_attribute.fail.stderr: -------------------------------------------------------------------------------- 1 | error: unrecognized attribute 2 | --> tests/codama_attribute/type_nodes/string_type_node/unrecognized_attribute.fail.rs:3:24 3 | | 4 | 3 | #[codama(type = string(unrecognized))] 5 | | ^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/boolean_value_node/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = true)] 4 | #[codama(default_value = false)] 5 | pub struct Test; 6 | 7 | fn main() {} 8 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/number_value_node/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = 0)] 4 | #[codama(default_value = 42)] 5 | #[codama(default_value = -42)] 6 | #[codama(default_value = 1.5)] 7 | #[codama(default_value = -1.5)] 8 | pub struct Test; 9 | 10 | fn main() {} 11 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/payer_value_node/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = payer)] 4 | pub struct Test; 5 | 6 | #[codama(default_value = payer())] 7 | pub struct TestWithParenthesis; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/payer_value_node/with_input.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = payer(42))] 4 | pub struct TestWithInteger; 5 | 6 | #[codama(default_value = payer(banana))] 7 | pub struct TestWithPath; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/payer_value_node/with_input.fail.stderr: -------------------------------------------------------------------------------- 1 | error: payer value does not accept any input 2 | --> tests/codama_attribute/values_nodes/payer_value_node/with_input.fail.rs:3:26 3 | | 4 | 3 | #[codama(default_value = payer(42))] 5 | | ^^^^^^^^^ 6 | 7 | error: payer value does not accept any input 8 | --> tests/codama_attribute/values_nodes/payer_value_node/with_input.fail.rs:6:26 9 | | 10 | 6 | #[codama(default_value = payer(banana))] 11 | | ^^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/public_key_value_node/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = public_key("1111"))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/public_key_value_node/invalid_input.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = public_key(42))] 4 | pub struct TestWithInteger; 5 | 6 | #[codama(default_value = public_key(banana))] 7 | pub struct TestWithPath; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/public_key_value_node/invalid_input.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a string 2 | --> tests/codama_attribute/values_nodes/public_key_value_node/invalid_input.fail.rs:3:37 3 | | 4 | 3 | #[codama(default_value = public_key(42))] 5 | | ^^ 6 | 7 | error: expected a string 8 | --> tests/codama_attribute/values_nodes/public_key_value_node/invalid_input.fail.rs:6:37 9 | | 10 | 6 | #[codama(default_value = public_key(banana))] 11 | | ^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/public_key_value_node/no_input.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = public_key)] 4 | pub struct Test; 5 | 6 | #[codama(default_value = public_key())] 7 | pub struct TestWithParenthesis; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/public_key_value_node/no_input.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a list: `public_key(...)` or `public_key = (...)` 2 | --> tests/codama_attribute/values_nodes/public_key_value_node/no_input.fail.rs:3:26 3 | | 4 | 3 | #[codama(default_value = public_key)] 5 | | ^^^^^^^^^^ 6 | 7 | error: public_key is missing 8 | --> tests/codama_attribute/values_nodes/public_key_value_node/no_input.fail.rs:6:26 9 | | 10 | 6 | #[codama(default_value = public_key())] 11 | | ^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/public_key_value_node/too_many_inputs.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = public_key("1111", "2222"))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/public_key_value_node/too_many_inputs.fail.stderr: -------------------------------------------------------------------------------- 1 | error: public_key is already set 2 | --> tests/codama_attribute/values_nodes/public_key_value_node/too_many_inputs.fail.rs:3:45 3 | | 4 | 3 | #[codama(default_value = public_key("1111", "2222"))] 5 | | ^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/string_value_node/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = "hello world")] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/sysvar/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = sysvar("rent"))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/sysvar/invalid_input.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = sysvar(42))] 4 | pub struct TestWithInteger; 5 | 6 | #[codama(default_value = sysvar(banana))] 7 | pub struct TestWithPath; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/sysvar/invalid_input.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a string 2 | --> tests/codama_attribute/values_nodes/sysvar/invalid_input.fail.rs:3:33 3 | | 4 | 3 | #[codama(default_value = sysvar(42))] 5 | | ^^ 6 | 7 | error: expected a string 8 | --> tests/codama_attribute/values_nodes/sysvar/invalid_input.fail.rs:6:33 9 | | 10 | 6 | #[codama(default_value = sysvar(banana))] 11 | | ^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/sysvar/no_input.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = sysvar)] 4 | pub struct Test; 5 | 6 | #[codama(default_value = sysvar())] 7 | pub struct TestWithParenthesis; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/sysvar/no_input.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a list: `sysvar(...)` or `sysvar = (...)` 2 | --> tests/codama_attribute/values_nodes/sysvar/no_input.fail.rs:3:26 3 | | 4 | 3 | #[codama(default_value = sysvar)] 5 | | ^^^^^^ 6 | 7 | error: sysvar_identifier is missing 8 | --> tests/codama_attribute/values_nodes/sysvar/no_input.fail.rs:6:26 9 | | 10 | 6 | #[codama(default_value = sysvar())] 11 | | ^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/sysvar/too_many_inputs.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = sysvar("rent", "clock"))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/sysvar/too_many_inputs.fail.stderr: -------------------------------------------------------------------------------- 1 | error: sysvar_identifier is already set 2 | --> tests/codama_attribute/values_nodes/sysvar/too_many_inputs.fail.rs:3:41 3 | | 4 | 3 | #[codama(default_value = sysvar("rent", "clock"))] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/sysvar/unrecognized_sysvar.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::codama; 2 | 3 | #[codama(default_value = sysvar("banana"))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_attribute/values_nodes/sysvar/unrecognized_sysvar.fail.stderr: -------------------------------------------------------------------------------- 1 | error: unrecognized sysvar 2 | --> tests/codama_attribute/values_nodes/sysvar/unrecognized_sysvar.fail.rs:3:33 3 | | 4 | 3 | #[codama(default_value = sysvar("banana"))] 5 | | ^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_errors_derive/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::CodamaErrors; 2 | 3 | #[derive(CodamaErrors)] 4 | pub enum MyProgramErrors { 5 | WrongArgument, 6 | WrongAccount, 7 | } 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_instruction_derive/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::CodamaInstruction; 2 | 3 | #[derive(CodamaInstruction)] 4 | pub struct StructTest; 5 | 6 | #[derive(CodamaInstruction)] 7 | pub enum EnumTest {} 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_instruction_derive/multiple_types.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::{codama, CodamaInstruction}; 2 | 3 | #[derive(CodamaInstruction)] 4 | #[codama(type = boolean)] 5 | #[derive(PartialEq)] 6 | #[codama(type = public_key)] 7 | #[derive(Debug)] 8 | #[codama(type = number(u32))] 9 | pub struct StructTest { 10 | #[codama(type = boolean)] 11 | #[codama(type = public_key)] 12 | pub field: u32, 13 | } 14 | 15 | #[derive(CodamaInstruction)] 16 | #[codama(type = boolean)] 17 | #[codama(type = public_key)] 18 | pub enum EnumTest { 19 | #[codama(type = boolean)] 20 | #[codama(type = public_key)] 21 | Variant { 22 | #[codama(type = boolean)] 23 | #[codama(type = public_key)] 24 | field: u32, 25 | }, 26 | } 27 | 28 | fn main() {} 29 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_instruction_derive/multiple_types.fail.stderr: -------------------------------------------------------------------------------- 1 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 2 | --> tests/codama_instruction_derive/multiple_types.fail.rs:6:1 3 | | 4 | 6 | #[codama(type = public_key)] 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | 7 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 8 | --> tests/codama_instruction_derive/multiple_types.fail.rs:4:1 9 | | 10 | 4 | #[codama(type = boolean)] 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 12 | 13 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 14 | --> tests/codama_instruction_derive/multiple_types.fail.rs:10:5 15 | | 16 | 10 | #[codama(type = boolean)] 17 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 18 | 19 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 20 | --> tests/codama_instruction_derive/multiple_types.fail.rs:16:1 21 | | 22 | 16 | #[codama(type = boolean)] 23 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 24 | 25 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 26 | --> tests/codama_instruction_derive/multiple_types.fail.rs:19:5 27 | | 28 | 19 | #[codama(type = boolean)] 29 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 30 | 31 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 32 | --> tests/codama_instruction_derive/multiple_types.fail.rs:22:9 33 | | 34 | 22 | #[codama(type = boolean)] 35 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 36 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_instructions_derive/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::CodamaInstructions; 2 | 3 | #[derive(CodamaInstructions)] 4 | pub enum TokenInstructions { 5 | InitializeMint {}, 6 | InitializeToken {}, 7 | Transfer {}, 8 | } 9 | 10 | fn main() {} 11 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_type_derive/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::CodamaType; 2 | 3 | #[derive(CodamaType)] 4 | pub struct StructTest; 5 | 6 | #[derive(CodamaType)] 7 | pub enum EnumTest {} 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_type_derive/multiple_types.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_macros::{codama, CodamaType}; 2 | 3 | #[derive(CodamaType)] 4 | #[codama(type = boolean)] 5 | #[derive(PartialEq)] 6 | #[codama(type = public_key)] 7 | #[derive(Debug)] 8 | #[codama(type = number(u32))] 9 | pub struct StructTest { 10 | #[codama(type = boolean)] 11 | #[codama(type = public_key)] 12 | pub field: u32, 13 | } 14 | 15 | #[derive(CodamaType)] 16 | #[codama(type = boolean)] 17 | #[codama(type = public_key)] 18 | pub enum EnumTest { 19 | #[codama(type = boolean)] 20 | #[codama(type = public_key)] 21 | Variant { 22 | #[codama(type = boolean)] 23 | #[codama(type = public_key)] 24 | field: u32, 25 | }, 26 | } 27 | 28 | fn main() {} 29 | -------------------------------------------------------------------------------- /codama-macros/tests/codama_type_derive/multiple_types.fail.stderr: -------------------------------------------------------------------------------- 1 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 2 | --> tests/codama_type_derive/multiple_types.fail.rs:6:1 3 | | 4 | 6 | #[codama(type = public_key)] 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | 7 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 8 | --> tests/codama_type_derive/multiple_types.fail.rs:4:1 9 | | 10 | 4 | #[codama(type = boolean)] 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 12 | 13 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 14 | --> tests/codama_type_derive/multiple_types.fail.rs:10:5 15 | | 16 | 10 | #[codama(type = boolean)] 17 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 18 | 19 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 20 | --> tests/codama_type_derive/multiple_types.fail.rs:16:1 21 | | 22 | 16 | #[codama(type = boolean)] 23 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 24 | 25 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 26 | --> tests/codama_type_derive/multiple_types.fail.rs:19:5 27 | | 28 | 19 | #[codama(type = boolean)] 29 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 30 | 31 | error: This attribute is overridden by a `#[codama(type = ...)]` attribute below 32 | --> tests/codama_type_derive/multiple_types.fail.rs:22:9 33 | | 34 | 22 | #[codama(type = boolean)] 35 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 36 | -------------------------------------------------------------------------------- /codama-macros/tests/mod.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn tests() { 3 | let t = trybuild::TestCases::new(); 4 | t.pass("tests/**/_pass.rs"); 5 | t.pass("tests/**/*.pass.rs"); 6 | t.compile_fail("tests/**/*.fail.rs"); 7 | } 8 | -------------------------------------------------------------------------------- /codama-nodes/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-nodes/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama-nodes" 3 | description = "Node specifications and helpers for the Codama standard" 4 | version = "0.4.0" 5 | repository = { workspace = true } 6 | edition = { workspace = true } 7 | license = { workspace = true } 8 | 9 | [dependencies] 10 | codama-errors = { version = "0.4.0", path = "../codama-errors" } 11 | codama-nodes-derive = { version = "0.4.0", path = "derive" } 12 | derive_more = { version = "1.0", features = ["from"] } 13 | serde = { version = "1.0", features = ["derive"] } 14 | serde_json = "1.0" 15 | 16 | [dev-dependencies] 17 | pretty_assertions = "1.4.1" 18 | -------------------------------------------------------------------------------- /codama-nodes/derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama-nodes-derive" 3 | description = "Derive macros for Codama nodes" 4 | version = "0.4.0" 5 | repository = { workspace = true } 6 | edition = { workspace = true } 7 | license = { workspace = true } 8 | 9 | [lib] 10 | proc-macro = true 11 | 12 | [dependencies] 13 | codama-errors = { version = "0.4.0", path = "../../codama-errors" } 14 | codama-syn-helpers = { version = "0.4.0", path = "../../codama-syn-helpers" } 15 | derive_more = { version = "1.0", features = ["from"] } 16 | syn = { version = "2.0", features = ["extra-traits"] } 17 | quote = "1.0" 18 | proc-macro2 = "1.0" 19 | -------------------------------------------------------------------------------- /codama-nodes/derive/src/node.rs: -------------------------------------------------------------------------------- 1 | use crate::lowercase_first_letter; 2 | use codama_errors::CodamaResult; 3 | use codama_syn_helpers::extensions::*; 4 | use proc_macro2::TokenStream; 5 | use quote::quote; 6 | 7 | pub fn expand_attribute_node(input: &syn::DeriveInput) -> CodamaResult { 8 | input.as_struct()?; 9 | let item_name = &input.ident; 10 | let kind = lowercase_first_letter(&item_name.to_string()); 11 | 12 | Ok(quote! { 13 | #[derive(codama_nodes_derive::Node, core::fmt::Debug, core::cmp::PartialEq, core::clone::Clone, serde::Serialize, serde::Deserialize)] 14 | #[serde(tag = "kind", rename = #kind)] 15 | #[serde(rename_all = "camelCase")] 16 | #input 17 | }) 18 | } 19 | 20 | pub fn expand_derive_node(input: &syn::DeriveInput) -> CodamaResult { 21 | input.as_struct()?; 22 | let item_name = &input.ident; 23 | let (pre_generics, post_generics) = &input.generics.block_wrappers(); 24 | let kind = lowercase_first_letter(&item_name.to_string()); 25 | 26 | Ok(quote! { 27 | impl #pre_generics crate::NodeTrait for #item_name #post_generics{ 28 | const KIND: &'static str = #kind; 29 | } 30 | 31 | impl #pre_generics crate::HasKind for #item_name #post_generics{ 32 | fn kind(&self) -> &'static str { 33 | ::KIND 34 | } 35 | } 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /codama-nodes/derive/src/utils.rs: -------------------------------------------------------------------------------- 1 | pub fn lowercase_first_letter(s: &str) -> String { 2 | let mut c = s.chars(); 3 | match c.next() { 4 | None => String::new(), 5 | Some(first) => first.to_lowercase().collect::() + c.as_str(), 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /codama-nodes/src/contextual_value_nodes/account_bump_value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::CamelCaseString; 2 | use codama_nodes_derive::node; 3 | 4 | #[node] 5 | pub struct AccountBumpValueNode { 6 | // Data. 7 | pub name: CamelCaseString, 8 | } 9 | 10 | impl From for crate::Node { 11 | fn from(val: AccountBumpValueNode) -> Self { 12 | crate::Node::ContextualValue(val.into()) 13 | } 14 | } 15 | 16 | impl AccountBumpValueNode { 17 | pub fn new(name: T) -> Self 18 | where 19 | T: Into, 20 | { 21 | Self { name: name.into() } 22 | } 23 | } 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | use super::*; 28 | 29 | #[test] 30 | fn new() { 31 | let node = AccountBumpValueNode::new("my_account"); 32 | assert_eq!(node.name, CamelCaseString::new("myAccount")); 33 | } 34 | 35 | #[test] 36 | fn to_json() { 37 | let node = AccountBumpValueNode::new("myAccount"); 38 | let json = serde_json::to_string(&node).unwrap(); 39 | assert_eq!( 40 | json, 41 | r#"{"kind":"accountBumpValueNode","name":"myAccount"}"# 42 | ); 43 | } 44 | 45 | #[test] 46 | fn from_json() { 47 | let json = r#"{"kind":"accountBumpValueNode","name":"myAccount"}"#; 48 | let node: AccountBumpValueNode = serde_json::from_str(json).unwrap(); 49 | assert_eq!(node, AccountBumpValueNode::new("myAccount")); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /codama-nodes/src/contextual_value_nodes/account_value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::CamelCaseString; 2 | use codama_nodes_derive::node; 3 | 4 | #[node] 5 | pub struct AccountValueNode { 6 | // Data. 7 | pub name: CamelCaseString, 8 | } 9 | 10 | impl From for crate::Node { 11 | fn from(val: AccountValueNode) -> Self { 12 | crate::Node::ContextualValue(val.into()) 13 | } 14 | } 15 | 16 | impl AccountValueNode { 17 | pub fn new(name: T) -> Self 18 | where 19 | T: Into, 20 | { 21 | Self { name: name.into() } 22 | } 23 | } 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | use super::*; 28 | 29 | #[test] 30 | fn new() { 31 | let node = AccountValueNode::new("my_account"); 32 | assert_eq!(node.name, CamelCaseString::new("myAccount")); 33 | } 34 | 35 | #[test] 36 | fn to_json() { 37 | let node = AccountValueNode::new("myAccount"); 38 | let json = serde_json::to_string(&node).unwrap(); 39 | assert_eq!(json, r#"{"kind":"accountValueNode","name":"myAccount"}"#); 40 | } 41 | 42 | #[test] 43 | fn from_json() { 44 | let json = r#"{"kind":"accountValueNode","name":"myAccount"}"#; 45 | let node: AccountValueNode = serde_json::from_str(json).unwrap(); 46 | assert_eq!(node, AccountValueNode::new("myAccount")); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /codama-nodes/src/contextual_value_nodes/argument_value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::CamelCaseString; 2 | use codama_nodes_derive::node; 3 | 4 | #[node] 5 | pub struct ArgumentValueNode { 6 | // Data. 7 | pub name: CamelCaseString, 8 | } 9 | 10 | impl From for crate::Node { 11 | fn from(val: ArgumentValueNode) -> Self { 12 | crate::Node::ContextualValue(val.into()) 13 | } 14 | } 15 | 16 | impl ArgumentValueNode { 17 | pub fn new(name: T) -> Self 18 | where 19 | T: Into, 20 | { 21 | Self { name: name.into() } 22 | } 23 | } 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | use super::*; 28 | 29 | #[test] 30 | fn new() { 31 | let node = ArgumentValueNode::new("my_argument"); 32 | assert_eq!(node.name, CamelCaseString::new("myArgument")); 33 | } 34 | 35 | #[test] 36 | fn to_json() { 37 | let node = ArgumentValueNode::new("myArgument"); 38 | let json = serde_json::to_string(&node).unwrap(); 39 | assert_eq!(json, r#"{"kind":"argumentValueNode","name":"myArgument"}"#); 40 | } 41 | 42 | #[test] 43 | fn from_json() { 44 | let json = r#"{"kind":"argumentValueNode","name":"myArgument"}"#; 45 | let node: ArgumentValueNode = serde_json::from_str(json).unwrap(); 46 | assert_eq!(node, ArgumentValueNode::new("myArgument")); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /codama-nodes/src/contextual_value_nodes/contextual_value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | AccountBumpValueNode, AccountValueNode, ArgumentValueNode, ConditionalValueNode, HasKind, 3 | IdentityValueNode, PayerValueNode, PdaSeedValueNode, PdaValueNode, ProgramIdValueNode, 4 | ResolverValueNode, 5 | }; 6 | use codama_nodes_derive::{node_union, RegisteredNodes}; 7 | 8 | #[derive(RegisteredNodes)] 9 | #[node_union] 10 | pub enum RegisteredContextualValueNode { 11 | Account(AccountValueNode), 12 | AccountBump(AccountBumpValueNode), 13 | Argument(ArgumentValueNode), 14 | Conditional(ConditionalValueNode), 15 | Identity(IdentityValueNode), 16 | Payer(PayerValueNode), 17 | Pda(PdaValueNode), 18 | ProgramId(ProgramIdValueNode), 19 | Resolver(ResolverValueNode), 20 | 21 | #[registered] 22 | PdaSeed(PdaSeedValueNode), 23 | } 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | use super::*; 28 | 29 | #[test] 30 | fn kind_from_standalone() { 31 | let node: ContextualValueNode = ProgramIdValueNode::new().into(); 32 | assert_eq!(node.kind(), "programIdValueNode"); 33 | } 34 | 35 | #[test] 36 | fn kind_from_registered() { 37 | let node: RegisteredContextualValueNode = ProgramIdValueNode::new().into(); 38 | assert_eq!(node.kind(), "programIdValueNode"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /codama-nodes/src/contextual_value_nodes/identity_value_node.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes_derive::node; 2 | 3 | #[node] 4 | #[derive(Default)] 5 | pub struct IdentityValueNode {} 6 | 7 | impl From for crate::Node { 8 | fn from(val: IdentityValueNode) -> Self { 9 | crate::Node::ContextualValue(val.into()) 10 | } 11 | } 12 | 13 | impl IdentityValueNode { 14 | pub fn new() -> Self { 15 | Self::default() 16 | } 17 | } 18 | 19 | #[cfg(test)] 20 | mod tests { 21 | use super::*; 22 | 23 | #[test] 24 | fn new() { 25 | let node = IdentityValueNode::new(); 26 | assert_eq!(node, IdentityValueNode {}); 27 | } 28 | 29 | #[test] 30 | fn to_json() { 31 | let node = IdentityValueNode::new(); 32 | let json = serde_json::to_string(&node).unwrap(); 33 | assert_eq!(json, r#"{"kind":"identityValueNode"}"#); 34 | } 35 | 36 | #[test] 37 | fn from_json() { 38 | let json = r#"{"kind":"identityValueNode"}"#; 39 | let node: IdentityValueNode = serde_json::from_str(json).unwrap(); 40 | assert_eq!(node, IdentityValueNode::new()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /codama-nodes/src/contextual_value_nodes/mod.rs: -------------------------------------------------------------------------------- 1 | mod account_bump_value_node; 2 | mod account_value_node; 3 | mod argument_value_node; 4 | mod conditional_value_node; 5 | mod contextual_value_node; 6 | mod identity_value_node; 7 | mod payer_value_node; 8 | mod pda_seed_value_node; 9 | mod pda_value_node; 10 | mod program_id_value_node; 11 | mod resolver_value_node; 12 | 13 | pub use account_bump_value_node::*; 14 | pub use account_value_node::*; 15 | pub use argument_value_node::*; 16 | pub use conditional_value_node::*; 17 | pub use contextual_value_node::*; 18 | pub use identity_value_node::*; 19 | pub use payer_value_node::*; 20 | pub use pda_seed_value_node::*; 21 | pub use pda_value_node::*; 22 | pub use program_id_value_node::*; 23 | pub use resolver_value_node::*; 24 | -------------------------------------------------------------------------------- /codama-nodes/src/contextual_value_nodes/payer_value_node.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes_derive::node; 2 | 3 | #[node] 4 | #[derive(Default)] 5 | pub struct PayerValueNode {} 6 | 7 | impl From for crate::Node { 8 | fn from(val: PayerValueNode) -> Self { 9 | crate::Node::ContextualValue(val.into()) 10 | } 11 | } 12 | 13 | impl PayerValueNode { 14 | pub fn new() -> Self { 15 | Self::default() 16 | } 17 | } 18 | 19 | #[cfg(test)] 20 | mod tests { 21 | use super::*; 22 | 23 | #[test] 24 | fn new() { 25 | let node = PayerValueNode::new(); 26 | assert_eq!(node, PayerValueNode {}); 27 | } 28 | 29 | #[test] 30 | fn to_json() { 31 | let node = PayerValueNode::new(); 32 | let json = serde_json::to_string(&node).unwrap(); 33 | assert_eq!(json, r#"{"kind":"payerValueNode"}"#); 34 | } 35 | 36 | #[test] 37 | fn from_json() { 38 | let json = r#"{"kind":"payerValueNode"}"#; 39 | let node: PayerValueNode = serde_json::from_str(json).unwrap(); 40 | assert_eq!(node, PayerValueNode::new()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /codama-nodes/src/contextual_value_nodes/program_id_value_node.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes_derive::node; 2 | 3 | #[node] 4 | #[derive(Default)] 5 | pub struct ProgramIdValueNode {} 6 | 7 | impl From for crate::Node { 8 | fn from(val: ProgramIdValueNode) -> Self { 9 | crate::Node::ContextualValue(val.into()) 10 | } 11 | } 12 | 13 | impl ProgramIdValueNode { 14 | pub fn new() -> Self { 15 | Self::default() 16 | } 17 | } 18 | 19 | #[cfg(test)] 20 | mod tests { 21 | use super::*; 22 | 23 | #[test] 24 | fn new() { 25 | let node = ProgramIdValueNode::new(); 26 | assert_eq!(node, ProgramIdValueNode {}); 27 | } 28 | 29 | #[test] 30 | fn to_json() { 31 | let node = ProgramIdValueNode::new(); 32 | let json = serde_json::to_string(&node).unwrap(); 33 | assert_eq!(json, r#"{"kind":"programIdValueNode"}"#); 34 | } 35 | 36 | #[test] 37 | fn from_json() { 38 | let json = r#"{"kind":"programIdValueNode"}"#; 39 | let node: ProgramIdValueNode = serde_json::from_str(json).unwrap(); 40 | assert_eq!(node, ProgramIdValueNode::new()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /codama-nodes/src/count_nodes/count_node.rs: -------------------------------------------------------------------------------- 1 | use crate::{FixedCountNode, PrefixedCountNode, RemainderCountNode}; 2 | use codama_nodes_derive::node_union; 3 | 4 | #[node_union] 5 | pub enum CountNode { 6 | Fixed(FixedCountNode), 7 | Prefixed(PrefixedCountNode), 8 | Remainder(RemainderCountNode), 9 | } 10 | 11 | #[cfg(test)] 12 | mod tests { 13 | use super::*; 14 | use crate::HasKind; 15 | 16 | #[test] 17 | fn kind() { 18 | let node: CountNode = RemainderCountNode::new().into(); 19 | assert_eq!(node.kind(), "remainderCountNode"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /codama-nodes/src/count_nodes/fixed_count_node.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes_derive::node; 2 | 3 | #[node] 4 | pub struct FixedCountNode { 5 | // Data. 6 | pub value: usize, 7 | } 8 | 9 | impl From for crate::Node { 10 | fn from(val: FixedCountNode) -> Self { 11 | crate::Node::Count(val.into()) 12 | } 13 | } 14 | 15 | impl FixedCountNode { 16 | pub fn new(value: usize) -> Self { 17 | Self { value } 18 | } 19 | } 20 | 21 | #[cfg(test)] 22 | mod tests { 23 | use super::*; 24 | 25 | #[test] 26 | fn new() { 27 | let node = FixedCountNode::new(42); 28 | assert_eq!(node.value, 42); 29 | } 30 | 31 | #[test] 32 | fn to_json() { 33 | let node = FixedCountNode::new(42); 34 | let json = serde_json::to_string(&node).unwrap(); 35 | assert_eq!(json, r#"{"kind":"fixedCountNode","value":42}"#); 36 | } 37 | 38 | #[test] 39 | fn from_json() { 40 | let json = r#"{"kind":"fixedCountNode","value":42}"#; 41 | let node: FixedCountNode = serde_json::from_str(json).unwrap(); 42 | assert_eq!(node, FixedCountNode::new(42)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /codama-nodes/src/count_nodes/mod.rs: -------------------------------------------------------------------------------- 1 | mod count_node; 2 | mod fixed_count_node; 3 | mod prefixed_count_node; 4 | mod remainder_count_node; 5 | 6 | pub use count_node::*; 7 | pub use fixed_count_node::*; 8 | pub use prefixed_count_node::*; 9 | pub use remainder_count_node::*; 10 | -------------------------------------------------------------------------------- /codama-nodes/src/count_nodes/remainder_count_node.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes_derive::node; 2 | 3 | #[node] 4 | #[derive(Default)] 5 | pub struct RemainderCountNode {} 6 | 7 | impl From for crate::Node { 8 | fn from(val: RemainderCountNode) -> Self { 9 | crate::Node::Count(val.into()) 10 | } 11 | } 12 | 13 | impl RemainderCountNode { 14 | pub fn new() -> Self { 15 | Self::default() 16 | } 17 | } 18 | 19 | #[cfg(test)] 20 | mod tests { 21 | use super::*; 22 | 23 | #[test] 24 | fn new() { 25 | let node = RemainderCountNode::new(); 26 | assert_eq!(node, RemainderCountNode {}); 27 | } 28 | 29 | #[test] 30 | fn to_json() { 31 | let node = RemainderCountNode::new(); 32 | let json = serde_json::to_string(&node).unwrap(); 33 | assert_eq!(json, r#"{"kind":"remainderCountNode"}"#); 34 | } 35 | 36 | #[test] 37 | fn from_json() { 38 | let json = r#"{"kind":"remainderCountNode"}"#; 39 | let node: RemainderCountNode = serde_json::from_str(json).unwrap(); 40 | assert_eq!(node, RemainderCountNode::new()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /codama-nodes/src/discriminator_nodes/discriminator_node.rs: -------------------------------------------------------------------------------- 1 | use crate::{ConstantDiscriminatorNode, FieldDiscriminatorNode, SizeDiscriminatorNode}; 2 | use codama_nodes_derive::node_union; 3 | 4 | #[node_union] 5 | pub enum DiscriminatorNode { 6 | Constant(ConstantDiscriminatorNode), 7 | Field(FieldDiscriminatorNode), 8 | Size(SizeDiscriminatorNode), 9 | } 10 | 11 | #[cfg(test)] 12 | mod tests { 13 | use super::*; 14 | use crate::HasKind; 15 | 16 | #[test] 17 | fn kind() { 18 | let node: DiscriminatorNode = SizeDiscriminatorNode::new(42).into(); 19 | assert_eq!(node.kind(), "sizeDiscriminatorNode"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /codama-nodes/src/discriminator_nodes/field_discriminator_node.rs: -------------------------------------------------------------------------------- 1 | use crate::CamelCaseString; 2 | use codama_nodes_derive::node; 3 | 4 | #[node] 5 | pub struct FieldDiscriminatorNode { 6 | // Data. 7 | pub name: CamelCaseString, 8 | pub offset: usize, 9 | } 10 | 11 | impl From for crate::Node { 12 | fn from(val: FieldDiscriminatorNode) -> Self { 13 | crate::Node::Discriminator(val.into()) 14 | } 15 | } 16 | 17 | impl FieldDiscriminatorNode { 18 | pub fn new(name: T, offset: usize) -> Self 19 | where 20 | T: Into, 21 | { 22 | Self { 23 | name: name.into(), 24 | offset, 25 | } 26 | } 27 | } 28 | 29 | #[cfg(test)] 30 | mod tests { 31 | use super::*; 32 | 33 | #[test] 34 | fn new() { 35 | let node = FieldDiscriminatorNode::new("my_field", 0); 36 | assert_eq!(node.name, CamelCaseString::new("myField")); 37 | assert_eq!(node.offset, 0); 38 | } 39 | 40 | #[test] 41 | fn to_json() { 42 | let node = FieldDiscriminatorNode::new("myField", 0); 43 | let json = serde_json::to_string(&node).unwrap(); 44 | assert_eq!( 45 | json, 46 | r#"{"kind":"fieldDiscriminatorNode","name":"myField","offset":0}"# 47 | ); 48 | } 49 | 50 | #[test] 51 | fn from_json() { 52 | let json = r#"{"kind":"fieldDiscriminatorNode","name":"myField","offset":0}"#; 53 | let node: FieldDiscriminatorNode = serde_json::from_str(json).unwrap(); 54 | assert_eq!(node, FieldDiscriminatorNode::new("myField", 0)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /codama-nodes/src/discriminator_nodes/mod.rs: -------------------------------------------------------------------------------- 1 | mod constant_discriminator_node; 2 | mod discriminator_node; 3 | mod field_discriminator_node; 4 | mod size_discriminator_node; 5 | 6 | pub use constant_discriminator_node::*; 7 | pub use discriminator_node::*; 8 | pub use field_discriminator_node::*; 9 | pub use size_discriminator_node::*; 10 | -------------------------------------------------------------------------------- /codama-nodes/src/discriminator_nodes/size_discriminator_node.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes_derive::node; 2 | 3 | #[node] 4 | pub struct SizeDiscriminatorNode { 5 | // Data. 6 | pub size: usize, 7 | } 8 | 9 | impl From for crate::Node { 10 | fn from(val: SizeDiscriminatorNode) -> Self { 11 | crate::Node::Discriminator(val.into()) 12 | } 13 | } 14 | 15 | impl SizeDiscriminatorNode { 16 | pub fn new(size: usize) -> Self { 17 | Self { size } 18 | } 19 | } 20 | 21 | #[cfg(test)] 22 | mod tests { 23 | use super::*; 24 | 25 | #[test] 26 | fn new() { 27 | let node = SizeDiscriminatorNode::new(42); 28 | assert_eq!(node.size, 42); 29 | } 30 | 31 | #[test] 32 | fn to_json() { 33 | let node = SizeDiscriminatorNode::new(42); 34 | let json = serde_json::to_string(&node).unwrap(); 35 | assert_eq!(json, r#"{"kind":"sizeDiscriminatorNode","size":42}"#); 36 | } 37 | 38 | #[test] 39 | fn from_json() { 40 | let json = r#"{"kind":"sizeDiscriminatorNode","size":42}"#; 41 | let node: SizeDiscriminatorNode = serde_json::from_str(json).unwrap(); 42 | assert_eq!(node, SizeDiscriminatorNode::new(42)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /codama-nodes/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod account_node; 2 | mod contextual_value_nodes; 3 | mod count_nodes; 4 | mod defined_type_node; 5 | mod discriminator_nodes; 6 | mod error_node; 7 | mod instruction_account_node; 8 | mod instruction_argument_node; 9 | mod instruction_byte_delta_node; 10 | mod instruction_node; 11 | mod instruction_remaining_accounts_node; 12 | mod link_nodes; 13 | mod node; 14 | mod pda_node; 15 | mod pda_seed_nodes; 16 | mod program_node; 17 | mod root_node; 18 | mod shared; 19 | mod traits; 20 | mod type_nodes; 21 | mod value_nodes; 22 | 23 | pub use account_node::*; 24 | pub use contextual_value_nodes::*; 25 | pub use count_nodes::*; 26 | pub use defined_type_node::*; 27 | pub use discriminator_nodes::*; 28 | pub use error_node::*; 29 | pub use instruction_account_node::*; 30 | pub use instruction_argument_node::*; 31 | pub use instruction_byte_delta_node::*; 32 | pub use instruction_node::*; 33 | pub use instruction_remaining_accounts_node::*; 34 | pub use link_nodes::*; 35 | pub use node::*; 36 | pub use pda_node::*; 37 | pub use pda_seed_nodes::*; 38 | pub use program_node::*; 39 | pub use root_node::*; 40 | pub use shared::*; 41 | pub use traits::*; 42 | pub use type_nodes::*; 43 | pub use value_nodes::*; 44 | 45 | // Serde helper function to use with `#[serde(some_thing = "crate::is_default")]`. 46 | fn is_default(t: &T) -> bool { 47 | t == &T::default() 48 | } 49 | -------------------------------------------------------------------------------- /codama-nodes/src/link_nodes/link_node.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | AccountLinkNode, DefinedTypeLinkNode, InstructionAccountLinkNode, InstructionArgumentLinkNode, 3 | InstructionLinkNode, PdaLinkNode, ProgramLinkNode, 4 | }; 5 | use codama_nodes_derive::node_union; 6 | 7 | #[node_union] 8 | pub enum LinkNode { 9 | Account(AccountLinkNode), 10 | DefinedType(DefinedTypeLinkNode), 11 | Instruction(InstructionLinkNode), 12 | InstructionAccount(InstructionAccountLinkNode), 13 | InstructionArgument(InstructionArgumentLinkNode), 14 | Pda(PdaLinkNode), 15 | Program(ProgramLinkNode), 16 | } 17 | 18 | #[cfg(test)] 19 | mod tests { 20 | use super::*; 21 | use crate::HasKind; 22 | 23 | #[test] 24 | fn kind() { 25 | let node: LinkNode = ProgramLinkNode::new("myProgram").into(); 26 | assert_eq!(node.kind(), "programLinkNode"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /codama-nodes/src/link_nodes/mod.rs: -------------------------------------------------------------------------------- 1 | mod account_link_node; 2 | mod defined_type_link_node; 3 | mod instruction_account_link_node; 4 | mod instruction_argument_link_node; 5 | mod instruction_link_node; 6 | mod link_node; 7 | mod pda_link_node; 8 | mod program_link_node; 9 | 10 | pub use account_link_node::*; 11 | pub use defined_type_link_node::*; 12 | pub use instruction_account_link_node::*; 13 | pub use instruction_argument_link_node::*; 14 | pub use instruction_link_node::*; 15 | pub use link_node::*; 16 | pub use pda_link_node::*; 17 | pub use program_link_node::*; 18 | -------------------------------------------------------------------------------- /codama-nodes/src/pda_seed_nodes/mod.rs: -------------------------------------------------------------------------------- 1 | mod constant_pda_seed_node; 2 | mod pda_seed_node; 3 | mod variable_pda_seed_node; 4 | 5 | pub use constant_pda_seed_node::*; 6 | pub use pda_seed_node::*; 7 | pub use variable_pda_seed_node::*; 8 | -------------------------------------------------------------------------------- /codama-nodes/src/pda_seed_nodes/pda_seed_node.rs: -------------------------------------------------------------------------------- 1 | use crate::{ConstantPdaSeedNode, VariablePdaSeedNode}; 2 | use codama_nodes_derive::node_union; 3 | 4 | #[node_union] 5 | pub enum PdaSeedNode { 6 | Constant(ConstantPdaSeedNode), 7 | Variable(VariablePdaSeedNode), 8 | } 9 | 10 | #[cfg(test)] 11 | mod tests { 12 | use super::*; 13 | use crate::{HasKind, NumberTypeNode, NumberValueNode, U8}; 14 | 15 | #[test] 16 | fn kind() { 17 | let node: PdaSeedNode = 18 | ConstantPdaSeedNode::new(NumberTypeNode::le(U8), NumberValueNode::new(42u8)).into(); 19 | assert_eq!(node.kind(), "constantPdaSeedNode"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /codama-nodes/src/shared/bytes_encoding.rs: -------------------------------------------------------------------------------- 1 | use codama_errors::{CodamaError, CodamaResult}; 2 | use serde::{Deserialize, Serialize}; 3 | pub use BytesEncoding::*; 4 | 5 | #[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] 6 | #[serde(rename_all = "camelCase")] 7 | pub enum BytesEncoding { 8 | Base16, 9 | Base58, 10 | Base64, 11 | Utf8, 12 | } 13 | 14 | impl TryFrom for BytesEncoding { 15 | type Error = CodamaError; 16 | 17 | fn try_from(value: String) -> CodamaResult { 18 | value.as_str().try_into() 19 | } 20 | } 21 | 22 | impl TryFrom<&str> for BytesEncoding { 23 | type Error = CodamaError; 24 | 25 | fn try_from(value: &str) -> CodamaResult { 26 | match value { 27 | "base16" => Ok(Base16), 28 | "base58" => Ok(Base58), 29 | "base64" => Ok(Base64), 30 | "utf8" => Ok(Utf8), 31 | _ => Err(CodamaError::InvalidBytesEncoding(value.to_string())), 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /codama-nodes/src/shared/default_value_strategy.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] 4 | #[serde(rename_all = "camelCase")] 5 | pub enum DefaultValueStrategy { 6 | Omitted, 7 | Optional, 8 | } 9 | -------------------------------------------------------------------------------- /codama-nodes/src/shared/mod.rs: -------------------------------------------------------------------------------- 1 | mod bytes_encoding; 2 | mod camel_case_string; 3 | mod default_value_strategy; 4 | mod docs; 5 | mod instruction_input_value_node; 6 | mod is_account_signer; 7 | 8 | pub use bytes_encoding::*; 9 | pub use camel_case_string::*; 10 | pub use default_value_strategy::*; 11 | pub use docs::*; 12 | pub use instruction_input_value_node::*; 13 | pub use is_account_signer::*; 14 | -------------------------------------------------------------------------------- /codama-nodes/src/traits.rs: -------------------------------------------------------------------------------- 1 | use codama_errors::CodamaResult; 2 | use std::fmt::Debug; 3 | 4 | pub trait NodeTrait: 5 | HasKind + Debug + PartialEq + Clone + serde::Serialize + for<'de> serde::Deserialize<'de> 6 | { 7 | const KIND: &'static str; 8 | 9 | fn to_json(&self) -> CodamaResult { 10 | serde_json::to_string(&self).map_err(Into::into) 11 | } 12 | 13 | fn to_json_pretty(&self) -> CodamaResult { 14 | serde_json::to_string_pretty(&self).map_err(Into::into) 15 | } 16 | 17 | fn from_json(json: &str) -> CodamaResult { 18 | serde_json::from_str(json).map_err(Into::into) 19 | } 20 | } 21 | 22 | pub trait NodeUnionTrait: 23 | HasKind + Debug + PartialEq + Clone + serde::Serialize + for<'de> serde::Deserialize<'de> 24 | { 25 | } 26 | 27 | pub trait HasKind { 28 | fn kind(&self) -> &'static str; 29 | } 30 | -------------------------------------------------------------------------------- /codama-nodes/src/type_nodes/bytes_type_node.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes_derive::type_node; 2 | 3 | #[type_node] 4 | #[derive(Default)] 5 | pub struct BytesTypeNode {} 6 | 7 | impl BytesTypeNode { 8 | pub fn new() -> Self { 9 | Self::default() 10 | } 11 | } 12 | 13 | impl From for crate::Node { 14 | fn from(val: BytesTypeNode) -> Self { 15 | crate::Node::Type(val.into()) 16 | } 17 | } 18 | 19 | #[cfg(test)] 20 | mod tests { 21 | use super::*; 22 | 23 | #[test] 24 | fn new() { 25 | let node = BytesTypeNode::new(); 26 | assert_eq!(node, BytesTypeNode {}); 27 | } 28 | 29 | #[test] 30 | fn to_json() { 31 | let node = BytesTypeNode::new(); 32 | let json = serde_json::to_string(&node).unwrap(); 33 | assert_eq!(json, r#"{"kind":"bytesTypeNode"}"#); 34 | } 35 | 36 | #[test] 37 | fn from_json() { 38 | let json = r#"{"kind":"bytesTypeNode"}"#; 39 | let node: BytesTypeNode = serde_json::from_str(json).unwrap(); 40 | assert_eq!(node, BytesTypeNode::new()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /codama-nodes/src/type_nodes/enum_variant_type_node.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | EnumEmptyVariantTypeNode, EnumStructVariantTypeNode, EnumTupleVariantTypeNode, HasKind, Node, 3 | RegisteredTypeNode, 4 | }; 5 | use codama_errors::CodamaError; 6 | use codama_nodes_derive::node_union; 7 | 8 | #[node_union] 9 | pub enum EnumVariantTypeNode { 10 | Empty(EnumEmptyVariantTypeNode), 11 | Struct(EnumStructVariantTypeNode), 12 | Tuple(EnumTupleVariantTypeNode), 13 | } 14 | 15 | impl TryFrom for EnumVariantTypeNode { 16 | type Error = CodamaError; 17 | 18 | fn try_from(value: Node) -> Result { 19 | match value { 20 | Node::Type(RegisteredTypeNode::EnumEmptyVariant(node)) => { 21 | Ok(EnumVariantTypeNode::Empty(node.clone())) 22 | } 23 | Node::Type(RegisteredTypeNode::EnumTupleVariant(node)) => { 24 | Ok(EnumVariantTypeNode::Tuple(node.clone())) 25 | } 26 | Node::Type(RegisteredTypeNode::EnumStructVariant(node)) => { 27 | Ok(EnumVariantTypeNode::Struct(node.clone())) 28 | } 29 | _ => Err(CodamaError::InvalidNodeConversion { 30 | from: value.kind().into(), 31 | into: "EnumVariantTypeNode".into(), 32 | }), 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /codama-nodes/src/type_nodes/nested_type_leaf.rs: -------------------------------------------------------------------------------- 1 | use crate::{HasKind, TypeNode, TypeNodeTrait}; 2 | use codama_errors::CodamaResult; 3 | 4 | #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] 5 | pub struct NestedTypeLeaf(pub TypeNode); 6 | 7 | impl TypeNodeTrait for NestedTypeLeaf { 8 | fn try_from_type_node(node: TypeNode) -> CodamaResult { 9 | Ok(Self(node)) 10 | } 11 | fn into_type_node(self) -> TypeNode { 12 | self.0 13 | } 14 | } 15 | 16 | impl HasKind for NestedTypeLeaf { 17 | fn kind(&self) -> &'static str { 18 | self.0.kind() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /codama-nodes/src/type_nodes/public_key_type_node.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes_derive::type_node; 2 | 3 | #[type_node] 4 | #[derive(Default)] 5 | pub struct PublicKeyTypeNode {} 6 | 7 | impl From for crate::Node { 8 | fn from(val: PublicKeyTypeNode) -> Self { 9 | crate::Node::Type(val.into()) 10 | } 11 | } 12 | 13 | impl PublicKeyTypeNode { 14 | pub fn new() -> Self { 15 | Self::default() 16 | } 17 | } 18 | 19 | #[cfg(test)] 20 | mod tests { 21 | use super::*; 22 | 23 | #[test] 24 | fn new() { 25 | let node = PublicKeyTypeNode::new(); 26 | assert_eq!(node, PublicKeyTypeNode {}); 27 | } 28 | 29 | #[test] 30 | fn to_json() { 31 | let node = PublicKeyTypeNode::new(); 32 | let json = serde_json::to_string(&node).unwrap(); 33 | assert_eq!(json, r#"{"kind":"publicKeyTypeNode"}"#); 34 | } 35 | 36 | #[test] 37 | fn from_json() { 38 | let json = r#"{"kind":"publicKeyTypeNode"}"#; 39 | let node: PublicKeyTypeNode = serde_json::from_str(json).unwrap(); 40 | assert_eq!(node, PublicKeyTypeNode::new()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /codama-nodes/src/type_nodes/traits.rs: -------------------------------------------------------------------------------- 1 | use crate::{HasKind, NodeUnionTrait, TypeNode}; 2 | use codama_errors::CodamaResult; 3 | use std::fmt::Debug; 4 | 5 | pub trait TypeNodeTrait: 6 | HasKind + Debug + PartialEq + Clone + serde::Serialize + for<'de> serde::Deserialize<'de> 7 | { 8 | fn try_from_type_node(node: TypeNode) -> CodamaResult; 9 | fn into_type_node(self) -> TypeNode; 10 | } 11 | 12 | pub trait TypeNodeUnionTrait: NodeUnionTrait {} 13 | 14 | pub trait NestedTypeNodeTrait: 15 | Debug + PartialEq + Clone + serde::Serialize + for<'de> serde::Deserialize<'de> 16 | { 17 | type Mapped: NestedTypeNodeTrait; 18 | fn get_nested_type_node(&self) -> &T; 19 | fn try_map_nested_type_node CodamaResult>( 20 | self, 21 | f: F, 22 | ) -> CodamaResult>; 23 | fn map_nested_type_node U>(self, f: F) -> Self::Mapped { 24 | self.try_map_nested_type_node(|value| Ok(f(value))).unwrap() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /codama-nodes/src/value_nodes/boolean_value_node.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes_derive::node; 2 | 3 | #[node] 4 | pub struct BooleanValueNode { 5 | // Data. 6 | pub boolean: bool, 7 | } 8 | 9 | impl From for crate::Node { 10 | fn from(val: BooleanValueNode) -> Self { 11 | crate::Node::Value(val.into()) 12 | } 13 | } 14 | 15 | impl BooleanValueNode { 16 | pub fn new(boolean: bool) -> Self { 17 | Self { boolean } 18 | } 19 | } 20 | 21 | #[cfg(test)] 22 | mod tests { 23 | use super::*; 24 | 25 | #[test] 26 | fn new() { 27 | assert!(BooleanValueNode::new(true).boolean); 28 | assert!(!BooleanValueNode::new(false).boolean); 29 | } 30 | 31 | #[test] 32 | fn to_json() { 33 | let node = BooleanValueNode::new(true); 34 | let json = serde_json::to_string(&node).unwrap(); 35 | assert_eq!(json, r#"{"kind":"booleanValueNode","boolean":true}"#); 36 | } 37 | 38 | #[test] 39 | fn from_json() { 40 | let json = r#"{"kind":"booleanValueNode","boolean":true}"#; 41 | let node: BooleanValueNode = serde_json::from_str(json).unwrap(); 42 | assert_eq!(node, BooleanValueNode::new(true)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /codama-nodes/src/value_nodes/mod.rs: -------------------------------------------------------------------------------- 1 | mod array_value_node; 2 | mod boolean_value_node; 3 | mod bytes_value_node; 4 | mod constant_value_node; 5 | mod enum_value_node; 6 | mod map_entry_value_node; 7 | mod map_value_node; 8 | mod none_value_node; 9 | mod number_value_node; 10 | mod public_key_value_node; 11 | mod set_value_node; 12 | mod some_value_node; 13 | mod string_value_node; 14 | mod struct_field_value_node; 15 | mod struct_value_node; 16 | mod tuple_value_node; 17 | mod value_node; 18 | 19 | pub use array_value_node::*; 20 | pub use boolean_value_node::*; 21 | pub use bytes_value_node::*; 22 | pub use constant_value_node::*; 23 | pub use enum_value_node::*; 24 | pub use map_entry_value_node::*; 25 | pub use map_value_node::*; 26 | pub use none_value_node::*; 27 | pub use number_value_node::*; 28 | pub use public_key_value_node::*; 29 | pub use set_value_node::*; 30 | pub use some_value_node::*; 31 | pub use string_value_node::*; 32 | pub use struct_field_value_node::*; 33 | pub use struct_value_node::*; 34 | pub use tuple_value_node::*; 35 | pub use value_node::*; 36 | -------------------------------------------------------------------------------- /codama-nodes/src/value_nodes/none_value_node.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes_derive::node; 2 | 3 | #[node] 4 | #[derive(Default)] 5 | pub struct NoneValueNode {} 6 | 7 | impl From for crate::Node { 8 | fn from(val: NoneValueNode) -> Self { 9 | crate::Node::Value(val.into()) 10 | } 11 | } 12 | 13 | impl NoneValueNode { 14 | pub fn new() -> Self { 15 | Self::default() 16 | } 17 | } 18 | 19 | #[cfg(test)] 20 | mod tests { 21 | use super::*; 22 | 23 | #[test] 24 | fn new() { 25 | let node = NoneValueNode::new(); 26 | assert_eq!(node, NoneValueNode {}); 27 | } 28 | 29 | #[test] 30 | fn to_json() { 31 | let node = NoneValueNode::new(); 32 | let json = serde_json::to_string(&node).unwrap(); 33 | assert_eq!(json, r#"{"kind":"noneValueNode"}"#); 34 | } 35 | 36 | #[test] 37 | fn from_json() { 38 | let json = r#"{"kind":"noneValueNode"}"#; 39 | let node: NoneValueNode = serde_json::from_str(json).unwrap(); 40 | assert_eq!(node, NoneValueNode::new()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /codama-nodes/src/value_nodes/some_value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::ValueNode; 2 | use codama_nodes_derive::node; 3 | 4 | #[node] 5 | pub struct SomeValueNode { 6 | // Children. 7 | pub value: Box, 8 | } 9 | 10 | impl From for crate::Node { 11 | fn from(val: SomeValueNode) -> Self { 12 | crate::Node::Value(val.into()) 13 | } 14 | } 15 | 16 | impl SomeValueNode { 17 | pub fn new(value: T) -> Self 18 | where 19 | T: Into, 20 | { 21 | Self { 22 | value: Box::new(value.into()), 23 | } 24 | } 25 | } 26 | 27 | #[cfg(test)] 28 | mod tests { 29 | use super::*; 30 | use crate::NumberValueNode; 31 | 32 | #[test] 33 | fn new() { 34 | let node = SomeValueNode::new(NumberValueNode::new(42)); 35 | assert_eq!(*node.value, ValueNode::Number(NumberValueNode::new(42))); 36 | } 37 | 38 | #[test] 39 | fn to_json() { 40 | let node = SomeValueNode::new(NumberValueNode::new(42)); 41 | let json = serde_json::to_string(&node).unwrap(); 42 | assert_eq!( 43 | json, 44 | r#"{"kind":"someValueNode","value":{"kind":"numberValueNode","number":42}}"# 45 | ); 46 | } 47 | 48 | #[test] 49 | fn from_json() { 50 | let json = r#"{"kind":"someValueNode","value":{"kind":"numberValueNode","number":42}}"#; 51 | let node: SomeValueNode = serde_json::from_str(json).unwrap(); 52 | assert_eq!(node, SomeValueNode::new(NumberValueNode::new(42u32))); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /codama-nodes/src/value_nodes/value_node.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | ArrayValueNode, BooleanValueNode, BytesValueNode, ConstantValueNode, EnumValueNode, HasKind, 3 | MapEntryValueNode, MapValueNode, NoneValueNode, NumberValueNode, PublicKeyValueNode, 4 | SetValueNode, SomeValueNode, StringValueNode, StructFieldValueNode, StructValueNode, 5 | TupleValueNode, 6 | }; 7 | use codama_nodes_derive::{node_union, RegisteredNodes}; 8 | 9 | #[derive(RegisteredNodes)] 10 | #[node_union] 11 | pub enum RegisteredValueNode { 12 | Array(ArrayValueNode), 13 | Boolean(BooleanValueNode), 14 | Bytes(BytesValueNode), 15 | Constant(ConstantValueNode), 16 | Enum(EnumValueNode), 17 | Map(MapValueNode), 18 | None(NoneValueNode), 19 | Number(NumberValueNode), 20 | PublicKey(PublicKeyValueNode), 21 | Set(SetValueNode), 22 | Some(SomeValueNode), 23 | String(StringValueNode), 24 | Struct(StructValueNode), 25 | Tuple(TupleValueNode), 26 | 27 | #[registered] 28 | StructField(StructFieldValueNode), 29 | #[registered] 30 | MapEntry(MapEntryValueNode), 31 | } 32 | 33 | #[cfg(test)] 34 | mod tests { 35 | use super::*; 36 | 37 | #[test] 38 | fn kind_from_standalone() { 39 | let node: ValueNode = NoneValueNode::new().into(); 40 | assert_eq!(node.kind(), "noneValueNode"); 41 | } 42 | 43 | #[test] 44 | fn kind_from_registered() { 45 | let node: RegisteredValueNode = NoneValueNode::new().into(); 46 | assert_eq!(node.kind(), "noneValueNode"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /codama-nodes/tests-derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama-nodes-derive-test-macros" 3 | description = "Tests for internal Codama node macros" 4 | repository = { workspace = true } 5 | edition = { workspace = true } 6 | license = { workspace = true } 7 | publish = false 8 | 9 | [dev-dependencies] 10 | codama-errors = { version = "0.4.0", path = "../../codama-errors" } 11 | codama-nodes = { version = "0.4.0", path = ".." } 12 | codama-nodes-derive = { version = "0.4.0", path = "../derive" } 13 | derive_more = { version = "1.0", features = ["from"] } 14 | trybuild = { version = "1.0.49", features = ["diff"] } 15 | serde = { version = "1.0", features = ["derive"] } 16 | serde_json = "1.0" 17 | -------------------------------------------------------------------------------- /codama-nodes/tests-derive/tests/mod.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn tests() { 3 | let t = trybuild::TestCases::new(); 4 | t.pass("tests/node/*.rs"); 5 | t.pass("tests/node_union/*.rs"); 6 | t.pass("tests/registered_nodes/*.pass.rs"); 7 | t.compile_fail("tests/registered_nodes/*.fail.rs"); 8 | } 9 | -------------------------------------------------------------------------------- /codama-nodes/tests-derive/tests/node/generic.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes_derive::Node; 2 | 3 | pub trait HasKind { 4 | fn kind(&self) -> &'static str; 5 | } 6 | pub trait NodeTrait { 7 | const KIND: &'static str; 8 | } 9 | 10 | pub trait SomeTrait {} 11 | impl SomeTrait for u32 {} 12 | 13 | #[derive(Node)] 14 | pub struct NumberTypeNode { 15 | pub value: T, 16 | } 17 | 18 | fn main() { 19 | assert_eq!(NumberTypeNode::::KIND, "numberTypeNode"); 20 | } 21 | -------------------------------------------------------------------------------- /codama-nodes/tests-derive/tests/node/simple.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes_derive::Node; 2 | 3 | pub trait HasKind { 4 | fn kind(&self) -> &'static str; 5 | } 6 | pub trait NodeTrait { 7 | const KIND: &'static str; 8 | } 9 | 10 | #[derive(Node)] 11 | pub struct NumberTypeNode {} 12 | 13 | fn main() { 14 | assert_eq!(NumberTypeNode::KIND, "numberTypeNode"); 15 | } 16 | -------------------------------------------------------------------------------- /codama-nodes/tests-derive/tests/node_union/boxed.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes::{HasKind, NodeTrait, NodeUnionTrait}; 2 | use codama_nodes_derive::{node, NodeUnion}; 3 | 4 | #[node] 5 | pub struct NumberTypeNode {} 6 | 7 | #[node] 8 | pub struct StringTypeNode {} 9 | 10 | #[derive(NodeUnion, PartialEq, Debug, Clone)] 11 | pub enum TypeNode { 12 | Number(Box), 13 | String(Box), 14 | } 15 | 16 | fn main() { 17 | let node = TypeNode::Number(Box::new(NumberTypeNode {})); 18 | let json = r#"{"kind":"numberTypeNode"}"#; 19 | assert_eq!(serde_json::to_string(&node).unwrap(), json); 20 | assert_eq!(serde_json::from_str::(json).unwrap(), node); 21 | 22 | let node = TypeNode::String(Box::new(StringTypeNode {})); 23 | let json = r#"{"kind":"stringTypeNode"}"#; 24 | assert_eq!(serde_json::to_string(&node).unwrap(), json); 25 | assert_eq!(serde_json::from_str::(json).unwrap(), node); 26 | } 27 | -------------------------------------------------------------------------------- /codama-nodes/tests-derive/tests/node_union/generic.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes::{HasKind, NodeTrait, NodeUnionTrait}; 2 | use codama_nodes_derive::{node, NodeUnion}; 3 | use std::fmt::Debug; 4 | 5 | pub trait SomeTrait: 6 | Clone + PartialEq + Debug + serde::Serialize + for<'de> serde::Deserialize<'de> 7 | { 8 | } 9 | impl SomeTrait for u32 {} 10 | 11 | #[node] 12 | pub struct NumberTypeNode { 13 | #[serde(bound(serialize = "T: SomeTrait", deserialize = "T: SomeTrait"))] 14 | pub value: T, 15 | } 16 | 17 | #[node] 18 | pub struct StringTypeNode { 19 | #[serde(bound(serialize = "T: SomeTrait", deserialize = "T: SomeTrait"))] 20 | pub value: T, 21 | } 22 | 23 | #[derive(NodeUnion, PartialEq, Debug, Clone)] 24 | pub enum TypeNode { 25 | Number(NumberTypeNode), 26 | String(StringTypeNode), 27 | } 28 | 29 | fn main() { 30 | let node = TypeNode::Number(NumberTypeNode { value: 42 }); 31 | let json = r#"{"kind":"numberTypeNode","value":42}"#; 32 | assert_eq!(serde_json::to_string(&node).unwrap(), json); 33 | assert_eq!(serde_json::from_str::>(json).unwrap(), node); 34 | 35 | let node = TypeNode::String(StringTypeNode { value: 42 }); 36 | let json = r#"{"kind":"stringTypeNode","value":42}"#; 37 | assert_eq!(serde_json::to_string(&node).unwrap(), json); 38 | assert_eq!(serde_json::from_str::>(json).unwrap(), node); 39 | } 40 | -------------------------------------------------------------------------------- /codama-nodes/tests-derive/tests/node_union/simple.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes::{HasKind, NodeTrait, NodeUnionTrait}; 2 | use codama_nodes_derive::{node, NodeUnion}; 3 | 4 | #[node] 5 | pub struct NumberTypeNode {} 6 | 7 | #[node] 8 | pub struct StringTypeNode {} 9 | 10 | #[derive(NodeUnion, PartialEq, Debug, Clone)] 11 | pub enum TypeNode { 12 | Number(NumberTypeNode), 13 | String(StringTypeNode), 14 | } 15 | 16 | fn main() { 17 | let node = TypeNode::Number(NumberTypeNode {}); 18 | let json = r#"{"kind":"numberTypeNode"}"#; 19 | assert_eq!(serde_json::to_string(&node).unwrap(), json); 20 | assert_eq!(serde_json::from_str::(json).unwrap(), node); 21 | 22 | let node = TypeNode::String(StringTypeNode {}); 23 | let json = r#"{"kind":"stringTypeNode"}"#; 24 | assert_eq!(serde_json::to_string(&node).unwrap(), json); 25 | assert_eq!(serde_json::from_str::(json).unwrap(), node); 26 | } 27 | -------------------------------------------------------------------------------- /codama-nodes/tests-derive/tests/registered_nodes/from_registered.pass.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes::{HasKind, NodeTrait, NodeUnionTrait}; 2 | use codama_nodes_derive::{node, node_union, RegisteredNodes}; 3 | 4 | #[node] 5 | pub struct NumberTypeNode {} 6 | 7 | #[node] 8 | pub struct StructTypeNode {} 9 | 10 | #[node] 11 | pub struct StructFieldTypeNode {} 12 | 13 | #[derive(RegisteredNodes)] 14 | #[node_union] 15 | pub enum RegisteredTypeNode { 16 | Number(NumberTypeNode), 17 | Struct(StructTypeNode), 18 | #[registered] 19 | StructField(StructFieldTypeNode), 20 | } 21 | 22 | fn main() { 23 | let node = TypeNode::try_from(RegisteredTypeNode::Number(NumberTypeNode {})); 24 | assert!(matches!(node, Ok(TypeNode::Number(_)))); 25 | 26 | let node = TypeNode::try_from(RegisteredTypeNode::Struct(StructTypeNode {})); 27 | assert!(matches!(node, Ok(TypeNode::Struct(_)))); 28 | 29 | let node = TypeNode::try_from(RegisteredTypeNode::StructField(StructFieldTypeNode {})); 30 | assert!(matches!( 31 | node, 32 | Err(codama_errors::CodamaError::InvalidNodeConversion { .. }) 33 | )); 34 | } 35 | -------------------------------------------------------------------------------- /codama-nodes/tests-derive/tests/registered_nodes/from_standalone.pass.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes::{HasKind, NodeTrait, NodeUnionTrait}; 2 | use codama_nodes_derive::{node, node_union, RegisteredNodes}; 3 | 4 | #[node] 5 | pub struct NumberTypeNode {} 6 | 7 | #[node] 8 | pub struct StructTypeNode {} 9 | 10 | #[node] 11 | pub struct StructFieldTypeNode {} 12 | 13 | #[derive(RegisteredNodes)] 14 | #[node_union] 15 | pub enum RegisteredTypeNode { 16 | Number(NumberTypeNode), 17 | Struct(StructTypeNode), 18 | #[registered] 19 | StructField(StructFieldTypeNode), 20 | } 21 | 22 | fn main() { 23 | let node: RegisteredTypeNode = TypeNode::Number(NumberTypeNode {}).into(); 24 | assert!(matches!(node, RegisteredTypeNode::Number(_))); 25 | 26 | let node: RegisteredTypeNode = TypeNode::Struct(StructTypeNode {}).into(); 27 | assert!(matches!(node, RegisteredTypeNode::Struct(_))); 28 | } 29 | -------------------------------------------------------------------------------- /codama-nodes/tests-derive/tests/registered_nodes/simple.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes::{HasKind, NodeTrait, NodeUnionTrait}; 2 | use codama_nodes_derive::{node, node_union, RegisteredNodes}; 3 | 4 | #[node] 5 | pub struct NumberTypeNode {} 6 | 7 | #[node] 8 | pub struct StructTypeNode {} 9 | 10 | #[node] 11 | pub struct StructFieldTypeNode {} 12 | 13 | #[derive(RegisteredNodes)] 14 | #[node_union] 15 | pub enum RegisteredTypeNode { 16 | Number(NumberTypeNode), 17 | Struct(StructTypeNode), 18 | #[registered] 19 | StructField(StructFieldTypeNode), 20 | } 21 | 22 | fn main() { 23 | TypeNode::StructField(StructFieldTypeNode {}); 24 | } 25 | -------------------------------------------------------------------------------- /codama-nodes/tests-derive/tests/registered_nodes/simple.fail.stderr: -------------------------------------------------------------------------------- 1 | error[E0599]: no variant or associated item named `StructField` found for enum `TypeNode` in the current scope 2 | --> tests/registered_nodes/simple.fail.rs:23:15 3 | | 4 | 15 | pub enum RegisteredTypeNode { 5 | | --------------------------- variant or associated item `StructField` not found for this enum 6 | ... 7 | 23 | TypeNode::StructField(StructFieldTypeNode {}); 8 | | ^^^^^^^^^^^ variant or associated item not found in `TypeNode` 9 | -------------------------------------------------------------------------------- /codama-nodes/tests-derive/tests/registered_nodes/simple.pass.rs: -------------------------------------------------------------------------------- 1 | use codama_nodes::{HasKind, NodeTrait, NodeUnionTrait}; 2 | use codama_nodes_derive::{node, node_union, RegisteredNodes}; 3 | 4 | #[node] 5 | pub struct NumberTypeNode {} 6 | 7 | #[node] 8 | pub struct StructTypeNode {} 9 | 10 | #[node] 11 | pub struct StructFieldTypeNode {} 12 | 13 | #[derive(RegisteredNodes)] 14 | #[node_union] 15 | pub enum RegisteredTypeNode { 16 | Number(NumberTypeNode), 17 | Struct(StructTypeNode), 18 | #[registered] 19 | StructField(StructFieldTypeNode), 20 | } 21 | 22 | fn main() { 23 | let node = RegisteredTypeNode::Number(NumberTypeNode {}); 24 | assert!(matches!(node, RegisteredTypeNode::Number(_))); 25 | 26 | let node = RegisteredTypeNode::Struct(StructTypeNode {}); 27 | assert!(matches!(node, RegisteredTypeNode::Struct(_))); 28 | 29 | let node = RegisteredTypeNode::StructField(StructFieldTypeNode {}); 30 | assert!(matches!(node, RegisteredTypeNode::StructField(_))); 31 | 32 | let node = TypeNode::Number(NumberTypeNode {}); 33 | assert!(matches!(node, TypeNode::Number(_))); 34 | 35 | let node = TypeNode::Struct(StructTypeNode {}); 36 | assert!(matches!(node, TypeNode::Struct(_))); 37 | } 38 | -------------------------------------------------------------------------------- /codama-stores/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-stores/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama-stores" 3 | description = "Load the content of crates recursively in stores" 4 | version = "0.4.0" 5 | repository = { workspace = true } 6 | edition = { workspace = true } 7 | license = { workspace = true } 8 | 9 | [dev-dependencies] 10 | quote = "1.0" 11 | 12 | [dependencies] 13 | cargo_toml = "0.20" 14 | codama-errors = { version = "0.4.0", path = "../codama-errors" } 15 | proc-macro2 = "1.0" 16 | syn = { version = "2.0", features = ["extra-traits", "full"] } 17 | -------------------------------------------------------------------------------- /codama-stores/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod crate_store; 2 | mod file_module_store; 3 | mod root_store; 4 | 5 | pub use crate_store::*; 6 | pub use file_module_store::*; 7 | pub use root_store::*; 8 | -------------------------------------------------------------------------------- /codama-stores/src/root_store.rs: -------------------------------------------------------------------------------- 1 | use crate::CrateStore; 2 | use codama_errors::{CodamaResult, IteratorCombineErrors}; 3 | use std::path::Path; 4 | 5 | #[derive(Debug, PartialEq)] 6 | pub struct RootStore { 7 | pub crates: Vec, 8 | } 9 | 10 | impl RootStore { 11 | pub fn load>(path: P) -> CodamaResult { 12 | Self::load_all(&[path]) 13 | } 14 | 15 | pub fn load_all>(paths: &[P]) -> CodamaResult { 16 | Ok(Self { 17 | crates: paths 18 | .iter() 19 | .map(CrateStore::load) 20 | .collect_and_combine_errors()?, 21 | }) 22 | } 23 | 24 | pub fn hydrate(tt: proc_macro2::TokenStream) -> CodamaResult { 25 | Ok(Self { 26 | crates: vec![CrateStore::hydrate(tt)?], 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /codama-stores/tests/from_tokens/mod.rs: -------------------------------------------------------------------------------- 1 | use codama_stores::{CrateStore, RootStore}; 2 | use quote::quote; 3 | 4 | #[test] 5 | fn root_from_tokens() { 6 | let tt = quote! { 7 | enum Membership { None, Basic, Premium } 8 | struct Person { 9 | name: String, 10 | age: u8, 11 | member: Membership, 12 | } 13 | }; 14 | 15 | let store = RootStore::hydrate(tt).unwrap(); 16 | assert_eq!(store.crates.len(), 1); 17 | assert!(matches!(store.crates[0].file, syn::File { .. })); 18 | } 19 | 20 | #[test] 21 | fn crate_from_tokens() { 22 | let tt = quote! { 23 | enum Membership { None, Basic, Premium } 24 | struct Person { 25 | name: String, 26 | age: u8, 27 | member: Membership, 28 | } 29 | }; 30 | 31 | let store = CrateStore::hydrate(tt).unwrap(); 32 | assert!(matches!(store.file, syn::File { .. })); 33 | assert!(store.manifest.is_none()); 34 | assert_eq!(store.file_modules.len(), 0); 35 | assert_eq!(store.path.to_str(), Some("")); 36 | } 37 | -------------------------------------------------------------------------------- /codama-stores/tests/lib.rs: -------------------------------------------------------------------------------- 1 | mod from_tokens; 2 | mod nested_modules; 3 | mod single_crate; 4 | 5 | pub fn get_path(relative_path: &str) -> std::path::PathBuf { 6 | let project_dir = env!("CARGO_MANIFEST_DIR"); 7 | std::path::Path::new(project_dir) 8 | .join("tests") 9 | .join(relative_path) 10 | } 11 | -------------------------------------------------------------------------------- /codama-stores/tests/nested_modules/crate/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-stores/tests/nested_modules/crate/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nested-modules" 3 | version = "0.0.0" 4 | edition = "2021" 5 | publish = false 6 | -------------------------------------------------------------------------------- /codama-stores/tests/nested_modules/crate/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Item index: 0 2 | pub type Foo = (); 3 | 4 | // Item index: 1 5 | pub mod nested_1 { 6 | // Item index: 0 7 | pub mod nested_2 { 8 | // Item index: 0 9 | pub mod person; 10 | } 11 | 12 | // Item index: 1 13 | pub type Foo = (); 14 | 15 | // Item index: 2 16 | pub mod membership; 17 | } 18 | -------------------------------------------------------------------------------- /codama-stores/tests/nested_modules/crate/src/membership.rs: -------------------------------------------------------------------------------- 1 | pub enum Membership { 2 | None, 3 | Basic, 4 | Premium, 5 | } 6 | -------------------------------------------------------------------------------- /codama-stores/tests/nested_modules/crate/src/person.rs: -------------------------------------------------------------------------------- 1 | use crate::membership::Membership; 2 | 3 | pub struct Person { 4 | pub name: String, 5 | pub age: u8, 6 | pub membership: Membership, 7 | } 8 | -------------------------------------------------------------------------------- /codama-stores/tests/nested_modules/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::get_path; 2 | use codama_stores::RootStore; 3 | 4 | #[test] 5 | fn load_nested_modules() { 6 | let path = get_path("nested_modules/crate"); 7 | let root_store = RootStore::load_all(&[&path]).unwrap(); 8 | 9 | // The root store has one crate. 10 | assert_eq!(root_store.crates.len(), 1); 11 | let crate_store = &root_store.crates[0]; 12 | 13 | // The file modules are exported using depth-first search. 14 | let [person, membership] = &crate_store.file_modules.as_slice() else { 15 | panic!("Unexpected file modules in crate store"); 16 | }; 17 | assert_eq!(person.path, get_path("nested_modules/crate/src/person.rs")); 18 | assert_eq!( 19 | membership.path, 20 | get_path("nested_modules/crate/src/membership.rs") 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /codama-stores/tests/single_crate/crate/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-stores/tests/single_crate/crate/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "single-crate" 3 | version = "0.0.0" 4 | edition = "2021" 5 | publish = false 6 | -------------------------------------------------------------------------------- /codama-stores/tests/single_crate/crate/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod membership; 2 | mod person; 3 | 4 | pub use membership::*; 5 | pub use person::*; 6 | -------------------------------------------------------------------------------- /codama-stores/tests/single_crate/crate/src/membership.rs: -------------------------------------------------------------------------------- 1 | pub enum Membership { 2 | None, 3 | Basic, 4 | Premium, 5 | } 6 | -------------------------------------------------------------------------------- /codama-stores/tests/single_crate/crate/src/person.rs: -------------------------------------------------------------------------------- 1 | use crate::membership::Membership; 2 | 3 | pub struct Person { 4 | pub name: String, 5 | pub age: u8, 6 | pub membership: Membership, 7 | } 8 | -------------------------------------------------------------------------------- /codama-syn-helpers/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-syn-helpers/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama-syn-helpers" 3 | description = "Extension of syn for Codama" 4 | version = "0.4.0" 5 | repository = { workspace = true } 6 | edition = { workspace = true } 7 | license = { workspace = true } 8 | 9 | [dependencies] 10 | codama-errors = { version = "0.4.0", path = "../codama-errors" } 11 | derive_more = { version = "1.0", features = ["from"] } 12 | proc-macro2 = "1.0" 13 | quote = "1.0" 14 | syn = { version = "2.0", features = ["extra-traits", "full"] } 15 | -------------------------------------------------------------------------------- /codama-syn-helpers/src/extensions/fields.rs: -------------------------------------------------------------------------------- 1 | use super::ToTokensExtension; 2 | use codama_errors::CodamaResult; 3 | use syn::Fields; 4 | 5 | pub trait FieldsExtension { 6 | fn get_self(&self) -> &Fields; 7 | 8 | fn single_unnamed_field(&self) -> CodamaResult<&syn::Field> { 9 | let this = self.get_self(); 10 | match this { 11 | Fields::Unnamed(fields) if fields.unnamed.len() == 1 => Ok(&fields.unnamed[0]), 12 | _ => Err(this 13 | .error("expected a single unnamed field in the variant") 14 | .into()), 15 | } 16 | } 17 | } 18 | 19 | impl FieldsExtension for Fields { 20 | fn get_self(&self) -> &Fields { 21 | self 22 | } 23 | } 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | use super::*; 28 | 29 | #[test] 30 | fn single_unnamed_field_ok() { 31 | let r#struct: syn::ItemStruct = syn::parse_quote! { struct Foo(u32); }; 32 | assert!(r#struct.fields.single_unnamed_field().is_ok()); 33 | } 34 | 35 | #[test] 36 | fn single_unnamed_field_err() { 37 | let r#struct: syn::ItemStruct = syn::parse_quote! { struct Foo(u32, u64); }; 38 | assert!(r#struct.fields.single_unnamed_field().is_err()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /codama-syn-helpers/src/extensions/file.rs: -------------------------------------------------------------------------------- 1 | use syn::File; 2 | 3 | pub trait FileExtension { 4 | fn get_self(&self) -> &File; 5 | 6 | /// Returns the string value of the Fileession if it is a literal string. 7 | fn empty() -> File { 8 | syn::File { 9 | shebang: None, 10 | attrs: Vec::new(), 11 | items: Vec::new(), 12 | } 13 | } 14 | } 15 | 16 | impl FileExtension for File { 17 | fn get_self(&self) -> &File { 18 | self 19 | } 20 | } 21 | 22 | #[cfg(test)] 23 | mod tests { 24 | use super::*; 25 | 26 | #[test] 27 | fn empty() { 28 | let file = File::empty(); 29 | assert_eq!(file.shebang, None); 30 | assert!(file.attrs.is_empty()); 31 | assert!(file.items.is_empty()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /codama-syn-helpers/src/extensions/item.rs: -------------------------------------------------------------------------------- 1 | use syn::Item; 2 | 3 | pub trait ItemExtension { 4 | fn get_self(&self) -> &Item; 5 | 6 | fn attributes(&self) -> Option<&Vec> { 7 | match self.get_self() { 8 | Item::Const(i) => Some(&i.attrs), 9 | Item::Enum(i) => Some(&i.attrs), 10 | Item::ExternCrate(i) => Some(&i.attrs), 11 | Item::Fn(i) => Some(&i.attrs), 12 | Item::ForeignMod(i) => Some(&i.attrs), 13 | Item::Impl(i) => Some(&i.attrs), 14 | Item::Macro(i) => Some(&i.attrs), 15 | Item::Mod(i) => Some(&i.attrs), 16 | Item::Static(i) => Some(&i.attrs), 17 | Item::Struct(i) => Some(&i.attrs), 18 | Item::Trait(i) => Some(&i.attrs), 19 | Item::TraitAlias(i) => Some(&i.attrs), 20 | Item::Type(i) => Some(&i.attrs), 21 | Item::Union(i) => Some(&i.attrs), 22 | Item::Use(i) => Some(&i.attrs), 23 | _ => None, 24 | } 25 | } 26 | } 27 | 28 | impl ItemExtension for Item { 29 | fn get_self(&self) -> &Item { 30 | self 31 | } 32 | } 33 | 34 | #[cfg(test)] 35 | mod tests { 36 | use super::*; 37 | 38 | #[test] 39 | fn attributes() { 40 | let r#struct: Item = syn::parse_quote! { 41 | #[derive(Debug)] 42 | struct Foo(u32); 43 | }; 44 | assert!(matches!( 45 | r#struct.attributes().unwrap().as_slice(), 46 | [syn::Attribute { .. }] 47 | )); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /codama-syn-helpers/src/extensions/mod.rs: -------------------------------------------------------------------------------- 1 | mod attribute; 2 | mod derive_input; 3 | mod expr; 4 | mod fields; 5 | mod file; 6 | mod generics; 7 | mod item; 8 | mod meta_list; 9 | mod parse_buffer; 10 | mod path; 11 | mod to_tokens; 12 | mod r#type; 13 | 14 | pub use attribute::*; 15 | pub use derive_input::*; 16 | pub use expr::*; 17 | pub use fields::*; 18 | pub use file::*; 19 | pub use generics::*; 20 | pub use item::*; 21 | pub use meta_list::*; 22 | pub use parse_buffer::*; 23 | pub use path::*; 24 | pub use r#type::*; 25 | pub use to_tokens::*; 26 | -------------------------------------------------------------------------------- /codama-syn-helpers/src/extensions/to_tokens.rs: -------------------------------------------------------------------------------- 1 | use quote::ToTokens; 2 | use std::fmt::Display; 3 | 4 | pub trait ToTokensExtension { 5 | fn get_self(&self) -> &T; 6 | 7 | fn error(&self, message: impl Display) -> syn::Error { 8 | syn::Error::new_spanned(self.get_self(), message) 9 | } 10 | } 11 | 12 | impl ToTokensExtension for T { 13 | fn get_self(&self) -> &T { 14 | self 15 | } 16 | } 17 | 18 | #[cfg(test)] 19 | mod tests { 20 | use super::*; 21 | 22 | #[test] 23 | fn error() { 24 | let path: syn::Path = syn::parse_quote! { foo::bar }; 25 | let error = path.error("expected a single segment"); 26 | assert_eq!(error.to_string(), "expected a single segment"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /codama-syn-helpers/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod extensions; 2 | 3 | mod meta; 4 | pub use meta::*; 5 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama-syn-helpers-test-macros" 3 | description = "Tests for syn helpers macros" 4 | repository = { workspace = true } 5 | edition = { workspace = true } 6 | license = { workspace = true } 7 | publish = false 8 | 9 | [lib] 10 | proc-macro = true 11 | 12 | [dev-dependencies] 13 | trybuild = { version = "1.0.49", features = ["diff"] } 14 | 15 | [dependencies] 16 | codama-syn-helpers = { version = "0.4.0", path = ".." } 17 | syn = { version = "2.0", features = ["extra-traits"] } 18 | quote = "1.0" 19 | proc-macro2 = "1.0" 20 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_expr/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_expr; 2 | 3 | #[as_expr("hello")] 4 | pub struct Test; 5 | 6 | #[as_expr(foo)] 7 | pub struct TestFromPath; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_expr/from_path_list.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_expr; 2 | 3 | #[as_expr(foo(1, 2, 3))] 4 | pub struct Test; 5 | 6 | #[as_expr(foo = (1, 2, 3))] 7 | pub struct TestWithEq; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_expr/from_path_list.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a valid expression 2 | --> tests/as_expr/from_path_list.fail.rs:3:11 3 | | 4 | 3 | #[as_expr(foo(1, 2, 3))] 5 | | ^^^^^^^^^^^^ 6 | 7 | error: expected a valid expression 8 | --> tests/as_expr/from_path_list.fail.rs:6:11 9 | | 10 | 6 | #[as_expr(foo = (1, 2, 3))] 11 | | ^^^^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_expr/from_path_value.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_expr; 2 | 3 | #[as_expr(foo = bar(1, 2, 3))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_expr/from_path_value.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a valid expression 2 | --> tests/as_expr/from_path_value.fail.rs:3:11 3 | | 4 | 3 | #[as_expr(foo = bar(1, 2, 3))] 5 | | ^^^^^^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_expr/from_verbatim.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_expr; 2 | 3 | #[as_expr([==> ??? <==])] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_expr/from_verbatim.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a valid expression 2 | --> tests/as_expr/from_verbatim.fail.rs:3:11 3 | | 4 | 3 | #[as_expr([==> ??? <==])] 5 | | ^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path; 2 | 3 | #[as_path(foo)] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path/from_expr.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path; 2 | 3 | #[as_path("hello")] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path/from_expr.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a path 2 | --> tests/as_path/from_expr.fail.rs:3:11 3 | | 4 | 3 | #[as_path("hello")] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path/from_path_list.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path; 2 | 3 | #[as_path(foo(1, 2, 3))] 4 | pub struct Test; 5 | 6 | #[as_path(foo = (1, 2, 3))] 7 | pub struct TestWithEq; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path/from_path_list.fail.stderr: -------------------------------------------------------------------------------- 1 | error: unexpected tokens, expected a single path 2 | --> tests/as_path/from_path_list.fail.rs:3:14 3 | | 4 | 3 | #[as_path(foo(1, 2, 3))] 5 | | ^^^^^^^^^ 6 | 7 | error: unexpected tokens, expected a single path 8 | --> tests/as_path/from_path_list.fail.rs:6:15 9 | | 10 | 6 | #[as_path(foo = (1, 2, 3))] 11 | | ^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path/from_path_value.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path; 2 | 3 | #[as_path(foo = bar(1, 2, 3))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path/from_path_value.fail.stderr: -------------------------------------------------------------------------------- 1 | error: unexpected tokens, expected a single path 2 | --> tests/as_path/from_path_value.fail.rs:3:15 3 | | 4 | 3 | #[as_path(foo = bar(1, 2, 3))] 5 | | ^^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path/from_verbatim.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path; 2 | 3 | #[as_path([==> ??? <==])] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path/from_verbatim.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a path 2 | --> tests/as_path/from_verbatim.fail.rs:3:11 3 | | 4 | 3 | #[as_path([==> ??? <==])] 5 | | ^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_list/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path_list; 2 | 3 | #[as_path_list(foo(1, 2, 3))] 4 | pub struct Test; 5 | 6 | #[as_path_list(foo = (1, 2, 3))] 7 | pub struct TestWithEq; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_list/from_expr.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path_list; 2 | 3 | #[as_path_list("hello")] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_list/from_expr.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a path followed by a list: `my_path(...)` or `my_path = (...)` 2 | --> tests/as_path_list/from_expr.fail.rs:3:16 3 | | 4 | 3 | #[as_path_list("hello")] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_list/from_path.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path_list; 2 | 3 | #[as_path_list(foo)] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_list/from_path.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a list: `foo(...)` or `foo = (...)` 2 | --> tests/as_path_list/from_path.fail.rs:3:16 3 | | 4 | 3 | #[as_path_list(foo)] 5 | | ^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_list/from_path_value.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path_list; 2 | 3 | #[as_path_list(foo = bar(1, 2, 3))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_list/from_path_value.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a list: `foo = (...)` 2 | --> tests/as_path_list/from_path_value.fail.rs:3:22 3 | | 4 | 3 | #[as_path_list(foo = bar(1, 2, 3))] 5 | | ^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_list/from_verbatim.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path_list; 2 | 3 | #[as_path_list([==> ??? <==])] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_list/from_verbatim.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a path followed by a list: `my_path(...)` or `my_path = (...)` 2 | --> tests/as_path_list/from_verbatim.fail.rs:3:16 3 | | 4 | 3 | #[as_path_list([==> ??? <==])] 5 | | ^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_value/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path_value; 2 | 3 | #[as_path_value(foo = bar(1, 2, 3))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_value/from_expr.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path_value; 2 | 3 | #[as_path_value("hello")] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_value/from_expr.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a path followed by a value: `my_path = ...` 2 | --> tests/as_path_value/from_expr.fail.rs:3:17 3 | | 4 | 3 | #[as_path_value("hello")] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_value/from_path.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path_value; 2 | 3 | #[as_path_value(foo)] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_value/from_path.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a value for that path: `foo = ...` 2 | --> tests/as_path_value/from_path.fail.rs:3:17 3 | | 4 | 3 | #[as_path_value(foo)] 5 | | ^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_value/from_path_list.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path_value; 2 | 3 | #[as_path_value(foo(1, 2, 3))] 4 | pub struct Test; 5 | 6 | #[as_path_value(foo = (1, 2, 3))] 7 | pub struct TestWithEq; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_value/from_path_list.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected `=` followed by a single value: `foo = ...` 2 | --> tests/as_path_value/from_path_list.fail.rs:3:21 3 | | 4 | 3 | #[as_path_value(foo(1, 2, 3))] 5 | | ^^^^^^^ 6 | 7 | error: expected a single value, found a list 8 | --> tests/as_path_value/from_path_list.fail.rs:6:24 9 | | 10 | 6 | #[as_path_value(foo = (1, 2, 3))] 11 | | ^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_value/from_verbatim.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_path_value; 2 | 3 | #[as_path_value([==> ??? <==])] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_path_value/from_verbatim.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected a path followed by a value: `my_path = ...` 2 | --> tests/as_path_value/from_verbatim.fail.rs:3:17 3 | | 4 | 3 | #[as_path_value([==> ??? <==])] 5 | | ^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_verbatim/_pass.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_verbatim; 2 | 3 | #[as_verbatim([==> ??? <==])] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_verbatim/from_expr.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_verbatim; 2 | 3 | #[as_verbatim("hello")] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_verbatim/from_expr.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected verbatim 2 | --> tests/as_verbatim/from_expr.fail.rs:3:15 3 | | 4 | 3 | #[as_verbatim("hello")] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_verbatim/from_path.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_verbatim; 2 | 3 | #[as_verbatim(foo)] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_verbatim/from_path.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected verbatim 2 | --> tests/as_verbatim/from_path.fail.rs:3:15 3 | | 4 | 3 | #[as_verbatim(foo)] 5 | | ^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_verbatim/from_path_list.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_verbatim; 2 | 3 | #[as_verbatim(foo(1, 2, 3))] 4 | pub struct Test; 5 | 6 | #[as_verbatim(foo = (1, 2, 3))] 7 | pub struct TestWithEq; 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_verbatim/from_path_list.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected verbatim 2 | --> tests/as_verbatim/from_path_list.fail.rs:3:15 3 | | 4 | 3 | #[as_verbatim(foo(1, 2, 3))] 5 | | ^^^^^^^^^^^^ 6 | 7 | error: expected verbatim 8 | --> tests/as_verbatim/from_path_list.fail.rs:6:15 9 | | 10 | 6 | #[as_verbatim(foo = (1, 2, 3))] 11 | | ^^^^^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_verbatim/from_path_value.fail.rs: -------------------------------------------------------------------------------- 1 | use codama_syn_helpers_test_macros::as_verbatim; 2 | 3 | #[as_verbatim(foo = bar(1, 2, 3))] 4 | pub struct Test; 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/as_verbatim/from_path_value.fail.stderr: -------------------------------------------------------------------------------- 1 | error: expected verbatim 2 | --> tests/as_verbatim/from_path_value.fail.rs:3:15 3 | | 4 | 3 | #[as_verbatim(foo = bar(1, 2, 3))] 5 | | ^^^^^^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /codama-syn-helpers/tests-macros/tests/mod.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn tests() { 3 | let t = trybuild::TestCases::new(); 4 | t.pass("tests/**/_pass.rs"); 5 | t.pass("tests/**/*.pass.rs"); 6 | t.compile_fail("tests/**/*.fail.rs"); 7 | } 8 | -------------------------------------------------------------------------------- /codama/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codama" 3 | description = "Generate clients, CLIs, documentation and more from your Solana programs" 4 | version = "0.4.0" 5 | repository = { workspace = true } 6 | edition = { workspace = true } 7 | license = { workspace = true } 8 | 9 | [dependencies] 10 | codama-errors = { version = "0.4.0", path = "../codama-errors" } 11 | codama-korok-plugins = { version = "0.4.0", path = "../codama-korok-plugins" } 12 | codama-korok-visitors = { version = "0.4.0", path = "../codama-korok-visitors" } 13 | codama-koroks = { version = "0.4.0", path = "../codama-koroks" } 14 | codama-macros = { version = "0.4.0", path = "../codama-macros" } 15 | codama-nodes = { version = "0.4.0", path = "../codama-nodes" } 16 | codama-stores = { version = "0.4.0", path = "../codama-stores" } 17 | proc-macro2 = "1.0" 18 | -------------------------------------------------------------------------------- /codama/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod codama; 2 | 3 | pub use codama::*; 4 | pub use codama_errors::*; 5 | pub use codama_korok_plugins::*; 6 | pub use codama_korok_visitors::*; 7 | pub use codama_koroks::*; 8 | pub use codama_nodes::*; 9 | pub use codama_stores::*; 10 | 11 | extern crate codama_macros; 12 | pub use codama_macros::*; 13 | -------------------------------------------------------------------------------- /codama/tests/lib.rs: -------------------------------------------------------------------------------- 1 | mod membership; 2 | mod system; 3 | 4 | pub fn get_path(relative_path: &str) -> std::path::PathBuf { 5 | let project_dir = env!("CARGO_MANIFEST_DIR"); 6 | std::path::Path::new(project_dir) 7 | .join("tests") 8 | .join(relative_path) 9 | } 10 | -------------------------------------------------------------------------------- /codama/tests/membership/crate/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama/tests/membership/crate/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "membership" 3 | version = "1.2.3" 4 | edition = "2021" 5 | publish = false 6 | 7 | [package.metadata.solana] 8 | program-id = "Membership1111111111111111111111111" 9 | -------------------------------------------------------------------------------- /codama/tests/membership/crate/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod membership; 2 | mod person; 3 | 4 | pub use membership::*; 5 | pub use person::*; 6 | -------------------------------------------------------------------------------- /codama/tests/membership/crate/src/membership.rs: -------------------------------------------------------------------------------- 1 | #[derive(CodamaType)] 2 | pub enum Membership { 3 | None, 4 | Basic, 5 | Premium, 6 | } 7 | -------------------------------------------------------------------------------- /codama/tests/membership/crate/src/person.rs: -------------------------------------------------------------------------------- 1 | use super::Membership; 2 | 3 | #[derive(CodamaAccount)] 4 | pub struct Person { 5 | pub name: String, 6 | pub age: u8, 7 | pub membership: Membership, 8 | #[codama(type = public_key)] 9 | pub wallet: [u8; 32], 10 | } 11 | -------------------------------------------------------------------------------- /codama/tests/system/crate/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /codama/tests/system/crate/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "system" 3 | version = "1.0.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | [package.metadata.solana] 8 | program-id = "11111111111111111111111111111111" 9 | 10 | [dependencies] 11 | solana-pubkey = "2.2.0" 12 | -------------------------------------------------------------------------------- /codama/tests/system/crate/src/errors.rs: -------------------------------------------------------------------------------- 1 | use codama::CodamaErrors; 2 | use thiserror::Error; 3 | 4 | #[derive(CodamaErrors, Error, Debug)] 5 | pub enum SystemError { 6 | #[error("an account with the same address already exists")] 7 | AccountAlreadyInUse, 8 | 9 | #[error("account does not have enough SOL to perform the operation")] 10 | ResultWithNegativeLamports, 11 | 12 | #[error("cannot assign account to this program id")] 13 | InvalidProgramId, 14 | 15 | #[error("cannot allocate account data of this length")] 16 | InvalidAccountDataLength, 17 | 18 | #[error("length of requested seed is too long")] 19 | MaxSeedLengthExceeded, 20 | 21 | #[error("provided address does not match addressed derived from seed")] 22 | AddressWithSeedMismatch, 23 | 24 | #[error("advancing stored nonce requires a populated RecentBlockhashes sysvar")] 25 | NonceNoRecentBlockhashes, 26 | 27 | #[error("stored nonce is still in recent_blockhashes")] 28 | NonceBlockhashNotExpired, 29 | 30 | #[error("specified nonce does not match stored nonce")] 31 | NonceUnexpectedBlockhashValue, 32 | } 33 | -------------------------------------------------------------------------------- /codama/tests/system/crate/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod errors; 2 | mod instructions; 3 | mod state; 4 | 5 | pub use errors::*; 6 | pub use instructions::*; 7 | pub use state::*; 8 | -------------------------------------------------------------------------------- /codama/tests/system/crate/src/state.rs: -------------------------------------------------------------------------------- 1 | use codama::{CodamaAccount, CodamaType}; 2 | use solana_pubkey::Pubkey; 3 | 4 | #[derive(CodamaAccount)] 5 | pub struct Nonce { 6 | pub version: NonceVersion, 7 | pub state: NonceState, 8 | pub authority: Pubkey, 9 | pub blockhash: Pubkey, 10 | pub lamports_per_signature: u64, 11 | } 12 | 13 | #[derive(CodamaType)] 14 | #[repr(u32)] 15 | pub enum NonceVersion { 16 | Legacy, 17 | Current, 18 | } 19 | 20 | #[derive(CodamaType)] 21 | #[repr(u32)] 22 | pub enum NonceState { 23 | Uninitialized, 24 | Initialized, 25 | } 26 | --------------------------------------------------------------------------------