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 99 100 101 102 103
// Copyright (c) 2022 PHPER Framework Team
// PHPER is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan
// PSL v2. You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
#![warn(rust_2018_idioms, clippy::dbg_macro, clippy::print_stdout)]
#![doc = include_str!("../README.md")]
// TODO Write a bridge macro for easy usage about register functions and
// classes, like `cxx`.
mod alloc;
mod derives;
mod globals;
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, phper::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 `class`, `code` and `message`,
/// integration tests.
#[proc_macro_derive(Throwable, attributes(throwable, throwable_class))]
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())
}