1#![recursion_limit = "128"]
2extern crate proc_macro;
3
4mod core_impl;
5
6use core_impl::{ext::generate_ext_structs, metadata::generate_contract_metadata_method};
7
8use proc_macro::TokenStream;
9
10use self::core_impl::*;
11use darling::ast::NestedMeta;
12use darling::{Error, FromMeta};
13use inflector::Inflector;
14use proc_macro2::{Ident, Span};
15use quote::{ToTokens, quote};
16use syn::{
17 Expr, ImplItem, Item, ItemEnum, ItemImpl, ItemStruct, ItemTrait, WhereClause, parse_quote,
18};
19
20#[derive(Debug, Clone)]
21struct Serializers {
22 vec: Vec<Expr>,
23}
24
25impl FromMeta for Serializers {
26 fn from_expr(expr: &syn::Expr) -> Result<Self, darling::Error> {
27 match expr {
28 syn::Expr::Array(expr_array) => Ok(Serializers {
29 vec: expr_array
30 .elems
31 .iter()
32 .map(<Expr as FromMeta>::from_expr)
33 .map(|x| x.unwrap())
34 .collect::<Vec<_>>(),
35 }),
36 _ => Err(Error::unexpected_expr_type(expr)),
37 }
38 }
39}
40
41#[derive(FromMeta)]
42struct NearMacroArgs {
43 serializers: Option<Serializers>,
44 #[darling(default, flatten)]
45 near_bindgen_args: NearBindgenMacroArgs,
46 inside_nearsdk: Option<bool>,
47}
48
49fn has_nested_near_macros(item: TokenStream) -> bool {
50 syn::parse::<syn::Item>(item)
51 .ok()
52 .and_then(|item_ast| {
53 let attrs = match item_ast {
54 syn::Item::Struct(s) => s.attrs,
55 syn::Item::Enum(e) => e.attrs,
56 syn::Item::Impl(i) => i.attrs,
57 _ => vec![], };
59
60 attrs.into_iter().find(|attr| {
61 let path_str = attr.path().to_token_stream().to_string();
62 path_str == "near" || path_str == "near_bindgen"
63 })
64 })
65 .is_some()
66}
67
68#[proc_macro_attribute]
69pub fn near(attr: TokenStream, item: TokenStream) -> TokenStream {
70 if attr.to_string().contains("event_json") {
71 return core_impl::near_events(attr, item);
72 }
73
74 let meta_list = match NestedMeta::parse_meta_list(attr.into()) {
75 Ok(v) => v,
76 Err(e) => {
77 return TokenStream::from(Error::from(e).write_errors());
78 }
79 };
80
81 let near_macro_args = match NearMacroArgs::from_list(&meta_list) {
82 Ok(v) => v,
83 Err(e) => {
84 return TokenStream::from(e.write_errors());
85 }
86 };
87
88 let near_sdk_crate = if near_macro_args.inside_nearsdk.unwrap_or(false) {
89 quote! {crate}
90 } else {
91 quote! {::near_sdk}
92 };
93
94 if has_nested_near_macros(item.clone()) {
96 return TokenStream::from(
97 syn::Error::new(
98 Span::call_site(),
99 "#[near] or #[near_bindgen] attributes are not allowed to be nested inside of the outmost #[near] attribute. Only a single #[near] attribute is allowed",
100 )
101 .to_compile_error(),
102 );
103 }
104 let string_borsh_crate = quote! {#near_sdk_crate::borsh}.to_string();
105 let string_serde_crate = quote! {#near_sdk_crate::serde}.to_string();
106 let string_serde_with_crate = quote! {#near_sdk_crate::serde_with}.to_string();
107
108 let mut expanded: proc_macro2::TokenStream = quote! {};
109
110 if near_macro_args.near_bindgen_args.contract_state.is_some() {
111 let near_bindgen_args = near_macro_args.near_bindgen_args;
112 expanded = quote! {#[#near_sdk_crate::near_bindgen(#near_bindgen_args)]};
113 };
114
115 let mut has_borsh = false;
116 let mut has_json = false;
117
118 let mut borsh_attr = quote! {};
119
120 match near_macro_args.serializers {
121 Some(serializers) => {
122 let attr2 = serializers.clone();
123
124 attr2.vec.iter().for_each(|old_expr| {
125 let new_expr = &mut old_expr.clone();
126 match &mut *new_expr {
127 Expr::Call(call_expr) => {
128 if let Expr::Path(path) = &mut *call_expr.func
129 && let Some(ident) = path.path.get_ident()
130 {
131 if *ident == "json" {
132 has_json = true;
133 path.path = syn::Path::from(Ident::new("serde", Span::call_site()));
134 call_expr.args.push(parse_quote! {crate=#string_serde_crate});
135 } else if *ident == "borsh" {
136 has_borsh = true;
137 call_expr.args.push(parse_quote! {crate=#string_borsh_crate});
138 }
139 }
140 borsh_attr = quote! {#[#new_expr]};
141 }
142 Expr::Path(path_expr) => {
143 if let Some(ident) = path_expr.path.get_ident() {
144 if *ident == "json" {
145 has_json = true;
146 }
147 if *ident == "borsh" {
148 has_borsh = true;
149 borsh_attr = quote! {#[borsh(crate=#string_borsh_crate)]};
150 }
151 }
152 }
153 _ => {}
154 }
155 });
156 }
157 None => {
158 has_borsh = true;
159 borsh_attr = quote! {#[borsh(crate = #string_borsh_crate)]};
160 }
161 }
162
163 if has_json {
167 let enable_schemars = cfg!(feature = "abi").then_some(quote! {schemars = true,});
168 expanded = quote! {
169 #expanded
170 #[#near_sdk_crate::serde_with::serde_as(
171 crate = #string_serde_with_crate,
172 #enable_schemars
173 )]
174 #[derive(#near_sdk_crate::serde::Serialize, #near_sdk_crate::serde::Deserialize)]
175 #[serde(crate = #string_serde_crate)]
176 };
177 }
178
179 #[cfg(feature = "abi")]
180 {
181 let schema_derive: proc_macro2::TokenStream =
182 get_schema_derive(has_json, has_borsh, near_sdk_crate.clone(), false);
183 expanded = quote! {
184 #expanded
185 #schema_derive
186 };
187 }
188
189 if has_borsh {
190 expanded = quote! {
191 #expanded
192 #[derive(#near_sdk_crate::borsh::BorshSerialize, #near_sdk_crate::borsh::BorshDeserialize)]
193 #borsh_attr
194 };
195 }
196
197 if let Ok(input) = syn::parse::<ItemStruct>(item.clone()) {
198 expanded = quote! {
199 #expanded
200 #input
201 };
202 } else if let Ok(input) = syn::parse::<ItemEnum>(item.clone()) {
203 expanded = quote! {
204 #expanded
205 #input
206 };
207 } else if let Ok(input) = syn::parse::<ItemImpl>(item) {
208 expanded = quote! {
209 #[#near_sdk_crate::near_bindgen]
210 #input
211 };
212 } else {
213 return TokenStream::from(
214 syn::Error::new(
215 Span::call_site(),
216 "near macro can only be used on struct or enum definition and impl sections.",
217 )
218 .to_compile_error(),
219 );
220 }
221
222 TokenStream::from(expanded)
223}
224
225#[derive(Default, FromMeta)]
226struct NearBindgenMacroArgs {
227 contract_state: Option<core_impl::state::ContractStateArgs>,
228 #[darling(default)]
229 contract_metadata: core_impl::ContractMetadata,
230}
231
232impl quote::ToTokens for NearBindgenMacroArgs {
233 fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
234 let contract_state = &self.contract_state;
235 let contract_metadata = &self.contract_metadata;
236 tokens.extend(quote! {
237 contract_state(#contract_state),
238 contract_metadata(#contract_metadata),
239 })
240 }
241}
242
243#[proc_macro_attribute]
244pub fn near_bindgen(attr: TokenStream, item: TokenStream) -> TokenStream {
245 if attr.to_string().contains("event_json") {
246 return core_impl::near_events(attr, item);
247 }
248
249 let (ident, generics) = if let Ok(input) = syn::parse::<ItemStruct>(item.clone()) {
250 (input.ident, input.generics)
251 } else if let Ok(input) = syn::parse::<ItemEnum>(item.clone()) {
252 (input.ident, input.generics)
253 } else if let Ok(input) = syn::parse::<ItemImpl>(item) {
254 for method in &input.items {
255 if let ImplItem::Fn(m) = method {
256 let ident = &m.sig.ident;
257 if ident.eq("__contract_abi") || ident.eq("contract_source_metadata") {
258 return TokenStream::from(
259 syn::Error::new_spanned(
260 ident.to_token_stream(),
261 "use of reserved contract method",
262 )
263 .to_compile_error(),
264 );
265 }
266 }
267 }
268 return match process_impl_block(input) {
269 Ok(output) => output,
270 Err(output) => output,
271 }
272 .into();
273 } else {
274 return TokenStream::from(
275 syn::Error::new(
276 Span::call_site(),
277 "near_bindgen can only be used on struct or enum definition and impl sections.",
278 )
279 .to_compile_error(),
280 );
281 };
282
283 let attr_args = match NestedMeta::parse_meta_list(attr.into()) {
284 Ok(v) => v,
285 Err(e) => {
286 return Error::from(e).write_errors().into();
287 }
288 };
289
290 let args = match NearBindgenMacroArgs::from_list(&attr_args) {
291 Ok(v) => v,
292 Err(e) => {
293 return e.write_errors().into();
294 }
295 };
296
297 let impl_contract_state = args.contract_state.map(|s| s.impl_contract_state(&ident, &generics));
298 let metadata = args.contract_metadata.contract_source_metadata_const();
299
300 let metadata_impl_gen = {
301 let metadata_impl_gen = generate_contract_metadata_method(&ident, &generics).into();
302
303 let metadata_impl_gen = syn::parse::<ItemImpl>(metadata_impl_gen)
304 .expect("failed to generate contract metadata");
305 process_impl_block(metadata_impl_gen)
306 };
307
308 let metadata_impl_gen = match metadata_impl_gen {
309 Ok(metadata) => metadata,
310 Err(err) => return err.into(),
311 };
312
313 let ext_gen = generate_ext_structs(&ident, Some(&generics));
314 #[cfg(feature = "__abi-embed-checked")]
315 let abi_embedded = abi::embed();
316 #[cfg(not(feature = "__abi-embed-checked"))]
317 let abi_embedded = quote! {};
318 let item = proc_macro2::TokenStream::from(item);
319 TokenStream::from(quote! {
320 #item
321 #ext_gen
322 #abi_embedded
323 #metadata
324 #metadata_impl_gen
325 #impl_contract_state
326 })
327}
328
329fn process_impl_block(
336 mut input: ItemImpl,
337) -> Result<proc_macro2::TokenStream, proc_macro2::TokenStream> {
338 let item_impl_info = match ItemImplInfo::new(&mut input) {
339 Ok(x) => x,
340 Err(err) => return Err(err.to_compile_error()),
341 };
342
343 #[cfg(not(feature = "__abi-generate"))]
344 let abi_generated = quote! {};
345 #[cfg(feature = "__abi-generate")]
346 let abi_generated = abi::generate(&item_impl_info);
347
348 let generated_code = item_impl_info.wrapper_code();
349
350 let ext_generated_code = item_impl_info.generate_ext_wrapper_code();
352
353 Ok(TokenStream::from(quote! {
354 #ext_generated_code
355 #input
356 #generated_code
357 #abi_generated
358 })
359 .into())
360}
361
362#[proc_macro_attribute]
363pub fn ext_contract(attr: TokenStream, item: TokenStream) -> TokenStream {
364 if let Ok(mut input) = syn::parse::<ItemTrait>(item) {
365 let mod_name: Option<proc_macro2::Ident> = if attr.is_empty() {
366 None
367 } else {
368 match syn::parse(attr) {
369 Ok(x) => x,
370 Err(err) => {
371 return TokenStream::from(
372 syn::Error::new(
373 Span::call_site(),
374 format!("Failed to parse mod name for ext_contract: {err}"),
375 )
376 .to_compile_error(),
377 );
378 }
379 }
380 };
381 let item_trait_info = match ItemTraitInfo::new(&mut input, mod_name) {
382 Ok(x) => x,
383 Err(err) => return TokenStream::from(err.to_compile_error()),
384 };
385 let ext_api = item_trait_info.wrap_trait_ext();
386
387 TokenStream::from(quote! {
388 #input
389 #ext_api
390 })
391 } else {
392 TokenStream::from(
393 syn::Error::new(Span::call_site(), "ext_contract can only be used on traits")
394 .to_compile_error(),
395 )
396 }
397}
398
399#[cfg(feature = "abi")]
400#[derive(darling::FromDeriveInput, Debug)]
401#[darling(attributes(abi), forward_attrs(serde, borsh_skip, schemars, validate))]
402struct DeriveNearSchema {
403 attrs: Vec<syn::Attribute>,
404 json: Option<bool>,
405 borsh: Option<bool>,
406}
407
408#[proc_macro_derive(NearSchema, attributes(abi, serde, borsh, schemars, validate, inside_nearsdk))]
409pub fn derive_near_schema(#[allow(unused)] input: TokenStream) -> TokenStream {
410 #[cfg(not(feature = "abi"))]
411 {
412 TokenStream::from(quote! {})
413 }
414
415 #[cfg(feature = "abi")]
416 {
417 use darling::FromDeriveInput;
418
419 let derive_input = syn::parse_macro_input!(input as syn::DeriveInput);
420 let generics = derive_input.generics.clone();
421 let args = match DeriveNearSchema::from_derive_input(&derive_input) {
422 Ok(v) => v,
423 Err(e) => {
424 return TokenStream::from(e.write_errors());
425 }
426 };
427
428 if args.borsh.is_none()
429 && args.json.is_none()
430 && derive_input.clone().attrs.iter().any(|attr| attr.path().is_ident("abi"))
431 {
432 return TokenStream::from(
433 syn::Error::new_spanned(
434 derive_input.to_token_stream(),
435 "At least one of `json` or `borsh` inside of `#[abi(...)]` must be specified",
436 )
437 .to_compile_error(),
438 );
439 }
440
441 let (json_schema, borsh_schema) = (args.json.unwrap_or(false), args.borsh.unwrap_or(false));
443 let mut input = derive_input.clone();
444 input.attrs = args.attrs;
445
446 let strip_unknown_attr = |attrs: &mut Vec<syn::Attribute>| {
447 attrs.retain(|attr| {
448 ["serde", "schemars", "validate", "borsh"]
449 .iter()
450 .any(|&path| attr.path().is_ident(path))
451 });
452 };
453
454 match &mut input.data {
455 syn::Data::Struct(data) => {
456 for field in &mut data.fields {
457 strip_unknown_attr(&mut field.attrs);
458 }
459 }
460 syn::Data::Enum(data) => {
461 for variant in &mut data.variants {
462 strip_unknown_attr(&mut variant.attrs);
463 for field in &mut variant.fields {
464 strip_unknown_attr(&mut field.attrs);
465 }
466 }
467 }
468 syn::Data::Union(_) => {
469 return TokenStream::from(
470 syn::Error::new_spanned(
471 input.to_token_stream(),
472 "`NearSchema` does not support derive for unions",
473 )
474 .to_compile_error(),
475 );
476 }
477 }
478
479 let near_sdk_crate =
480 if derive_input.attrs.iter().any(|attr| attr.path().is_ident("inside_nearsdk")) {
481 quote! {crate}
482 } else {
483 quote! {::near_sdk}
484 };
485
486 let json_schema = json_schema || !borsh_schema;
488
489 let derive = get_schema_derive(json_schema, borsh_schema, near_sdk_crate.clone(), true);
490
491 let input_ident = &input.ident;
492
493 let input_ident_proxy = quote::format_ident!("{}__NEAR_SCHEMA_PROXY", input_ident);
494
495 let json_impl = if json_schema {
496 let where_clause = get_where_clause(
497 &generics,
498 input_ident,
499 quote! {#near_sdk_crate::schemars::JsonSchema},
500 );
501 quote! {
502 #[automatically_derived]
503 impl #generics #near_sdk_crate::schemars::JsonSchema for #input_ident_proxy #generics #where_clause {
504 fn schema_name() -> ::std::string::String {
505 <#input_ident #generics as #near_sdk_crate::schemars::JsonSchema>::schema_name()
506 }
507
508 fn json_schema(r#gen: &mut #near_sdk_crate::schemars::r#gen::SchemaGenerator) -> #near_sdk_crate::schemars::schema::Schema {
509 <#input_ident #generics as #near_sdk_crate::schemars::JsonSchema>::json_schema(r#gen)
510 }
511 }
512 }
513 } else {
514 quote! {}
515 };
516
517 let borsh_impl = if borsh_schema {
518 let where_clause = get_where_clause(
519 &generics,
520 input_ident,
521 quote! {#near_sdk_crate::borsh::BorshSchema},
522 );
523 quote! {
524 #[automatically_derived]
525 impl #generics #near_sdk_crate::borsh::BorshSchema for #input_ident_proxy #generics #where_clause {
526 fn declaration() -> #near_sdk_crate::borsh::schema::Declaration {
527 <#input_ident #generics as #near_sdk_crate::borsh::BorshSchema>::declaration()
528 }
529
530 fn add_definitions_recursively(
531 definitions: &mut #near_sdk_crate::borsh::__private::maybestd::collections::BTreeMap<
532 #near_sdk_crate::borsh::schema::Declaration,
533 #near_sdk_crate::borsh::schema::Definition
534 >,
535 ) {
536 <#input_ident #generics as #near_sdk_crate::borsh::BorshSchema>::add_definitions_recursively(definitions);
537 }
538 }
539 }
540 } else {
541 quote! {}
542 };
543
544 TokenStream::from(quote! {
545 #[cfg(not(target_arch = "wasm32"))]
546 const _: () = {
547 #[allow(non_camel_case_types)]
548 type #input_ident_proxy #generics = #input_ident #generics;
549 {
550 #derive
551 #[allow(dead_code)]
552 #input
553
554 #json_impl
555 #borsh_impl
556 };
557 };
558 })
559 }
560}
561
562#[allow(dead_code)]
563fn get_schema_derive(
564 json_schema: bool,
565 borsh_schema: bool,
566 near_sdk_crate: proc_macro2::TokenStream,
567 need_borsh_crate: bool,
568) -> proc_macro2::TokenStream {
569 let string_borsh_crate = quote! {#near_sdk_crate::borsh}.to_string();
570 let string_schemars_crate = quote! {#near_sdk_crate::schemars}.to_string();
571
572 let mut derive = quote! {};
573 if borsh_schema {
574 derive = quote! {
575 #[cfg_attr(not(target_arch = "wasm32"), derive(#near_sdk_crate::borsh::BorshSchema))]
576 };
577 if need_borsh_crate {
578 derive = quote! {
579 #derive
580 #[cfg_attr(not(target_arch = "wasm32"), borsh(crate = #string_borsh_crate))]
581 };
582 }
583 }
584 if json_schema {
585 derive = quote! {
586 #derive
587 #[cfg_attr(not(target_arch = "wasm32"), derive(#near_sdk_crate::schemars::JsonSchema))]
588 #[cfg_attr(not(target_arch = "wasm32"), schemars(crate = #string_schemars_crate))]
589 };
590 }
591 derive
592}
593
594#[cfg(feature = "abi")]
595fn get_where_clause(
596 generics: &syn::Generics,
597 input_ident: &syn::Ident,
598 trait_name: proc_macro2::TokenStream,
599) -> WhereClause {
600 let (_, ty_generics, where_clause) = generics.split_for_impl();
601
602 let predicate = parse_quote!(#input_ident #ty_generics: #trait_name);
603
604 let where_clause: WhereClause = if let Some(mut w) = where_clause.cloned() {
605 w.predicates.push(predicate);
606 w
607 } else {
608 parse_quote!(where #predicate)
609 };
610 where_clause
611}
612
613#[proc_macro_derive(PanicOnDefault)]
614pub fn derive_no_default(item: TokenStream) -> TokenStream {
615 match syn::parse::<Item>(item) {
616 Ok(Item::Enum(ItemEnum { ident, .. })) | Ok(Item::Struct(ItemStruct { ident, .. })) => {
617 TokenStream::from(quote! {
618 const _: () = {
619 #[automatically_derived]
620 impl ::std::default::Default for #ident {
621 fn default() -> Self {
622 ::near_sdk::env::panic_str("The contract is not initialized");
623 }
624 }
625 };
626 })
627 }
628 _ => TokenStream::from(
629 syn::Error::new(
630 Span::call_site(),
631 "PanicOnDefault can only be used on type declarations sections.",
632 )
633 .to_compile_error(),
634 ),
635 }
636}
637
638#[proc_macro_derive(BorshStorageKey)]
639pub fn borsh_storage_key(item: TokenStream) -> TokenStream {
640 let (name, generics) = if let Ok(input) = syn::parse::<ItemEnum>(item.clone()) {
641 (input.ident, input.generics)
642 } else if let Ok(input) = syn::parse::<ItemStruct>(item) {
643 (input.ident, input.generics)
644 } else {
645 return TokenStream::from(
646 syn::Error::new(
647 Span::call_site(),
648 "BorshStorageKey can only be used as a derive on enums or structs.",
649 )
650 .to_compile_error(),
651 );
652 };
653 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
654 let predicate = parse_quote!(#name #ty_generics: ::near_sdk::borsh::BorshSerialize);
655 let where_clause: WhereClause = if let Some(mut w) = where_clause.cloned() {
656 w.predicates.push(predicate);
657 w
658 } else {
659 parse_quote!(where #predicate)
660 };
661 TokenStream::from(quote! {
662 impl #impl_generics ::near_sdk::__private::BorshIntoStorageKey for #name #ty_generics #where_clause {}
663 })
664}
665
666#[proc_macro_derive(FunctionError)]
667pub fn function_error(item: TokenStream) -> TokenStream {
668 let name = if let Ok(input) = syn::parse::<ItemEnum>(item.clone()) {
669 input.ident
670 } else if let Ok(input) = syn::parse::<ItemStruct>(item) {
671 input.ident
672 } else {
673 return TokenStream::from(
674 syn::Error::new(
675 Span::call_site(),
676 "FunctionError can only be used as a derive on enums or structs.",
677 )
678 .to_compile_error(),
679 );
680 };
681 TokenStream::from(quote! {
682 impl ::near_sdk::FunctionError for #name {
683 fn panic(&self) -> ! {
684 ::near_sdk::env::panic_str(&::std::string::ToString::to_string(&self))
685 }
686 }
687 })
688}
689
690#[proc_macro_derive(EventMetadata, attributes(event_version))]
691pub fn derive_event_attributes(item: TokenStream) -> TokenStream {
692 if let Ok(input) = syn::parse::<ItemEnum>(item) {
693 let name = &input.ident;
694 let standard_name = format!("{name}_event_standard");
696 let standard_ident = syn::Ident::new(&standard_name, Span::call_site());
697 let mut event_meta: Vec<proc_macro2::TokenStream> = vec![];
699 let mut version_arms: Vec<proc_macro2::TokenStream> = vec![];
700 let mut event_name_arms: Vec<proc_macro2::TokenStream> = vec![];
701 for var in &input.variants {
702 if let Some(version) = core_impl::get_event_version(var) {
703 let var_ident = &var.ident;
704 event_meta.push(quote! {
705 #name::#var_ident { .. } => {(::std::string::ToString::to_string(&#standard_ident), ::std::string::ToString::to_string(#version))}
706 });
707 version_arms.push(quote! {
708 #name::#var_ident { .. } => ::std::borrow::Cow::Borrowed(#version)
709 });
710 let event_name =
711 proc_macro2::Literal::string(&var.ident.to_string().to_snake_case());
712 event_name_arms.push(quote! {
713 #name::#var_ident { .. } => ::std::borrow::Cow::Borrowed(#event_name)
714 });
715 } else {
716 return TokenStream::from(
717 syn::Error::new(
718 Span::call_site(),
719 "Near events must have `event_version`. Must have a single string literal value.",
720 )
721 .to_compile_error(),
722 );
723 }
724 }
725
726 let (impl_generics, type_generics, where_clause) = &input.generics.split_for_impl();
728 let mut generics = input.generics.clone();
730 let event_lifetime = syn::Lifetime::new("'near_event", Span::call_site());
731 generics.params.insert(
732 0,
733 syn::GenericParam::Lifetime(syn::LifetimeParam::new(event_lifetime.clone())),
734 );
735
736 TokenStream::from(quote! {
737 impl #impl_generics #name #type_generics #where_clause {
738 pub fn emit(&self) {
739 use ::near_sdk::AsNep297Event;
740 ::near_sdk::env::log_str(&self.to_nep297_event().to_event_log());
741 }
742
743 pub fn to_json(&self) -> ::near_sdk::serde_json::Value {
744 use ::near_sdk::AsNep297Event;
745 self.to_nep297_event().to_json()
746 }
747
748 pub fn standard(&self) -> ::std::borrow::Cow<'_, str> {
749 ::std::borrow::Cow::Borrowed(#standard_ident)
750 }
751
752 pub fn version(&self) -> ::std::borrow::Cow<'_, str> {
753 match self {
754 #(#version_arms),*
755 }
756 }
757
758 pub fn event(&self) -> ::std::borrow::Cow<'_, str> {
759 match self {
760 #(#event_name_arms),*
761 }
762 }
763 }
764
765 impl #impl_generics ::near_sdk::events::AsNep297Event for #name #type_generics #where_clause{
766 fn to_nep297_event(&self) -> ::near_sdk::events::Nep297Event<'_, Self> {
767 ::near_sdk::events::Nep297Event::new(
768 ::std::borrow::Cow::Borrowed(#standard_ident),
769 match self {
770 #(#version_arms),*
771 },
772 match self {
773 #(#event_name_arms),*
774 },
775 self,
776 )
777 }
778 }
779
780
781 })
782 } else {
783 TokenStream::from(
784 syn::Error::new(
785 Span::call_site(),
786 "EventMetadata can only be used as a derive on enums.",
787 )
788 .to_compile_error(),
789 )
790 }
791}