ink_ir/ir/event/
config.rs

1// Copyright (C) Use Ink (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::{
16    ast,
17    utils::duplicate_config_err,
18};
19
20/// The configuration arguments to the `#[ink::event(..)]` attribute macro.
21#[derive(Debug, PartialEq, Eq)]
22pub struct EventConfig {
23    /// If set to `false`, a signature topic is generated and emitted for this event.
24    /// If set to `true`, **no** signature topic is generated or emitted for this event.,
25    /// This is the default value.
26    anonymous: bool,
27
28    /// Manually specified signature topic hash.
29    signature_topic_hex: Option<String>,
30}
31
32impl TryFrom<ast::AttributeArgs> for EventConfig {
33    type Error = syn::Error;
34
35    fn try_from(args: ast::AttributeArgs) -> Result<Self, Self::Error> {
36        let mut anonymous: Option<syn::Path> = None;
37        let mut signature_topic: Option<syn::LitStr> = None;
38        for arg in args.into_iter() {
39            if arg.name().is_ident("anonymous") {
40                if let Some(lit_bool) = anonymous {
41                    return Err(duplicate_config_err(lit_bool, arg, "anonymous", "event"));
42                }
43                if let ast::Meta::Path(path) = arg {
44                    anonymous = Some(path)
45                } else {
46                    return Err(format_err_spanned!(
47                        arg,
48                        "encountered an unexpected value for `anonymous` ink! event item configuration argument. \
49                        Did you mean #[ink::event(anonymous)] ?",
50                    ));
51                }
52            } else if arg.name().is_ident("signature_topic") {
53                if anonymous.is_some() {
54                    return Err(format_err_spanned!(
55                        arg,
56                        "cannot specify `signature_topic` with `anonymous` in ink! event item configuration argument",
57                    ));
58                }
59
60                if let Some(lit_str) = signature_topic {
61                    return Err(duplicate_config_err(
62                        lit_str,
63                        arg,
64                        "signature_topic",
65                        "event",
66                    ));
67                }
68                if let Some(lit_str) = arg.value().and_then(ast::MetaValue::as_lit_string)
69                {
70                    signature_topic = Some(lit_str.clone())
71                } else {
72                    return Err(format_err_spanned!(
73                        arg,
74                        "expected a string literal value for `signature_topic` ink! event item configuration argument",
75                    ));
76                }
77            } else {
78                return Err(format_err_spanned!(
79                    arg,
80                    "encountered unknown or unsupported ink! event item configuration argument",
81                ));
82            }
83        }
84
85        Ok(EventConfig::new(
86            anonymous.is_some(),
87            signature_topic.map(|lit_str| lit_str.value()),
88        ))
89    }
90}
91
92impl EventConfig {
93    /// Construct a new [`EventConfig`].
94    pub fn new(anonymous: bool, signature_topic_hex: Option<String>) -> Self {
95        Self {
96            anonymous,
97            signature_topic_hex,
98        }
99    }
100
101    /// Returns the anonymous configuration argument.
102    pub fn anonymous(&self) -> bool {
103        self.anonymous
104    }
105
106    /// Returns the manually specified signature topic.
107    pub fn signature_topic_hex(&self) -> Option<&str> {
108        self.signature_topic_hex.as_deref()
109    }
110}