-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Expand file tree
/
Copy pathcommon.rs
More file actions
59 lines (51 loc) · 1.82 KB
/
common.rs
File metadata and controls
59 lines (51 loc) · 1.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use crate::IxArg;
use anyhow::Result;
use heck::CamelCase;
use quote::{quote, quote_spanned};
// Namespace for calculating instruction sighash signatures for any instruction
// not affecting program state.
pub const SIGHASH_GLOBAL_NAMESPACE: &str = "global";
// We don't technically use sighash, because the input arguments aren't given.
// Rust doesn't have method overloading so no need to use the arguments.
// However, we do namespace methods in the preeimage so that we can use
// different traits with the same method name.
pub fn sighash(namespace: &str, name: &str) -> [u8; 8] {
let preimage = format!("{namespace}:{name}");
let mut sighash = [0u8; 8];
sighash.copy_from_slice(&crate::hash::hash(preimage.as_bytes()).to_bytes()[..8]);
sighash
}
pub fn gen_discriminator(namespace: &str, name: impl ToString) -> proc_macro2::TokenStream {
let discriminator = sighash(namespace, name.to_string().as_str());
format!("&{discriminator:?}").parse().unwrap()
}
pub fn generate_ix_variant_spanned(
name: &str,
args: &[IxArg],
span: proc_macro2::Span,
) -> proc_macro2::TokenStream {
let ix_arg_names: Vec<&syn::Ident> = args.iter().map(|arg| &arg.name).collect();
let ix_name_camel = generate_ix_variant_name_spanned(name, span);
if args.is_empty() {
quote_spanned! { span =>
#ix_name_camel
}
} else {
quote_spanned! { span =>
#ix_name_camel {
#(#ix_arg_names),*
}
}
}
}
pub fn generate_ix_variant_name(name: &str) -> Result<syn::Ident> {
Ok(syn::parse_str(&name.to_camel_case())?)
}
pub fn generate_ix_variant_name_spanned(
name: &str,
span: proc_macro2::Span,
) -> proc_macro2::TokenStream {
let n = name.to_camel_case();
let ident = proc_macro2::Ident::new(&n, span);
quote! { #ident }
}