1#![recursion_limit = "128"]
2extern crate proc_macro;
3use proc_macro::TokenStream;
4use std::env;
5use subcontract::derive_contract_impl;
6use subcontract::storage;
7
8use quote::quote;
9use syn::Item;
10
11mod contract;
12mod subcontract;
13mod util;
14
15#[proc_macro_attribute]
24pub fn subcontract(_: TokenStream, item: TokenStream) -> TokenStream {
25 let parsed: Item = syn::parse(item).unwrap();
26 subcontract::generate(&parsed).into()
27}
28
29#[deprecated(since = "0.9.0", note = "Please use #[loamstorage] instead.")]
30#[proc_macro_derive(IntoKey)]
31pub fn into_key(item: TokenStream) -> TokenStream {
32 syn::parse::<Item>(item)
33 .and_then(subcontract::into_key::from_item)
34 .map_or_else(|e| e.to_compile_error().into(), Into::into)
35}
36
37#[proc_macro_derive(Lazy)]
38pub fn lazy(item: TokenStream) -> TokenStream {
39 syn::parse::<Item>(item)
40 .and_then(subcontract::lazy::from_item)
41 .map_or_else(|e| e.to_compile_error().into(), Into::into)
42}
43
44pub(crate) fn manifest() -> std::path::PathBuf {
45 std::path::PathBuf::from(
46 env::var("CARGO_MANIFEST_DIR").expect("failed to finde cargo manifest"),
47 )
48 .join("Cargo.toml")
49}
50
51#[proc_macro]
62pub fn import_contract(tokens: TokenStream) -> TokenStream {
63 let cargo_file = manifest();
64 let mut dir = loam_build::get_target_dir(&cargo_file)
65 .unwrap()
66 .join(tokens.to_string());
67 let name = syn::parse::<syn::Ident>(tokens).expect("The input must be a valid identifier");
68 dir.set_extension("wasm");
69 let binding = dir.canonicalize().unwrap();
70 let file = binding.to_str().unwrap();
71 quote! {
72 mod #name {
73 use loam_sdk::soroban_sdk;
74 loam_sdk::soroban_sdk::contractimport!(file = #file);
75 }
76 }
77 .into()
78}
79
80#[proc_macro_attribute]
109pub fn derive_contract(args: TokenStream, item: TokenStream) -> TokenStream {
110 let parsed: Item = syn::parse(item.clone()).expect("failed to parse Item");
111 derive_contract_impl(proc_macro2::TokenStream::from(args), parsed).into()
112}
113
114#[proc_macro]
120pub fn stellar_asset(input: TokenStream) -> TokenStream {
121 let input_str = syn::parse_macro_input!(input as syn::LitStr);
123 let network = std::env::var("STELLAR_NETWORK").unwrap_or_else(|_| "local".to_owned());
124 let asset = util::parse_asset_literal(&input_str, &network);
125
126 asset.into()
128}
129
130#[proc_macro_attribute]
131pub fn loamstorage(_attr: TokenStream, item: TokenStream) -> TokenStream {
132 syn::parse::<Item>(item)
133 .and_then(storage::from_item)
134 .map_or_else(|e| e.to_compile_error().into(), Into::into)
135}