Conversation
| #[proc_macro_derive(CodamaPdaHelpers, attributes(codama))] | ||
| pub fn codama_pda_helpers_derive(input: TokenStream) -> TokenStream { |
There was a problem hiding this comment.
Whatever we land on with the derive name, just want to flag that IMO it should start with Codama since it purely relies on codama attributes.
| /// (wrapping `Address` methods) | ||
| /// - `derive_address` | ||
| /// - `create_program_address` | ||
| /// - `find_program_address` | ||
| /// - `try_find_program_address` | ||
| /// - `derive_program_address` |
There was a problem hiding this comment.
@febo thoughts on which Address methods this should include? This sort of wraps everything, but maybe it should be a blessed subset.
lorisleiva
left a comment
There was a problem hiding this comment.
I'll go through this thoroughly asap but I just wanted to share some early first impression feedback.
| @@ -0,0 +1,97 @@ | |||
| use heck::ToSnakeCase; | |||
There was a problem hiding this comment.
Since we already have an exported CamelCaseString struct in codama-nodes maybe it would be cleaner / more consistent to also add a SnakeCaseString struct there instead of introducing a new dependency.
| #[proc_macro_derive(CodamaPdaHelpers, attributes(codama))] | ||
| pub fn codama_pda_helpers_derive(input: TokenStream) -> TokenStream { | ||
| #[cfg(not(target_os = "solana"))] | ||
| { | ||
| pda_helpers::codama_pda_helpers_derive_impl(input.into()) | ||
| .unwrap_or_else(codama_errors::CodamaError::into_compile_error) | ||
| .into() | ||
| } | ||
| #[cfg(target_os = "solana")] | ||
| { | ||
| input | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
It would be nice if this macro was on its own crate. Maybe something like codama-pda-helpers or whatever the name ends up being here.
That way, if anyone wants to use a slightly different version of our generated code, it's easier for them to fork that crate on its own.
|
@lorisleiva @grod220 I opened #NNN with the Gabe, if you are still on this I will leave the |
|
@aditya-able, I've moved on to some other things, but if you find it useful, I encourage you to push things forward! Feel free to take over this branch/PR or another 👍 |
Same shape as CamelCaseString: same derives, new<T: AsRef<str>>, the String and &str conversions, Deref and AsRef, and the tests in the same order. Word boundaries deliberately do not follow CamelCaseString. to_camel_case reads a run of uppercase letters as one word, turning tokenAMint into tokenAmint and SPLToken into spltoken. In snake_case that would give token_amint and spltoken, which make poor identifiers, and tokenAMint and tokenBMint show up often enough in real PDA seeds to matter. So an uppercase run splits before its last letter when a lowercase letter follows. Digits carry the case of whatever preceded them, so a digit ends a word only when an uppercase letter follows a lowercase run. seed2Bump gives seed2_bump while mint_2, this123 and 2Mint are left alone. That combination is exactly heck::ToSnakeCase, checked by differential fuzzing against heck over 1,000,021 inputs with zero mismatches, so codama-idl#86 can drop the dependency without a change in behaviour.
Same shape as CamelCaseString: same derives, new<T: AsRef<str>>, the String and &str conversions, Deref and AsRef, and the tests in the same order. Word boundaries deliberately do not follow CamelCaseString. to_camel_case reads a run of uppercase letters as one word, turning tokenAMint into tokenAmint and SPLToken into spltoken. In snake_case that would give token_amint and spltoken, which make poor identifiers, and tokenAMint and tokenBMint show up often enough in real PDA seeds to matter. So an uppercase run splits before its last letter when a lowercase letter follows. Digits carry the case of whatever preceded them, so a digit ends a word only when an uppercase letter follows a lowercase run. seed2Bump gives seed2_bump while mint_2, this123 and 2Mint are left alone. That combination matches heck::ToSnakeCase, checked by differential fuzzing over 1,000,021 ASCII inputs with zero mismatches. On a further 400,000 Unicode inputs the only divergence is a word-final Greek capital sigma, which heck lowercases to the final form while this lowercases per character, as to_camel_case does. So codama-idl#86 can drop the dependency.
Same shape as CamelCaseString: same derives, new<T: AsRef<str>>, the String and &str conversions, Deref and AsRef, and the tests in the same order. Word boundaries deliberately do not follow CamelCaseString. to_camel_case reads a run of uppercase letters as one word, turning tokenAMint into tokenAmint and SPLToken into spltoken. In snake_case that would give token_amint and spltoken, which make poor identifiers, and tokenAMint and tokenBMint show up often enough in real PDA seeds to matter. So an uppercase run splits before its last letter when a lowercase letter follows. Digits carry the case of whatever preceded them, so a digit ends a word only when an uppercase letter follows a lowercase run. seed2Bump gives seed2_bump while mint_2, this123 and 2Mint are left alone. That combination matches heck::ToSnakeCase, checked by differential fuzzing over 1,000,021 ASCII inputs with zero mismatches. On a further 400,000 Unicode inputs the only divergence is a word-final Greek capital sigma, which heck lowercases to the final form while this lowercases per character, as to_camel_case does. So codama-idl#86 can drop the dependency.
|
@lorisleiva happy to take this over if it's still wanted Gabe gave the go-ahead above. Before I rebase, two v2 questions, since the answers change what I'd build:
On casing: agreed on #136, no new type in codama-nodes. If you want to keep heck out, I have If the answer is wait for v2, I'd rather spend the time on the identifier rename instead. Point me at whichever is more useful. |
|
@senzenn Since v2 is just around the corner I'd rather not make any radical changes to v1 in the meantime since we otherwise risk to miss some features when forward-porting them to v2. |
Adds
#[derive(CodamaPdaHelpers)]which generates runtime PDA helper methods from existing #[codama(seed(...))] attributes. This reduces repeated manual PDA boilerplate program devs are writing.API
#[codama(seed(...))]directives and generates:seedsseeds_with_bumpsigner_seedsderive_addresscreate_program_addressfind_program_addresstry_find_program_addressderive_program_addressDiscussion points
Addressmethods be shipped? Aka, should we dropfind_program_address?implvs external crate helpers