Attribute Macro tcl::proc

source ·
#[proc]
Expand description

A proc macro attribute for filling the gap between ObjCmdProc functions and Rust functions with “normal” input arguments.

§Purpose

Generally, a Tcl command’s function signature is extern "C" fn( tcl::reexport_clib::ClientData, *mut tcl::reexport_clib::Tcl_Interp, c_int, *const *mut tcl::reexport_clib::Tcl_Obj ) -> c_int, aka ObjCmdProc. Arguments are stored in an array of tcl::reexport_clib::Tcl_Obj, and must be converted to real types before using them, which is boring.

With the help of the #[proc] attribute, The translation of function signatures and conversions of arguments are generated behind the proc macros.

This attributes will generate code to catch panics and abort the program to avoid undefined behaviour caused by panic across FFI boundary.

§Constraints

Two category of parameters are allowed:

  • Owned value

    Implementation detail: using std::convert::TryFrom to obtain the argument.

  • Borrowed value

    Implementation detail: borrowing from Tcl<T> to obtain the argument which borrows T.

The returning type is preferred but not mandatory a Result<T,E>:

  • The Ok value will be converted to a Tcl Obj which is the result for the interpreter.

  • The Err value must be able to be converted from the following errors: InterpError, DeError, NullDataPtr.

    If all the errors are from this crate, you can simply use -> TclResult<T>.

    If all the errors implement std::error::Error, you can simply use -> Result<T, Box<dyn std::error::Error>>.

    Otherwise you can use checked exceptions: #[cex] fn your_command( /* args omitted */ ) -> Result!( T throws InterpError, DeError, NullDataPtr, YourErrors ).