Skip to content

Commit

Permalink
Endpoint macro that auto add functions
Browse files Browse the repository at this point in the history
IT IS NOT DONE YET.

The macro needs to add the generated code to the implementation.
  • Loading branch information
Murmeldyret committed Dec 7, 2023
1 parent f84ebf0 commit 68bb3d9
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 5 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ regex = "1.10.2"
mockall = "0.11.4"
bcrypt = "0.15.0"
serde_json = "1.0.108"
ecdar_api_macros = { version = "0.1.0", path = "ecdar_api_macros" }

[build-dependencies]
tonic-build = "0.10.2"
Expand Down
14 changes: 14 additions & 0 deletions ecdar_api_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "ecdar_api_macros"
version = "0.1.0"
edition = "2021"

[lib]
proc-macro = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
syn = { version = "2.0", features = ["full"] }
quote = "1.0"
# proc-macro2 = "1.0.70"
114 changes: 114 additions & 0 deletions ecdar_api_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, ImplItemFn, Item, ItemFn, ItemImpl, ItemMod};

Check warning on line 3 in ecdar_api_macros/src/lib.rs

View workflow job for this annotation

GitHub Actions / Clippy lint and check

unused imports: `ImplItemFn`, `ItemFn`

warning: unused imports: `ImplItemFn`, `ItemFn` --> ecdar_api_macros/src/lib.rs:3:30 | 3 | use syn::{parse_macro_input, ImplItemFn, Item, ItemFn, ItemImpl, ItemMod}; | ^^^^^^^^^^ ^^^^^^ | = note: `#[warn(unused_imports)]` on by default

#[proc_macro_attribute]
pub fn endpoints(_attr: TokenStream, item: TokenStream) -> TokenStream {
let item_mod: ItemMod = parse_macro_input!(item as ItemMod);

let impl_names: Vec<String> = item_mod
.clone()
.content
.as_ref()
.map(|(_, items)| {
items.iter().filter_map(|item| {
if let syn::Item::Impl(impl_item) = item {
Some(
impl_item
.trait_
.as_ref()
.map_or_else(
|| None,
|t| Some(t.1.segments.last().unwrap().ident.to_string()),
)
.unwrap_or_else(|| "".to_string()),
)
} else {
None
}
})
})
.unwrap()
.collect();

let names: Vec<String> = impl_names
.clone()
.into_iter()
.filter(|item| !item.is_empty())
.collect();

let mut endpoints: Vec<String> = Vec::new();

let items_impl: Vec<Item> = item_mod.content.unwrap().1;

let items_impl: Vec<ItemImpl> = items_impl
.into_iter()
.filter_map(|item| match item {
Item::Impl(item_impl) => Some(item_impl),
_ => None,
})
.collect();

let items_impl: Vec<ItemImpl> = items_impl
.clone()
.into_iter()
.filter(|item| item.trait_.is_some())
.collect();

for i in 0..items_impl.len() {
let existing_functions: Vec<String> = items_impl[i]
.items
.iter()
.filter_map(|item| match item {
syn::ImplItem::Fn(function) => Some(function.sig.ident.to_string()),
_ => None,
})
.collect();

for function in existing_functions {
endpoints.push(format!("{}/{}", names[i], function));
}
}

let new_function: TokenStream = quote! {
async fn endpoints(&self, request: tonic::Request<()>) -> std::result::Result<tonic::Response<EndpointsResponse>, tonic::Status> {
let names = vec![#(#endpoints.to_string()),*];
Ok(Response::new(EndpointsResponse {
endpoints: names
}))
}
}
.into();

println!("{}", new_function.to_string());

// let mut updated_items = item_mod.content.as_ref()

// let mut updated_items = input.items.clone();

// updated_items.push(syn::ImplItem::Fn(parse_macro_input!(
// new_function as ImplItemFn
// )));

// let updated_impl = ItemImpl {
// attrs: input.attrs,
// defaultness: input.defaultness,
// unsafety: input.unsafety,
// impl_token: input.impl_token,
// generics: input.generics,
// trait_: input.trait_,
// self_ty: input.self_ty,
// brace_token: input.brace_token,
// items: updated_items,
// };

// let output = quote! {
// #updated_impl
// };

// println!("{}", output.to_string());

// output.into()

Check warning on line 111 in ecdar_api_macros/src/lib.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/Ecdar-API/Ecdar-API/ecdar_api_macros/src/lib.rs
todo!()
}

14 changes: 9 additions & 5 deletions src/api/ecdar_api.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
#![ecdar_api_macros::endpoints]

Check failure on line 1 in src/api/ecdar_api.rs

View workflow job for this annotation

GitHub Actions / Clippy lint and check

inner macro attributes are unstable

error[E0658]: inner macro attributes are unstable --> src/api/ecdar_api.rs:1:4 | 1 | #![ecdar_api_macros::endpoints] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information

Check failure on line 1 in src/api/ecdar_api.rs

View workflow job for this annotation

GitHub Actions / Clippy lint and check

inner macro attributes are unstable

error[E0658]: inner macro attributes are unstable --> src/api/ecdar_api.rs:1:4 | 1 | #![ecdar_api_macros::endpoints] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
#![feature(custom_inner_attributes)]

use super::server::server::{
ecdar_api_auth_server::EcdarApiAuth,
ecdar_api_server::EcdarApi,
ecdar_backend_server::EcdarBackend,
get_auth_token_request::{user_credentials, UserCredentials},
CreateAccessRequest, CreateProjectRequest, CreateProjectResponse, CreateQueryRequest,
CreateUserRequest, DeleteAccessRequest, DeleteProjectRequest, DeleteQueryRequest,
GetAuthTokenRequest, GetAuthTokenResponse, GetProjectRequest, GetProjectResponse,
ListProjectsInfoResponse, Query, QueryRequest, QueryResponse, SendQueryRequest,
SendQueryResponse, SimulationStartRequest, SimulationStepRequest, SimulationStepResponse,
UpdateAccessRequest, UpdateProjectRequest, UpdateQueryRequest, UpdateUserRequest,
UserTokenResponse,
EndpointsResponse, GetAuthTokenRequest, GetAuthTokenResponse, GetProjectRequest,
GetProjectResponse, ListProjectsInfoResponse, Query, QueryRequest, QueryResponse,
SendQueryRequest, SendQueryResponse, SimulationStartRequest, SimulationStepRequest,
SimulationStepResponse, UpdateAccessRequest, UpdateProjectRequest, UpdateQueryRequest,
UpdateUserRequest, UserTokenResponse,
};
use crate::api::context_collection::ContextCollection;
use crate::api::{
Expand Down Expand Up @@ -1050,3 +1053,4 @@ mod user_logic_tests;
#[cfg(test)]

Check warning on line 1053 in src/api/ecdar_api.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/Ecdar-API/Ecdar-API/src/api/ecdar_api.rs
#[path = "../tests/api/session_logic.rs"]
mod session_logic_tests;

Check failure on line 1055 in src/api/ecdar_api.rs

View workflow job for this annotation

GitHub Actions / Clippy lint and check

non-inline modules in proc macro input are unstable

error[E0658]: non-inline modules in proc macro input are unstable --> src/api/ecdar_api.rs:1055:1 | 1055 | mod session_logic_tests; | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #54727 <https://github.com/rust-lang/rust/issues/54727> for more information

1 change: 1 addition & 0 deletions src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ pub mod ecdar_api;
pub mod hashing_context;

Check warning on line 4 in src/api/mod.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/Ecdar-API/Ecdar-API/src/api/mod.rs
pub mod reveaal_context;
pub mod server;

0 comments on commit 68bb3d9

Please sign in to comment.