1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
#![warn(rust_2018_idioms, clippy::dbg_macro, clippy::print_stdout)] /*! The proc-macros for [phper](https://crates.io/crates/phper). ## License [Unlicense](https://github.com/jmjoy/phper/blob/master/LICENSE). */ // TODO Write a bridge macro for easy usage about register functions and classes, like `cxx`. mod alloc; mod derives; mod inner; mod log; mod utils; use proc_macro::TokenStream; use syn::{parse_macro_input, DeriveInput}; /// C style string end with '\0'. /// /// # Examples /// /// ```no_test /// use std::ffi::CStr; /// /// assert_eq!(c_str!("foo"), unsafe { /// CStr::from_ptr("foo\0".as_ptr().cast()) /// }); /// ``` #[proc_macro] pub fn c_str(input: TokenStream) -> TokenStream { utils::c_str(input) } /// C style string end with '\0'. /// /// # Examples /// /// ```no_test /// assert_eq!(c_str_ptr!("foo"), "foo\0".as_ptr().cast()); /// ``` #[proc_macro] pub fn c_str_ptr(input: TokenStream) -> TokenStream { utils::c_str_ptr(input) } /// PHP module entry, wrap the `phper::modules::Module` write operation. /// /// # Examples /// /// ```no_test /// use phper::{php_get_module, modules::Module}; /// /// #[php_get_module] /// pub fn get_module() -> Module { /// let mut module = Module::new( /// env!("CARGO_PKG_NAME"), /// env!("CARGO_PKG_VERSION"), /// env!("CARGO_PKG_AUTHORS"), /// ); /// /// // ... /// /// module /// } /// /// ``` #[proc_macro_attribute] pub fn php_get_module(attr: TokenStream, input: TokenStream) -> TokenStream { inner::php_get_module(attr, input) } /// Auto derive for `phper::errors::Throwable`. /// /// # Examples /// /// ```no_test /// #[derive(thiserror::Error, crate::Throwable, Debug)] /// #[throwable(class = "Exception")] /// pub enum Error { /// #[error(transparent)] /// Io(#[from] std::io::Error), /// /// #[error(transparent)] /// #[throwable(transparent)] /// My(#[from] MyError), /// } /// ``` /// /// TODO Support attribute `throwable` with `code` and `message`, integration tests. #[proc_macro_derive(Throwable, attributes(throwable, throwable_class, throwable_crate))] pub fn derive_throwable(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); derives::derive_throwable(input).unwrap_or_else(|e| e.into_compile_error().into()) }