From 2b30f83a2161fc10713f58d8128d42d71c51d50b Mon Sep 17 00:00:00 2001
From: Georgy Moshkin <gmoshkin@picodata.io>
Date: Fri, 17 Jun 2022 13:35:54 +0300
Subject: [PATCH] refactor: stringify_cfunc macro now accepts full path to
 function

---
 src/main.rs      | 17 +++++------------
 src/tarantool.rs | 24 +++++++++++++++++-------
 2 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 583fa1b084..8194c8c413 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -128,14 +128,9 @@ fn init_handlers() {
         "#,
     );
 
-    use discovery::proc_discover;
-    declare_cfunc!(proc_discover);
-
-    use traft::node::raft_interact;
-    declare_cfunc!(raft_interact);
-
-    use traft::node::raft_join;
-    declare_cfunc!(raft_join);
+    declare_cfunc!(discovery::proc_discover);
+    declare_cfunc!(traft::node::raft_interact);
+    declare_cfunc!(traft::node::raft_join);
 }
 
 fn rm_tarantool_files(data_dir: &str) {
@@ -485,8 +480,7 @@ fn start_join(args: &args::Run, leader_address: String) {
         advertise_address: args.advertise_address(),
     };
 
-    use traft::node::raft_join;
-    let fn_name = stringify_cfunc!(raft_join);
+    let fn_name = stringify_cfunc!(traft::node::raft_join);
     let resp: traft::JoinResponse = tarantool::net_box_call_retry(&leader_address, fn_name, &req);
 
     picolib_setup(args);
@@ -608,8 +602,7 @@ fn postjoin(args: &args::Run) {
         let leader_id = node.status().leader_id.expect("leader_id deinitialized");
         let leader = traft::Storage::peer_by_raft_id(leader_id).unwrap().unwrap();
 
-        use traft::node::raft_join;
-        let fn_name = stringify_cfunc!(raft_join);
+        let fn_name = stringify_cfunc!(traft::node::raft_join);
         let now = Instant::now();
         match tarantool::net_box_call(&leader.peer_address, fn_name, &req, timeout) {
             Err(e) => {
diff --git a/src/tarantool.rs b/src/tarantool.rs
index e6f9df7366..53801e2539 100644
--- a/src/tarantool.rs
+++ b/src/tarantool.rs
@@ -8,21 +8,31 @@ use ::tarantool::net_box;
 use ::tarantool::tlua::{self, LuaFunction, LuaTable};
 use ::tarantool::tuple::AsTuple;
 
+#[macro_export]
+macro_rules! stringify_last_token {
+    ($tail:tt) => { std::stringify!($tail) };
+    ($head:tt $($tail:tt)+) => { $crate::stringify_last_token!($($tail)+) };
+}
+
+/// Checks that the given function exists and returns it's name suitable for
+/// calling it via tarantool rpc.
+///
+/// The argument can be a full path to the function.
 #[macro_export]
 macro_rules! stringify_cfunc {
-    ( $func_name:expr ) => {{
+    ( $($func_name:tt)+ ) => {{
         use ::tarantool::tuple::FunctionArgs;
         use ::tarantool::tuple::FunctionCtx;
         use libc::c_int;
 
-        let _: unsafe extern "C" fn(FunctionCtx, FunctionArgs) -> c_int = $func_name;
-        concat!(".", stringify!($func_name))
+        let _: unsafe extern "C" fn(FunctionCtx, FunctionArgs) -> c_int = $($func_name)+;
+        concat!(".", $crate::stringify_last_token!($($func_name)+))
     }};
 }
 
 #[macro_export]
 macro_rules! declare_cfunc {
-    ( $func_name:expr ) => {{
+    ( $($func_name:tt)+ ) => {{
         use ::tarantool::tuple::FunctionArgs;
         use ::tarantool::tuple::FunctionCtx;
         use libc::c_int;
@@ -32,10 +42,10 @@ macro_rules! declare_cfunc {
         // and we may get this error: dlsym(RTLD_DEFAULT, some_fn): symbol not found
         fn used(_: unsafe extern "C" fn(FunctionCtx, FunctionArgs) -> c_int) {}
 
-        used($func_name);
-        crate::tarantool::eval(concat!(
+        used($($func_name)+);
+        $crate::tarantool::eval(concat!(
             "box.schema.func.create('.",
-            stringify!($func_name),
+            $crate::stringify_last_token!($($func_name)+),
             "', {
                 language = 'C',
                 if_not_exists = true
-- 
GitLab