feat(rmc): start implementing new rmc protocol abstraction
This commit is contained in:
parent
3ea7c7e671
commit
6f02339464
6 changed files with 283 additions and 77 deletions
51
Cargo.lock
generated
51
Cargo.lock
generated
|
|
@ -66,7 +66,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -77,7 +77,7 @@ checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -225,7 +225,7 @@ dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
"which",
|
"which",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -267,7 +267,7 @@ checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -418,7 +418,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"proc-macro2-diagnostics",
|
"proc-macro2-diagnostics",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1051,7 +1051,7 @@ version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1266,7 +1266,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"proc-macro2-diagnostics",
|
"proc-macro2-diagnostics",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1302,7 +1302,7 @@ checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1339,7 +1339,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac"
|
checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1359,7 +1359,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
"version_check",
|
"version_check",
|
||||||
"yansi",
|
"yansi",
|
||||||
]
|
]
|
||||||
|
|
@ -1390,7 +1390,7 @@ dependencies = [
|
||||||
"prost",
|
"prost",
|
||||||
"prost-types",
|
"prost-types",
|
||||||
"regex",
|
"regex",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1404,7 +1404,7 @@ dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1521,7 +1521,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1633,7 +1633,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rocket_http",
|
"rocket_http",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
@ -1764,7 +1764,7 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1869,6 +1869,7 @@ dependencies = [
|
||||||
"macros",
|
"macros",
|
||||||
"md-5",
|
"md-5",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"paste",
|
||||||
"prost",
|
"prost",
|
||||||
"rand 0.9.0-beta.3",
|
"rand 0.9.0-beta.3",
|
||||||
"rc4",
|
"rc4",
|
||||||
|
|
@ -1921,9 +1922,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.96"
|
version = "2.0.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
|
checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -1976,7 +1977,7 @@ checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2047,7 +2048,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2149,7 +2150,7 @@ dependencies = [
|
||||||
"prost-build",
|
"prost-build",
|
||||||
"prost-types",
|
"prost-types",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2217,7 +2218,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2376,7 +2377,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2398,7 +2399,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
@ -2666,7 +2667,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2677,7 +2678,7 @@ checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.96",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ macros = { path = "macros" }
|
||||||
rocket = { version = "0.5.1", features = ["json", "serde_json"] }
|
rocket = { version = "0.5.1", features = ["json", "serde_json"] }
|
||||||
serde = { version = "1.0.217", features = ["derive"] }
|
serde = { version = "1.0.217", features = ["derive"] }
|
||||||
async-trait = "0.1.86"
|
async-trait = "0.1.86"
|
||||||
|
paste = "1.0.15"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tonic-build = "0.12.3"
|
tonic-build = "0.12.3"
|
||||||
|
|
|
||||||
4
macros/Cargo.lock
generated
4
macros/Cargo.lock
generated
|
|
@ -31,9 +31,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "2.0.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ edition = "2018"
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
quote = "1"
|
quote = "1.0.38"
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0.93"
|
||||||
syn = "1.0"
|
syn = { version = "2.0.98", features = ["full"] }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
|
|
||||||
use proc_macro2::TokenTree;
|
use proc_macro2::{Ident, Literal, Span, TokenTree};
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
|
use std::iter::FromIterator;
|
||||||
use syn::{parse_macro_input, DeriveInput, Data};
|
use syn::{parse_macro_input, DeriveInput, Data, PathSegment, TraitItem, FieldsNamed, Fields, Visibility, Type, TypePath, Path, ImplItem, ImplItemConst, Expr, ExprLit, Lit};
|
||||||
use quote::{quote, TokenStreamExt};
|
use quote::{quote, ToTokens, TokenStreamExt};
|
||||||
|
use syn::parse::ParseStream;
|
||||||
|
use syn::punctuated::Punctuated;
|
||||||
|
use syn::spanned::Spanned;
|
||||||
|
use syn::Visibility::Public;
|
||||||
|
|
||||||
/// Example of user-defined [derive mode macro][1]
|
/// Example of user-defined [derive mode macro][1]
|
||||||
///
|
///
|
||||||
|
|
@ -15,8 +18,8 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream {
|
||||||
let derive_input = parse_macro_input!(input as DeriveInput);
|
let derive_input = parse_macro_input!(input as DeriveInput);
|
||||||
|
|
||||||
let struct_attr = derive_input.attrs.iter()
|
let struct_attr = derive_input.attrs.iter()
|
||||||
.find(|a| a.path.segments.len() == 1 &&
|
.find(|a| a.path().segments.len() == 1 &&
|
||||||
a.path.segments.first().is_some_and(|p| p.ident.to_string() == "rmc_struct"));
|
a.path().segments.first().is_some_and(|p| p.ident.to_string() == "rmc_struct"));
|
||||||
|
|
||||||
let Data::Struct(s) = derive_input.data else {
|
let Data::Struct(s) = derive_input.data else {
|
||||||
panic!("rmc struct type MUST be a struct");
|
panic!("rmc struct type MUST be a struct");
|
||||||
|
|
@ -29,8 +32,8 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
for f in &s.fields{
|
for f in &s.fields{
|
||||||
if f.attrs.iter()
|
if f.attrs.iter()
|
||||||
.any(|a| a.path.segments.len() == 1 &&
|
.any(|a| a.path().segments.len() == 1 &&
|
||||||
a.path.segments.first().is_some_and(|p| p.ident.to_string() == "extends")){
|
a.path().segments.first().is_some_and(|p| p.ident.to_string() == "extends")){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let ident = f.ident.as_ref().unwrap();
|
let ident = f.ident.as_ref().unwrap();
|
||||||
|
|
@ -67,8 +70,8 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
for f in &s.fields{
|
for f in &s.fields{
|
||||||
if f.attrs.iter()
|
if f.attrs.iter()
|
||||||
.any(|a| a.path.segments.len() == 1 &&
|
.any(|a| a.path().segments.len() == 1 &&
|
||||||
a.path.segments.first().is_some_and(|p| p.ident.to_string() == "extends")){
|
a.path().segments.first().is_some_and(|p| p.ident.to_string() == "extends")){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,23 +92,12 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream {
|
||||||
// generate base with extends stuff
|
// generate base with extends stuff
|
||||||
|
|
||||||
let serialize_base_content = if let Some(attr) = struct_attr{
|
let serialize_base_content = if let Some(attr) = struct_attr{
|
||||||
let tokens = attr.tokens.clone();
|
let version: Literal = attr.parse_args().expect("has to be a literal");
|
||||||
let token = tokens.into_iter().next().unwrap();
|
|
||||||
|
|
||||||
let version = match token {
|
|
||||||
TokenTree::Group(g) => {
|
|
||||||
match g.stream().into_iter().next().unwrap(){
|
|
||||||
TokenTree::Literal(l) => l,
|
|
||||||
_ => panic!("expected literal")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => panic!("expected group")
|
|
||||||
};
|
|
||||||
|
|
||||||
let pre_inner = if let Some(f) = s.fields.iter().find(|f| {
|
let pre_inner = if let Some(f) = s.fields.iter().find(|f| {
|
||||||
f.attrs.iter()
|
f.attrs.iter()
|
||||||
.any(|a| a.path.segments.len() == 1 &&
|
.any(|a| a.path().segments.len() == 1 &&
|
||||||
a.path.segments.first().is_some_and(|p| p.ident.to_string() == "extends"))
|
a.path().segments.first().is_some_and(|p| p.ident.to_string() == "extends"))
|
||||||
}){
|
}){
|
||||||
let ident= f.ident.as_ref().unwrap();
|
let ident= f.ident.as_ref().unwrap();
|
||||||
quote! {
|
quote! {
|
||||||
|
|
@ -128,22 +120,12 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream {
|
||||||
};
|
};
|
||||||
|
|
||||||
let deserialize_base_content = if let Some(attr) = struct_attr{
|
let deserialize_base_content = if let Some(attr) = struct_attr{
|
||||||
let tokens = attr.tokens.clone();
|
let version: Literal = attr.parse_args().expect("has to be a literal");
|
||||||
let token = tokens.into_iter().next().unwrap();
|
|
||||||
|
|
||||||
let version = match token {
|
|
||||||
TokenTree::Group(g) => {
|
|
||||||
match g.stream().into_iter().next().unwrap(){
|
|
||||||
TokenTree::Literal(l) => l,
|
|
||||||
_ => panic!("expected literal")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => panic!("expected group")
|
|
||||||
};
|
|
||||||
let pre_inner = if let Some(f) = s.fields.iter().find(|f| {
|
let pre_inner = if let Some(f) = s.fields.iter().find(|f| {
|
||||||
f.attrs.iter()
|
f.attrs.iter()
|
||||||
.any(|a| a.path.segments.len() == 1 &&
|
.any(|a| a.path().segments.len() == 1 &&
|
||||||
a.path.segments.first().is_some_and(|p| p.ident.to_string() == "extends"))
|
a.path().segments.first().is_some_and(|p| p.ident.to_string() == "extends"))
|
||||||
}){
|
}){
|
||||||
let ident= f.ident.as_ref().unwrap();
|
let ident= f.ident.as_ref().unwrap();
|
||||||
let ty= &f.ty;
|
let ty= &f.ty;
|
||||||
|
|
@ -181,4 +163,134 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream {
|
||||||
};
|
};
|
||||||
|
|
||||||
tokens.into()
|
tokens.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn rmc_proto(attr: TokenStream, input: TokenStream) -> TokenStream{
|
||||||
|
let mut proto_num = parse_macro_input!(attr as syn::LitInt);
|
||||||
|
|
||||||
|
let mut input = parse_macro_input!(input as syn::ItemTrait);
|
||||||
|
|
||||||
|
let info_struct_ident = format!("Raw{}Info",input.ident.to_string());
|
||||||
|
let info_struct_ident = Ident::new(&info_struct_ident, input.ident.span());
|
||||||
|
|
||||||
|
let raw_details_struct = syn::ItemStruct{
|
||||||
|
vis: Visibility::Public(Default::default()),
|
||||||
|
struct_token: Default::default(),
|
||||||
|
fields: Fields::Unit,
|
||||||
|
semi_token: Some(Default::default()),
|
||||||
|
ident: info_struct_ident.clone(),
|
||||||
|
attrs: vec![],
|
||||||
|
generics: Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let raw_details_impl_block = syn::ItemImpl{
|
||||||
|
impl_token: Default::default(),
|
||||||
|
generics: Default::default(),
|
||||||
|
attrs: vec![],
|
||||||
|
brace_token: Default::default(),
|
||||||
|
defaultness: None,
|
||||||
|
trait_: None,
|
||||||
|
self_ty: Box::new(Type::Path(TypePath{
|
||||||
|
qself: None,
|
||||||
|
path: Path{
|
||||||
|
segments: {
|
||||||
|
let mut punc = Punctuated::new();
|
||||||
|
punc.push(PathSegment::from(info_struct_ident));
|
||||||
|
punc
|
||||||
|
},
|
||||||
|
leading_colon: None,
|
||||||
|
}
|
||||||
|
})),
|
||||||
|
unsafety: None,
|
||||||
|
items: vec![
|
||||||
|
ImplItem::Const(
|
||||||
|
ImplItemConst{
|
||||||
|
defaultness: None,
|
||||||
|
semi_token: Default::default(),
|
||||||
|
attrs: vec![],
|
||||||
|
generics: Default::default(),
|
||||||
|
ident: Ident::new("PROTOCOL_ID", Span::call_site()),
|
||||||
|
vis: Public(Default::default()),
|
||||||
|
colon_token: Default::default(),
|
||||||
|
const_token: Default::default(),
|
||||||
|
eq_token: Default::default(),
|
||||||
|
expr: Expr::Lit(ExprLit{
|
||||||
|
attrs: vec![],
|
||||||
|
lit: Lit::Int(proto_num),
|
||||||
|
}),
|
||||||
|
ty: Type::Path(TypePath{
|
||||||
|
qself: None,
|
||||||
|
path: Path{
|
||||||
|
segments: {
|
||||||
|
let mut punc = Punctuated::new();
|
||||||
|
punc.push(PathSegment::from(Ident::new("u16", Span::call_site())));
|
||||||
|
punc
|
||||||
|
},
|
||||||
|
leading_colon: None,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
let funcs = input.items.iter().filter_map(|v| if let TraitItem::Fn(v) = v {Some(v)} else { None });
|
||||||
|
|
||||||
|
for func in funcs{
|
||||||
|
if matches!(func.default, Some(_)){
|
||||||
|
return syn::Error::new(func.default.span(), "rmc methods may not have bodies").to_compile_error().into();
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(attr) = func.attrs.iter()
|
||||||
|
.find(|a| a.path().segments.last().is_some_and(|s| s.ident.to_string() == "method_id")) else {
|
||||||
|
let span = func.sig.asyncness.span().join(func.semi_token.unwrap().span()).unwrap_or(func.sig.span());
|
||||||
|
return syn::Error::new(span, "every function inside of an rmc protocol must have a method id").to_compile_error().into();
|
||||||
|
};
|
||||||
|
|
||||||
|
todo!("generate raw impl")
|
||||||
|
}
|
||||||
|
|
||||||
|
quote!{
|
||||||
|
#input
|
||||||
|
#raw_details_struct
|
||||||
|
#raw_details_impl_block
|
||||||
|
}.into()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn method_id(_attr: TokenStream, input: TokenStream) -> TokenStream{
|
||||||
|
// this attribute doesnt do anything by itself, see `rmc_proto`
|
||||||
|
input
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn rmc_struct(attr: TokenStream, input: TokenStream) -> TokenStream{
|
||||||
|
let mut type_data = parse_macro_input!(input as DeriveInput);
|
||||||
|
let mut ident = parse_macro_input!(attr as syn::Path);
|
||||||
|
let last_token = ident.segments.last_mut().expect("empty path?");
|
||||||
|
|
||||||
|
last_token.ident = Ident::new(&("Local".to_owned() + &last_token.ident.to_string()), last_token.span());
|
||||||
|
|
||||||
|
|
||||||
|
let struct_name = &type_data.ident;
|
||||||
|
|
||||||
|
let out = quote!{
|
||||||
|
#type_data
|
||||||
|
|
||||||
|
impl #ident for #struct_name{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::rmc::protocols::RmcCallable for #struct_name{
|
||||||
|
async fn rmc_call(&self, protocol_id: u16, method_id: u32, rest: Vec<u8>){
|
||||||
|
<Self as #ident>::rmc_call(self, protocol_id, method_id, rest).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
out.into()
|
||||||
}
|
}
|
||||||
|
|
@ -1,17 +1,109 @@
|
||||||
use std::sync::Arc;
|
use macros::method_id;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::ops::Add;
|
||||||
|
use std::sync::{Arc, Condvar};
|
||||||
|
use std::time::Duration;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use tokio::sync::Mutex;
|
use chrono::TimeDelta;
|
||||||
use crate::prudp::socket::ExternalConnection;
|
use macros::{rmc_proto, rmc_struct};
|
||||||
|
use paste::paste;
|
||||||
|
use tokio::sync::{Mutex, Notify};
|
||||||
|
use tokio::time::{sleep_until, Instant};
|
||||||
|
use crate::prudp::socket::{ExternalConnection, SendingConnection};
|
||||||
use crate::rmc::structures::connection_data::ConnectionData;
|
use crate::rmc::structures::connection_data::ConnectionData;
|
||||||
|
|
||||||
pub trait RmcCallable{
|
struct RmcConnection(SendingConnection, RmcResponseReceiver);
|
||||||
fn rmc_call(protocol_id: u8, method_id: u8, rest: Vec<u8>);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LocalRmcObjectWrapper<T: RmcCallable>(T);
|
struct RmcResponseReceiver(Notify, Mutex<HashMap<(u16, u32), Vec<u8>>>);
|
||||||
impl<T: RmcCallable> LocalRmcObjectWrapper<T>{
|
|
||||||
pub fn new(object: T, conn: ExternalConnection) -> Self{
|
impl RmcResponseReceiver{
|
||||||
unimplemented!()
|
// returns none if timed out
|
||||||
|
pub async fn get_response_data(&self, proto: u16, method: u32) -> Option<Vec<u8>>{
|
||||||
|
let mut end_wait_time = Instant::now();
|
||||||
|
end_wait_time += Duration::from_secs(5);
|
||||||
|
|
||||||
|
let sleep_fut = sleep_until(end_wait_time);
|
||||||
|
tokio::pin!(sleep_fut);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut locked = self.1.lock().await;
|
||||||
|
|
||||||
|
if let Some(v) = locked.remove(&(proto, method)){
|
||||||
|
return Some(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
let notif_fut = self.0.notified();
|
||||||
|
|
||||||
|
drop(locked);
|
||||||
|
|
||||||
|
tokio::select! {
|
||||||
|
_ = &mut sleep_fut => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
_ = notif_fut => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait RmcCallable{
|
||||||
|
async fn rmc_call(&self, protocol_id: u16, method_id: u32, rest: Vec<u8>);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! define_rmc_proto {
|
||||||
|
(proto $name:ident{
|
||||||
|
$($protocol:path),*
|
||||||
|
}) => {
|
||||||
|
paste!{
|
||||||
|
trait [<Local $name>]: std::any::Any $( + [<Raw $protocol>])* {
|
||||||
|
async fn rmc_call(&self, protocol_id: u16, method_id: u32, rest: Vec<u8>){
|
||||||
|
match protocol_id{
|
||||||
|
$(
|
||||||
|
[<Raw $protocol Info>]::PROTOCOL_ID => <Self as [<Raw $protocol>]>::rmc_call_proto(self, method_id, rest).await,
|
||||||
|
)*
|
||||||
|
v => log::error!("invalid protocol called on rmc object {}", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
trait RawNotif{
|
||||||
|
async fn rmc_call_proto(&self, method_id: u32, rest: Vec<u8>){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RawNotifInfo;
|
||||||
|
impl RawNotifInfo{
|
||||||
|
const PROTOCOL_ID: u16 = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rmc_proto(1)]
|
||||||
|
pub trait Another{
|
||||||
|
#[method_id(1)]
|
||||||
|
async fn test();
|
||||||
|
}
|
||||||
|
|
||||||
|
define_rmc_proto!{
|
||||||
|
proto TestProto{
|
||||||
|
Notif,
|
||||||
|
Another
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[rmc_struct(TestProto)]
|
||||||
|
struct TestProtoImplementor{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawNotif for TestProtoImplementor{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue