ink_ir/ir/event/
signature_topic.rs1use impl_serde::serialize as serde_hex;
16use syn::spanned::Spanned;
17
18use crate::ast;
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub struct SignatureTopicArg {
25 topic: [u8; 32],
26}
27
28impl SignatureTopicArg {
29 pub fn signature_topic(&self) -> [u8; 32] {
30 self.topic
31 }
32}
33
34impl From<&[u8; 32]> for SignatureTopicArg {
35 fn from(value: &[u8; 32]) -> Self {
36 Self { topic: *value }
37 }
38}
39
40impl TryFrom<&syn::Lit> for SignatureTopicArg {
41 type Error = syn::Error;
42
43 fn try_from(lit: &syn::Lit) -> Result<Self, Self::Error> {
44 if let syn::Lit::Str(s) = lit {
45 let bytes: [u8; 32] = serde_hex::from_hex(&s.value())
46 .map_err(|_| {
47 format_err_spanned!(
48 lit,
49 "`signature_topic` has invalid hex string",
50 )
51 })?
52 .try_into()
53 .map_err(|e: Vec<u8>| {
54 format_err_spanned!(
55 lit,
56 "`signature_topic` is expected to be 32-byte hex string. Found {} bytes",
57 e.len()
58 )
59 })?;
60
61 Ok(Self { topic: bytes })
62 } else {
63 Err(format_err_spanned!(
64 lit,
65 "Expected string literal argument for the `signature_topic`"
66 ))
67 }
68 }
69}
70
71impl TryFrom<&ast::MetaValue> for SignatureTopicArg {
72 type Error = syn::Error;
73
74 fn try_from(value: &ast::MetaValue) -> Result<Self, Self::Error> {
75 if let ast::MetaValue::Lit(lit) = value {
76 Self::try_from(lit)
77 } else {
78 Err(format_err_spanned!(
79 value,
80 "Expected string argument for the `signature_topic`"
81 ))
82 }
83 }
84}
85
86impl TryFrom<ast::AttributeArgs> for Option<SignatureTopicArg> {
87 type Error = syn::Error;
88
89 fn try_from(args: ast::AttributeArgs) -> Result<Self, Self::Error> {
90 let mut signature_topic: Option<SignatureTopicArg> = None;
91 for arg in args.into_iter() {
92 if arg.name().is_ident("hash") {
93 if signature_topic.is_some() {
94 return Err(format_err!(
95 arg.span(),
96 "encountered duplicate ink! event configuration argument"
97 ));
98 }
99 signature_topic =
100 arg.value().map(SignatureTopicArg::try_from).transpose()?;
101 } else {
102 return Err(format_err_spanned!(
103 arg,
104 "encountered unknown or unsupported ink! event item configuration argument",
105 ));
106 }
107 }
108 Ok(signature_topic)
109 }
110}
111
112impl TryFrom<&syn::MetaNameValue> for SignatureTopicArg {
113 type Error = syn::Error;
114
115 fn try_from(nv: &syn::MetaNameValue) -> Result<Self, Self::Error> {
116 if nv.path.is_ident("signature_topic") {
117 if let syn::Expr::Lit(lit_expr) = &nv.value {
118 Self::try_from(&lit_expr.lit)
119 } else {
120 Err(format_err_spanned!(&nv.value, "Expected literal argument"))
121 }
122 } else {
123 Err(format_err_spanned!(nv, "Expected `signature_topic` ident"))
124 }
125 }
126}