frame_support_procedural/
transactional.rs1use frame_support_procedural_tools::generate_access_from_frame_or_crate;
19use proc_macro::TokenStream;
20use quote::quote;
21use syn::{ItemFn, Result};
22
23pub fn transactional(_attr: TokenStream, input: TokenStream) -> Result<TokenStream> {
24 let ItemFn { attrs, vis, sig, block } = syn::parse(input)?;
25
26 let crate_ = generate_access_from_frame_or_crate("frame-support")?;
27 let output = quote! {
28 #(#attrs)*
29 #vis #sig {
30 use #crate_::storage::{with_transaction, TransactionOutcome};
31 with_transaction(|| {
32 let r = (|| { #block })();
33 if r.is_ok() {
34 TransactionOutcome::Commit(r)
35 } else {
36 TransactionOutcome::Rollback(r)
37 }
38 })
39 }
40 };
41
42 Ok(output.into())
43}
44
45pub fn require_transactional(_attr: TokenStream, input: TokenStream) -> Result<TokenStream> {
46 let ItemFn { attrs, vis, sig, block } = syn::parse(input)?;
47
48 let crate_ = generate_access_from_frame_or_crate("frame-support")?;
49 let output = quote! {
50 #(#attrs)*
51 #vis #sig {
52 if !#crate_::storage::transactional::is_transactional() {
53 return Err(#crate_::sp_runtime::TransactionalError::NoLayer.into());
54 }
55 #block
56 }
57 };
58
59 Ok(output.into())
60}