#[macro_export]
macro_rules! info_table_start {
() => {
unsafe { $crate::ffi::php_info_print_table_start() };
};
}
#[macro_export]
macro_rules! info_table_end {
() => {
unsafe { $crate::ffi::php_info_print_table_end() }
};
}
#[macro_export]
macro_rules! info_table_header {
($($element:expr),*) => {$crate::_info_table_row!(php_info_print_table_header, $($element),*)};
}
#[macro_export]
macro_rules! info_table_row {
($($element:expr),*) => {$crate::_info_table_row!(php_info_print_table_row, $($element),*)};
}
#[doc(hidden)]
#[macro_export]
macro_rules! _info_table_row {
($fn: ident, $($element: expr),*) => {
unsafe {
$crate::ffi::$fn($crate::_info_table_row!(@COUNT; $($element),*) as i32, $(::std::ffi::CString::new($element).unwrap().as_ptr()),*);
}
};
(@COUNT; $($element: expr),*) => {
<[()]>::len(&[$($crate::_info_table_row![@SUBST; $element]),*])
};
(@SUBST; $_: expr) => { () };
}
#[macro_export]
macro_rules! call_user_func {
($fn: expr) => {
$fn.try_call(vec![])
};
($fn: expr, $($param: expr),*) => {
$fn.try_call(vec![$(&$param),*])
};
}
#[macro_export]
macro_rules! parse_args {
($ed: expr, $($arg: expr),*) => {{
let parser = $ed.parser()
$(.arg(&mut $arg))*
.parse();
if parser.is_err() {
return;
}
}};
($ed: expr, $($arg: expr),* ; $($opt: expr),*) => {{
let parser = $ed.parser()
$(.arg(&mut $arg))*
.not_required()
$(.arg(&mut $opt))*
.parse();
if parser.is_err() {
return;
}
}};
}
#[macro_export]
macro_rules! throw {
($ex: expr, $reason: expr) => {
$crate::exception::throw($ex, $reason);
return;
};
}
#[macro_export]
macro_rules! class_derives {
($type: ty) => {
impl<'a> $crate::convert::FromZendObject<'a> for &'a $type {
#[inline]
fn from_zend_object(obj: &'a $crate::types::ZendObject) -> $crate::error::Result<Self> {
let obj = $crate::types::ZendClassObject::<$type>::from_zend_obj(obj)
.ok_or($crate::error::Error::InvalidScope)?;
Ok(&**obj)
}
}
impl<'a> $crate::convert::FromZendObjectMut<'a> for &'a mut $type {
#[inline]
fn from_zend_object_mut(
obj: &'a mut $crate::types::ZendObject,
) -> $crate::error::Result<Self> {
let obj = $crate::types::ZendClassObject::<$type>::from_zend_obj_mut(obj)
.ok_or($crate::error::Error::InvalidScope)?;
Ok(&mut **obj)
}
}
impl<'a> $crate::convert::FromZval<'a> for &'a $type {
const TYPE: $crate::flags::DataType = $crate::flags::DataType::Object(Some(
<$type as $crate::class::RegisteredClass>::CLASS_NAME,
));
#[inline]
fn from_zval(zval: &'a $crate::types::Zval) -> ::std::option::Option<Self> {
<Self as $crate::convert::FromZendObject>::from_zend_object(zval.object()?).ok()
}
}
impl<'a> $crate::convert::FromZvalMut<'a> for &'a mut $type {
const TYPE: $crate::flags::DataType = $crate::flags::DataType::Object(Some(
<$type as $crate::class::RegisteredClass>::CLASS_NAME,
));
#[inline]
fn from_zval_mut(zval: &'a mut $crate::types::Zval) -> ::std::option::Option<Self> {
<Self as $crate::convert::FromZendObjectMut>::from_zend_object_mut(
zval.object_mut()?,
)
.ok()
}
}
impl $crate::convert::IntoZendObject for $type {
#[inline]
fn into_zend_object(
self,
) -> $crate::error::Result<$crate::boxed::ZBox<$crate::types::ZendObject>> {
Ok($crate::types::ZendClassObject::new(self).into())
}
}
impl $crate::convert::IntoZval for $type {
const TYPE: $crate::flags::DataType = $crate::flags::DataType::Object(Some(
<$type as $crate::class::RegisteredClass>::CLASS_NAME,
));
#[inline]
fn set_zval(
self,
zv: &mut $crate::types::Zval,
persistent: bool,
) -> $crate::error::Result<()> {
use $crate::convert::IntoZendObject;
self.into_zend_object()?.set_zval(zv, persistent)
}
}
};
}
macro_rules! into_zval {
($type: ty, $fn: ident, $dt: ident) => {
impl From<$type> for $crate::types::Zval {
fn from(val: $type) -> Self {
let mut zv = Self::new();
zv.$fn(val);
zv
}
}
impl $crate::convert::IntoZval for $type {
const TYPE: $crate::flags::DataType = $crate::flags::DataType::$dt;
fn set_zval(self, zv: &mut $crate::types::Zval, _: bool) -> $crate::error::Result<()> {
zv.$fn(self);
Ok(())
}
}
};
}
macro_rules! try_from_zval {
($type: ty, $fn: ident, $dt: ident) => {
impl $crate::convert::FromZval<'_> for $type {
const TYPE: $crate::flags::DataType = $crate::flags::DataType::$dt;
fn from_zval(zval: &$crate::types::Zval) -> ::std::option::Option<Self> {
use ::std::convert::TryInto;
zval.$fn().and_then(|val| val.try_into().ok())
}
}
impl ::std::convert::TryFrom<$crate::types::Zval> for $type {
type Error = $crate::error::Error;
fn try_from(value: $crate::types::Zval) -> $crate::error::Result<Self> {
<Self as $crate::convert::FromZval>::from_zval(&value)
.ok_or($crate::error::Error::ZvalConversion(value.get_type()))
}
}
};
}
#[macro_export]
macro_rules! php_print {
($arg: tt) => {{
$crate::zend::printf($arg).expect("Failed to print to PHP stdout");
}};
($($arg: tt) *) => {{
let args = format!($($arg)*);
$crate::zend::printf(args.as_str()).expect("Failed to print to PHP stdout");
}};
}
#[macro_export]
macro_rules! php_println {
() => {
$crate::php_print!("\n");
};
($fmt: tt) => {
$crate::php_print!(concat!($fmt, "\n"));
};
($fmt: tt, $($arg: tt) *) => {
$crate::php_print!(concat!($fmt, "\n"), $($arg)*);
};
}
pub(crate) use into_zval;
pub(crate) use try_from_zval;