diff --git a/examples/mission-control/src/account.rs b/examples/mission-control/src/account.rs index 720dae057..0775dc97a 100644 --- a/examples/mission-control/src/account.rs +++ b/examples/mission-control/src/account.rs @@ -1,12 +1,12 @@ +use crate::asset::*; +use crate::rate::*; +use near_sdk::borsh::{BorshDeserialize, BorshSerialize}; +use near_sdk::serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::ops; - use near_sdk::NearSchema; -use near_sdk::borsh::{BorshDeserialize, BorshSerialize}; -use near_sdk::serde::{Deserialize, Serialize}; -use crate::asset::*; -use crate::rate::*; +use near_sdk::near; #[derive( PartialEq, @@ -15,20 +15,17 @@ use crate::rate::*; Hash, Clone, Copy, - Serialize, - Deserialize, Debug, - BorshDeserialize, - BorshSerialize, NearSchema, )] -#[serde(crate = "near_sdk::serde")] -#[borsh(crate = "near_sdk::borsh")] +#[near(serializers = [json, borsh])] pub struct Quantity(pub i32); -#[derive(Clone, Serialize, Deserialize, BorshDeserialize, BorshSerialize, NearSchema)] -#[serde(crate = "near_sdk::serde")] -#[borsh(crate = "near_sdk::borsh")] +#[near] +pub struct X; + +#[derive(Clone, NearSchema)] +#[near(serializers = [json, borsh])] pub struct Account(pub HashMap); pub enum Tranx { diff --git a/examples/mission-control/src/agent.rs b/examples/mission-control/src/agent.rs index 86cb55bf3..92b6f1d66 100644 --- a/examples/mission-control/src/agent.rs +++ b/examples/mission-control/src/agent.rs @@ -4,10 +4,10 @@ use crate::rate::*; use near_sdk::borsh::{BorshDeserialize, BorshSerialize}; use near_sdk::serde::{Deserialize, Serialize}; use std::collections::HashMap; +use near_sdk::near; -#[derive(Clone, Serialize, Deserialize, BorshDeserialize, BorshSerialize)] -#[serde(crate = "near_sdk::serde")] -#[borsh(crate = "near_sdk::borsh")] +#[derive(Clone)] +#[near(serializers=[json, borsh])] pub struct Agent { pub account: Account, pub is_alive: bool, diff --git a/examples/mission-control/src/asset.rs b/examples/mission-control/src/asset.rs index 2eddc3aeb..0b5626a2e 100644 --- a/examples/mission-control/src/asset.rs +++ b/examples/mission-control/src/asset.rs @@ -1,6 +1,5 @@ use near_sdk::NearSchema; -use near_sdk::borsh::{BorshDeserialize, BorshSerialize}; -use near_sdk::serde::{Deserialize, Serialize}; +use near_sdk::near; #[derive( PartialEq, @@ -10,14 +9,9 @@ use near_sdk::serde::{Deserialize, Serialize}; Hash, Clone, Copy, - Serialize, - Deserialize, - BorshDeserialize, - BorshSerialize, NearSchema, )] -#[serde(crate = "near_sdk::serde")] -#[borsh(crate = "near_sdk::borsh")] +#[near(serializers = [json, borsh])] pub enum Resource { Battery, RgbSensor, @@ -33,14 +27,9 @@ pub enum Resource { Hash, Clone, Copy, - Serialize, - Deserialize, - BorshDeserialize, - BorshSerialize, NearSchema, )] -#[serde(crate = "near_sdk::serde")] -#[borsh(crate = "near_sdk::borsh")] +#[near(serializers = [json, borsh])] pub enum Reward { Score, Token, @@ -57,14 +46,9 @@ pub enum Reward { Hash, Clone, Copy, - Serialize, - Deserialize, - BorshDeserialize, - BorshSerialize, NearSchema, )] -#[serde(crate = "near_sdk::serde")] -#[borsh(crate = "near_sdk::borsh")] +#[near(serializers = [json, borsh])] pub enum Asset { Resource(Resource), Reward(Reward), @@ -76,16 +60,11 @@ pub enum Asset { PartialEq, Eq, Hash, - Serialize, - Deserialize, PartialOrd, Ord, - BorshDeserialize, - BorshSerialize, NearSchema )] -#[serde(crate = "near_sdk::serde")] -#[borsh(crate = "near_sdk::borsh")] +#[near(serializers = [json, borsh])] pub enum Exchange { MissionTimeWithResource, MissionTimeWithTrust, diff --git a/examples/mission-control/src/mission_control.rs b/examples/mission-control/src/mission_control.rs index daf5ffeec..e3b2f2a34 100644 --- a/examples/mission-control/src/mission_control.rs +++ b/examples/mission-control/src/mission_control.rs @@ -7,18 +7,21 @@ use near_sdk::borsh::{BorshDeserialize, BorshSerialize}; use near_sdk::serde::{Deserialize, Serialize}; use near_sdk::{env, near_bindgen}; use std::collections::HashMap; +use near_sdk::near; -#[near_bindgen] -#[derive(Serialize, Deserialize, BorshDeserialize, BorshSerialize)] -#[serde(crate = "near_sdk::serde")] -#[borsh(crate = "near_sdk::borsh")] +// #[near_bindgen] +// #[derive(Serialize, Deserialize, BorshDeserialize, BorshSerialize)] +// #[serde(crate = "near_sdk::serde")] +// #[borsh(crate = "near_sdk::borsh")] +#[near(serializers=[json, borsh, bindgen])] pub struct MissionControl { account: Account, agents: HashMap, rates: HashMap, } -#[near_bindgen] +// #[near] +#[near(serializers=[json, borsh, bindgen])] impl MissionControl { pub fn add_agent(&mut self) { let account_id = env::signer_account_id(); diff --git a/examples/mission-control/src/rate.rs b/examples/mission-control/src/rate.rs index 1d49234c1..7390d69f4 100644 --- a/examples/mission-control/src/rate.rs +++ b/examples/mission-control/src/rate.rs @@ -1,12 +1,10 @@ use crate::account::*; use crate::asset::*; -use near_sdk::borsh::{BorshDeserialize, BorshSerialize}; -use near_sdk::serde::{Deserialize, Serialize}; use std::collections::HashMap; +use near_sdk::near; -#[derive(PartialEq, Eq, Serialize, Deserialize, BorshDeserialize, BorshSerialize)] -#[serde(crate = "near_sdk::serde")] -#[borsh(crate = "near_sdk::borsh")] +#[derive(PartialEq, Eq)] +#[near(serializers = [json, borsh])] pub struct Rate { pub credit: HashMap, pub debit: HashMap, diff --git a/kek.rs b/kek.rs new file mode 100644 index 000000000..b1e81813c --- /dev/null +++ b/kek.rs @@ -0,0 +1,119 @@ +#[derive(near_sdk :: NearSchema)] +#[derive(near_sdk :: borsh :: BorshSerialize, near_sdk :: borsh :: +BorshDeserialize)] #[borsh(crate = "near_sdk::borsh")] +#[derive(near_sdk :: serde :: Serialize, near_sdk :: serde :: Deserialize)] +#[serde(crate = "near_sdk::serde")] #[abi(borsh, json)] pub struct +Quantity(pub i32) ; +mynear +#[derive(near_sdk :: NearSchema)] +#[derive(near_sdk :: borsh :: BorshSerialize, near_sdk :: borsh :: +BorshDeserialize)] #[borsh(crate = "near_sdk::borsh")] #[abi(borsh)] pub +struct X ; +mynear +#[derive(near_sdk :: NearSchema)] +#[derive(near_sdk :: borsh :: BorshSerialize, near_sdk :: borsh :: +BorshDeserialize)] #[borsh(crate = "near_sdk::borsh")] +#[derive(near_sdk :: serde :: Serialize, near_sdk :: serde :: Deserialize)] +#[serde(crate = "near_sdk::serde")] #[abi(borsh, json)] pub struct +Account(pub HashMap < Asset, Quantity >) ; +mynear +#[derive(near_sdk :: NearSchema)] +#[derive(near_sdk :: borsh :: BorshSerialize, near_sdk :: borsh :: +BorshDeserialize)] #[borsh(crate = "near_sdk::borsh")] +#[derive(near_sdk :: serde :: Serialize, near_sdk :: serde :: Deserialize)] +#[serde(crate = "near_sdk::serde")] #[abi(borsh, json)] pub struct Agent +{ pub account : Account, pub is_alive : bool, } +mynear +#[derive(near_sdk :: NearSchema)] +#[derive(near_sdk :: borsh :: BorshSerialize, near_sdk :: borsh :: +BorshDeserialize)] #[borsh(crate = "near_sdk::borsh")] +#[derive(near_sdk :: serde :: Serialize, near_sdk :: serde :: Deserialize)] +#[serde(crate = "near_sdk::serde")] #[abi(borsh, json)] pub enum Resource +{ Battery, RgbSensor, ThermalSensor, PoseEstimation, } +mynear +#[derive(near_sdk :: NearSchema)] +#[derive(near_sdk :: borsh :: BorshSerialize, near_sdk :: borsh :: +BorshDeserialize)] #[borsh(crate = "near_sdk::borsh")] +#[derive(near_sdk :: serde :: Serialize, near_sdk :: serde :: Deserialize)] +#[serde(crate = "near_sdk::serde")] #[abi(borsh, json)] pub enum Reward +{ Score, Token, Prediction, Currency, Policy, } +mynear +#[derive(near_sdk :: NearSchema)] +#[derive(near_sdk :: borsh :: BorshSerialize, near_sdk :: borsh :: +BorshDeserialize)] #[borsh(crate = "near_sdk::borsh")] +#[derive(near_sdk :: serde :: Serialize, near_sdk :: serde :: Deserialize)] +#[serde(crate = "near_sdk::serde")] #[abi(borsh, json)] pub enum Asset +{ Resource(Resource), Reward(Reward), MissionTime, Trust, } +mynear +#[derive(near_sdk :: NearSchema)] +#[derive(near_sdk :: borsh :: BorshSerialize, near_sdk :: borsh :: +BorshDeserialize)] #[borsh(crate = "near_sdk::borsh")] +#[derive(near_sdk :: serde :: Serialize, near_sdk :: serde :: Deserialize)] +#[serde(crate = "near_sdk::serde")] #[abi(borsh, json)] pub enum Exchange +{ MissionTimeWithResource, MissionTimeWithTrust, } +mynear +#[derive(near_sdk :: NearSchema)] +#[derive(near_sdk :: borsh :: BorshSerialize, near_sdk :: borsh :: +BorshDeserialize)] #[borsh(crate = "near_sdk::borsh")] +#[derive(near_sdk :: serde :: Serialize, near_sdk :: serde :: Deserialize)] +#[serde(crate = "near_sdk::serde")] #[abi(borsh, json)] pub struct +MissionControl +{ + account : Account, agents : HashMap < AccountId, Agent >, rates : HashMap + < Exchange, Rate >, +} +mynear +impl MissionControlExt +{ + pub fn add_agent(self,) -> :: near_sdk :: Promise + { + let __args = :: std :: vec! [] ; :: near_sdk :: Promise :: + new(self.account_id).function_call_weight(:: std :: string :: String + :: from("add_agent"), __args, self.deposit, self.static_gas, + self.gas_weight,) + } pub fn assets_quantity(self, account_id : AccountId, asset : Asset,) -> + :: near_sdk :: Promise + { + let __args = + { + #[derive(:: near_sdk :: serde :: Serialize)] + #[serde(crate = "::near_sdk::serde")] struct Input < 'nearinput > + { + account_id : & 'nearinput AccountId, asset : & 'nearinput + Asset, + } let __args = Input + { account_id : & account_id, asset : & asset, } ; :: near_sdk :: + serde_json :: + to_vec(& + __args).expect("Failed to serialize the cross contract args using JSON.") + } ; :: near_sdk :: Promise :: + new(self.account_id).function_call_weight(:: std :: string :: String + :: from("assets_quantity"), __args, self.deposit, self.static_gas, + self.gas_weight,) + } pub fn simulate(self, account_id : AccountId,) -> :: near_sdk :: Promise + { + let __args = + { + #[derive(:: near_sdk :: serde :: Serialize)] + #[serde(crate = "::near_sdk::serde")] struct Input < 'nearinput > + { account_id : & 'nearinput AccountId, } let __args = Input + { account_id : & account_id, } ; :: near_sdk :: serde_json :: + to_vec(& + __args).expect("Failed to serialize the cross contract args using JSON.") + } ; :: near_sdk :: Promise :: + new(self.account_id).function_call_weight(:: std :: string :: String + :: from("simulate"), __args, self.deposit, self.static_gas, + self.gas_weight,) + } +} +process_impl_block +#[derive(near_sdk :: NearSchema)] +#[derive(near_sdk :: borsh :: BorshSerialize, near_sdk :: borsh :: +BorshDeserialize)] #[borsh(crate = "near_sdk::borsh")] +#[derive(near_sdk :: serde :: Serialize, near_sdk :: serde :: Deserialize)] +#[serde(crate = "near_sdk::serde")] #[abi(borsh, json)] pub struct Rate +{ + pub credit : HashMap < Asset, Quantity >, pub debit : HashMap < Asset, + Quantity >, +} +mynear \ No newline at end of file diff --git a/near-sdk-macros/src/lib.rs b/near-sdk-macros/src/lib.rs index c6a4c105f..d31e91571 100644 --- a/near-sdk-macros/src/lib.rs +++ b/near-sdk-macros/src/lib.rs @@ -10,7 +10,172 @@ use proc_macro::TokenStream; use self::core_impl::*; use proc_macro2::{Ident, Span}; use quote::{quote, ToTokens}; -use syn::{parse_quote, ImplItem, ItemEnum, ItemImpl, ItemStruct, ItemTrait, WhereClause}; +use syn::{parse_quote, parse_macro_input, ImplItem, ItemEnum, ItemImpl, ItemStruct, ItemTrait, WhereClause, DeriveInput}; +use darling::{Error, FromMeta}; +use darling::ast::NestedMeta; +use darling; +// use syn::Meta; + + +#[derive(Debug)] +struct MyVec { + vec: Vec, +} +impl FromMeta for MyVec { + fn from_list(items: &[NestedMeta]) -> Result { + Ok(MyVec { + vec: + items + .iter() + .map(::from_nested_meta) + .map(|x| x.unwrap()) + .collect() + }) + } + + fn from_value(value: &syn::Lit) -> Result { + let expr_array = syn::ExprArray::from_value(value)?; + Self::from_expr(&syn::Expr::Array(expr_array)) + } + + fn from_expr(expr: &syn::Expr) -> Result { + match expr { + syn::Expr::Array(expr_array) => Ok(MyVec {vec: expr_array + .elems + .iter() + .map(::from_expr) + .map(|x| x.unwrap()) + .collect::>() + }), + syn::Expr::Lit(expr_lit) => Self::from_value(&expr_lit.lit), + syn::Expr::Group(g) => Self::from_expr(&g.expr), + _ => Err(Error::unexpected_expr_type(expr)), + } + } +} + +#[derive(Debug, FromMeta)] +struct MacroArgs { + serializers: Option, +} + +#[proc_macro_attribute] +pub fn kek(attr: TokenStream, item: TokenStream) -> TokenStream { + let input = parse_macro_input!(item as DeriveInput); + + eprintln!("{}", attr); + + return TokenStream::from(quote! {#input}); +} + +#[proc_macro_attribute] +pub fn near(attr: TokenStream, item: TokenStream) -> TokenStream { + let attr_args = match NestedMeta::parse_meta_list(attr.into()) { + Ok(v) => v, + Err(e) => { return TokenStream::from(Error::from(e).write_errors()); } + }; + + let _args = match MacroArgs::from_list(&attr_args) { + Ok(v) => v, + Err(e) => { return TokenStream::from(e.write_errors()); } + }; + + let mut has_borsh = false; + let mut has_json = false; + let mut has_bindgen = false; + + match _args.serializers { + Some(serializers) => { + for arg in serializers.vec { + if arg.to_string() == "borsh" { + has_borsh = true; + } else if arg.to_string() == "json" { + has_json = true; + } else if arg.to_string() == "bindgen" { + has_bindgen = true; + } else { + eprintln!("baaad"); + return TokenStream::new(); + } + } + }, + None => { + has_borsh = true; + }, + } + + let borsh = if has_borsh {quote!{ + #[derive(near_sdk::borsh::BorshSerialize, near_sdk::borsh::BorshDeserialize)] + #[borsh(crate = "near_sdk::borsh")] + }} else {quote!{}}; + let json = if has_json {quote!{ + #[derive(near_sdk::serde::Serialize, near_sdk::serde::Deserialize)] + #[serde(crate = "near_sdk::serde")] + }} else {quote!{}}; + let bindgen = if has_bindgen {quote!{ + #[near_sdk::near_bindgen] + }} else {quote!{}}; + + let mut abis = quote!{}; + if has_borsh && has_json { + abis = quote! { #[abi(borsh, json)] }; + } else if has_borsh { + abis = quote! { #[abi(borsh)] }; + } else if has_json { + abis = quote! { #[abi(json)] }; + } + + let theitem = item.clone(); + + let mut expanded; + if let Ok(input) = syn::parse::(item.clone()) { + expanded = quote! { + #[derive(near_sdk::NearSchema)] + #borsh + #json + #abis + #bindgen + #input + }; + } else if let Ok(input) = syn::parse::(item.clone()) { + expanded = quote! { + #[derive(near_sdk::NearSchema)] + #borsh + #json + #abis + #bindgen + #input + }; + } else if let Ok(input) = syn::parse::(item) { + expanded = quote! { + #bindgen + #input + }; + } else { + return TokenStream::from( + syn::Error::new( + Span::call_site(), + "near macro can only be used on struct or enum definition and impl sections.", + ) + .to_compile_error(), + ); + } + + // if let Ok(input) = syn::parse::(item) { + // let expanded = quote! { + // #[near_bindgen] + // #input + // }; + // return TokenStream::from(expanded); + // } + + + + eprintln!("{}", expanded); + eprintln!("mynear"); + + TokenStream::from(expanded) +} /// This attribute macro is used on a struct and its implementations /// to generate the necessary code to expose `pub` methods from the contract as well @@ -139,6 +304,13 @@ pub fn near_bindgen(attr: TokenStream, item: TokenStream) -> TokenStream { let abi_embedded = abi::embed(); #[cfg(not(feature = "__abi-embed-checked"))] let abi_embedded = quote! {}; + + eprintln!("ext structs:\n {}", ext_gen); + eprintln!("abi embedded:\n {}", abi_embedded); + eprintln!("metadata:\n {}", metadata); + eprintln!("metadata_impl_gen:\n {}", metadata_impl_gen); + eprintln!("finish"); + TokenStream::from(quote! { #input #ext_gen @@ -167,7 +339,7 @@ pub fn near_bindgen(attr: TokenStream, item: TokenStream) -> TokenStream { #metadata #metadata_impl_gen }) - } else if let Ok(input) = syn::parse::(item) { + } else if let Ok(mut input) = syn::parse::(item) { for method in &input.items { if let ImplItem::Fn(m) = method { let ident = &m.sig.ident; @@ -182,11 +354,58 @@ pub fn near_bindgen(attr: TokenStream, item: TokenStream) -> TokenStream { } } } - match process_impl_block(input) { + let x: proc_macro2::TokenStream = (match process_impl_block(input.clone()) { Ok(output) => output, Err(output) => output, } - .into() + .into()); + + let the_indent: Ident; + + if let Ok(x) = ItemImplInfo::new(& mut input) { + if let Ok(n) = syn::parse::(x.ty.to_token_stream().into()) { + the_indent = n; + } else { + return TokenStream::from( + syn::Error::new( + Span::call_site(), + "bad", + ) + .to_compile_error(), + ); + } + } else { + return TokenStream::from( + syn::Error::new( + Span::call_site(), + "bad", + ) + .to_compile_error(), + ); + } + + let metadata = core_impl::contract_source_metadata_const(attr); + let metadata_impl_gen = generate_metadata(&the_indent, &input.generics); + + let metadata_impl_gen = match metadata_impl_gen { + Ok(metadata) => metadata, + Err(err) => return err.into(), + }; + + #[cfg(feature = "__abi-embed-checked")] + let abi_embedded = abi::embed(); + #[cfg(not(feature = "__abi-embed-checked"))] + let abi_embedded = quote! {}; + + eprintln!("impl is: {}", x); + eprintln!("finish impl"); + TokenStream::from(quote! { + #x + // #abi_embedded + // #metadata + // #metadata_impl_gen + }) + } else { TokenStream::from( syn::Error::new( @@ -222,6 +441,11 @@ fn process_impl_block( // Add wrapper methods for ext call API let ext_generated_code = item_impl_info.generate_ext_wrapper_code(); + eprintln!("{}", quote! { + #ext_generated_code + }); + eprintln!("process_impl_block"); + Ok(TokenStream::from(quote! { #ext_generated_code #input diff --git a/near-sdk/src/lib.rs b/near-sdk/src/lib.rs index 2a97f93ce..492bd1621 100644 --- a/near-sdk/src/lib.rs +++ b/near-sdk/src/lib.rs @@ -8,8 +8,7 @@ extern crate quickcheck; pub use near_sdk_macros::{ - ext_contract, near_bindgen, BorshStorageKey, EventMetadata, FunctionError, NearSchema, - PanicOnDefault, + ext_contract, near_bindgen, near, kek, BorshStorageKey, EventMetadata, FunctionError, NearSchema, PanicOnDefault, }; pub mod store;