mirror of
https://github.com/icewind1991/ivory.git
synced 2026-06-03 18:54:07 +02:00
split off phpval code
This commit is contained in:
parent
736b800ae0
commit
aecef495de
5 changed files with 165 additions and 161 deletions
|
|
@ -90,7 +90,7 @@ fn export_fn(item: ItemFn) -> TokenStream {
|
|||
#(#arg_cast);*
|
||||
let result = #body;
|
||||
|
||||
let php_val = ::ivory::zend::PhpVal::from(result);
|
||||
let php_val = ::ivory::PhpVal::from(result);
|
||||
let zval = ::ivory::zend::ZVal::from(php_val);
|
||||
unsafe {
|
||||
*retval = zval
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ pub mod error;
|
|||
|
||||
pub mod externs;
|
||||
pub mod info;
|
||||
mod phpval;
|
||||
pub mod zend;
|
||||
pub use crate::error::{ArgError, CastError};
|
||||
pub use crate::zend::{ArrayKey, PhpVal};
|
||||
pub use crate::phpval::{ArrayKey, PhpVal};
|
||||
pub use ivory_macro::{ivory_export, ivory_module};
|
||||
|
|
|
|||
160
ivory/src/phpval.rs
Normal file
160
ivory/src/phpval.rs
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
use std::collections::HashMap;
|
||||
use std::hash::Hash;
|
||||
|
||||
use crate::zend::ZValType;
|
||||
use crate::CastError;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum ArrayKey {
|
||||
String(String),
|
||||
Int(u64),
|
||||
}
|
||||
|
||||
macro_rules! impl_from_array_key {
|
||||
($type:ty, $variant:ident, $type2:ty) => {
|
||||
impl From<$type> for ArrayKey {
|
||||
fn from(input: $type) -> Self {
|
||||
ArrayKey::$variant(input as $type2)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_from_array_key!(String, String, String);
|
||||
impl_from_array_key!(u64, Int, u64);
|
||||
impl_from_array_key!(u32, Int, u64);
|
||||
impl_from_array_key!(u16, Int, u64);
|
||||
impl_from_array_key!(u8, Int, u64);
|
||||
impl_from_array_key!(usize, Int, u64);
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum PhpVal {
|
||||
Undef,
|
||||
Null,
|
||||
Bool(bool),
|
||||
Long(i64),
|
||||
Double(f64),
|
||||
String(String),
|
||||
Array(Vec<(ArrayKey, PhpVal)>),
|
||||
Object(HashMap<String, PhpVal>),
|
||||
Resource(u64),
|
||||
Reference(),
|
||||
}
|
||||
|
||||
impl PhpVal {
|
||||
pub fn get_type(&self) -> ZValType {
|
||||
match self {
|
||||
PhpVal::Undef => ZValType::Undef,
|
||||
PhpVal::Null => ZValType::Null,
|
||||
PhpVal::Bool(true) => ZValType::True,
|
||||
PhpVal::Bool(false) => ZValType::False,
|
||||
PhpVal::Long(_) => ZValType::Long,
|
||||
PhpVal::Double(_) => ZValType::Double,
|
||||
PhpVal::String(_) => ZValType::String,
|
||||
PhpVal::Array(_) => ZValType::Array,
|
||||
PhpVal::Object(_) => ZValType::Object,
|
||||
PhpVal::Resource(_) => ZValType::Resource,
|
||||
PhpVal::Reference() => ZValType::Reference,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PhpVal {
|
||||
fn default() -> Self {
|
||||
PhpVal::Undef
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PhpVal> for Result<PhpVal, CastError> {
|
||||
fn from(val: PhpVal) -> Self {
|
||||
Ok(val)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_from_phpval {
|
||||
($type:ty, $variant:ident) => {
|
||||
// non nullable version
|
||||
impl From<PhpVal> for Result<$type, CastError> {
|
||||
fn from(val: PhpVal) -> Self {
|
||||
match val {
|
||||
PhpVal::$variant(val) => Ok(val),
|
||||
_ => Err(CastError {
|
||||
actual: val.get_type(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nullable version
|
||||
impl From<PhpVal> for Result<Option<$type>, CastError> {
|
||||
fn from(val: PhpVal) -> Self {
|
||||
match val {
|
||||
PhpVal::Null => Ok(None),
|
||||
PhpVal::Undef => Ok(None),
|
||||
PhpVal::$variant(val) => Ok(Some(val)),
|
||||
_ => Err(CastError {
|
||||
actual: val.get_type(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$type> for PhpVal {
|
||||
fn from(input: $type) -> Self {
|
||||
PhpVal::$variant(input)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_from_phpval!(i64, Long);
|
||||
impl_from_phpval!(f64, Double);
|
||||
impl_from_phpval!(bool, Bool);
|
||||
impl_from_phpval!(String, String);
|
||||
|
||||
impl From<()> for PhpVal {
|
||||
fn from(_input: ()) -> Self {
|
||||
PhpVal::Null
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<PhpVal>> From<Option<T>> for PhpVal {
|
||||
fn from(input: Option<T>) -> Self {
|
||||
match input {
|
||||
Some(inner) => inner.into(),
|
||||
None => PhpVal::Null,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<PhpVal>> From<Vec<T>> for PhpVal {
|
||||
fn from(input: Vec<T>) -> Self {
|
||||
PhpVal::Array(
|
||||
input
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(key, value)| (key.into(), value.into()))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Into<ArrayKey>, T: Into<PhpVal>> From<Vec<(K, T)>> for PhpVal {
|
||||
fn from(input: Vec<(K, T)>) -> Self {
|
||||
PhpVal::Array(
|
||||
input
|
||||
.into_iter()
|
||||
.map(|(key, value)| (key.into(), value.into()))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Into<ArrayKey> + Hash + Eq + Ord, T: Into<PhpVal>> From<HashMap<K, T>> for PhpVal {
|
||||
fn from(input: HashMap<K, T>) -> Self {
|
||||
let mut vec: Vec<(K, T)> = input.into_iter().collect();
|
||||
// since hashmap doesn't contain any stable order we sort it to get predictable results
|
||||
vec.sort_unstable_by(|(a, _), (b, _)| a.cmp(b));
|
||||
vec.into()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
pub use self::function::*;
|
||||
pub use self::module::*;
|
||||
pub use self::zval::{ArrayKey, ExecuteData, PhpVal, ZVal, ZValType};
|
||||
pub use self::zval::{ExecuteData, ZVal, ZValType};
|
||||
|
||||
mod function;
|
||||
mod module;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::fmt::Display;
|
||||
use std::hash::Hash;
|
||||
use std::intrinsics::transmute;
|
||||
use std::mem::{forget, size_of};
|
||||
use std::str;
|
||||
|
||||
use ivory_sys::*;
|
||||
|
||||
use crate::CastError;
|
||||
use crate::{ArrayKey, PhpVal};
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct ExecuteData(zend_execute_data);
|
||||
|
|
@ -204,161 +202,6 @@ impl From<u8> for ZValType {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum ArrayKey {
|
||||
String(String),
|
||||
Int(u64),
|
||||
}
|
||||
|
||||
macro_rules! impl_from_array_key {
|
||||
($type:ty, $variant:ident, $type2:ty) => {
|
||||
impl From<$type> for ArrayKey {
|
||||
fn from(input: $type) -> Self {
|
||||
ArrayKey::$variant(input as $type2)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_from_array_key!(String, String, String);
|
||||
impl_from_array_key!(u64, Int, u64);
|
||||
impl_from_array_key!(u32, Int, u64);
|
||||
impl_from_array_key!(u16, Int, u64);
|
||||
impl_from_array_key!(u8, Int, u64);
|
||||
impl_from_array_key!(usize, Int, u64);
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum PhpVal {
|
||||
Undef,
|
||||
Null,
|
||||
Bool(bool),
|
||||
Long(i64),
|
||||
Double(f64),
|
||||
String(String),
|
||||
Array(Vec<(ArrayKey, PhpVal)>),
|
||||
Object(HashMap<String, PhpVal>),
|
||||
Resource(u64),
|
||||
Reference(),
|
||||
}
|
||||
|
||||
impl PhpVal {
|
||||
pub fn get_type(&self) -> ZValType {
|
||||
match self {
|
||||
PhpVal::Undef => ZValType::Undef,
|
||||
PhpVal::Null => ZValType::Null,
|
||||
PhpVal::Bool(true) => ZValType::True,
|
||||
PhpVal::Bool(false) => ZValType::False,
|
||||
PhpVal::Long(_) => ZValType::Long,
|
||||
PhpVal::Double(_) => ZValType::Double,
|
||||
PhpVal::String(_) => ZValType::String,
|
||||
PhpVal::Array(_) => ZValType::Array,
|
||||
PhpVal::Object(_) => ZValType::Object,
|
||||
PhpVal::Resource(_) => ZValType::Resource,
|
||||
PhpVal::Reference() => ZValType::Reference,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PhpVal {
|
||||
fn default() -> Self {
|
||||
PhpVal::Undef
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PhpVal> for Result<PhpVal, CastError> {
|
||||
fn from(val: PhpVal) -> Self {
|
||||
Ok(val)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_from_phpval {
|
||||
($type:ty, $variant:ident) => {
|
||||
// non nullable version
|
||||
impl From<PhpVal> for Result<$type, CastError> {
|
||||
fn from(val: PhpVal) -> Self {
|
||||
match val {
|
||||
PhpVal::$variant(val) => Ok(val),
|
||||
_ => Err(CastError {
|
||||
actual: val.get_type(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nullable version
|
||||
impl From<PhpVal> for Result<Option<$type>, CastError> {
|
||||
fn from(val: PhpVal) -> Self {
|
||||
match val {
|
||||
PhpVal::Null => Ok(None),
|
||||
PhpVal::Undef => Ok(None),
|
||||
PhpVal::$variant(val) => Ok(Some(val)),
|
||||
_ => Err(CastError {
|
||||
actual: val.get_type(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$type> for PhpVal {
|
||||
fn from(input: $type) -> Self {
|
||||
PhpVal::$variant(input)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_from_phpval!(i64, Long);
|
||||
impl_from_phpval!(f64, Double);
|
||||
impl_from_phpval!(bool, Bool);
|
||||
impl_from_phpval!(String, String);
|
||||
|
||||
impl From<()> for PhpVal {
|
||||
fn from(_input: ()) -> Self {
|
||||
PhpVal::Null
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<PhpVal>> From<Option<T>> for PhpVal {
|
||||
fn from(input: Option<T>) -> Self {
|
||||
match input {
|
||||
Some(inner) => inner.into(),
|
||||
None => PhpVal::Null,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<PhpVal>> From<Vec<T>> for PhpVal {
|
||||
fn from(input: Vec<T>) -> Self {
|
||||
PhpVal::Array(
|
||||
input
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(key, value)| (key.into(), value.into()))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Into<ArrayKey>, T: Into<PhpVal>> From<Vec<(K, T)>> for PhpVal {
|
||||
fn from(input: Vec<(K, T)>) -> Self {
|
||||
PhpVal::Array(
|
||||
input
|
||||
.into_iter()
|
||||
.map(|(key, value)| (key.into(), value.into()))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Into<ArrayKey> + Hash + Eq + Ord, T: Into<PhpVal>> From<HashMap<K, T>> for PhpVal {
|
||||
fn from(input: HashMap<K, T>) -> Self {
|
||||
let mut vec: Vec<(K, T)> = input.into_iter().collect();
|
||||
// since hashmap doesn't contain any stable order we sort it to get predictable results
|
||||
vec.sort_unstable_by(|(a, _), (b, _)| a.cmp(b));
|
||||
vec.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ZValType> for _zval_struct__bindgen_ty_1 {
|
||||
fn from(ty: ZValType) -> Self {
|
||||
_zval_struct__bindgen_ty_1 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue