From 0a13a13389f4042947e49601d763d38186142536 Mon Sep 17 00:00:00 2001 From: ijl Date: Mon, 18 Sep 2023 22:14:27 +0000 Subject: [PATCH] serialize::per_type, ffi::yyjson and other reorganization --- script/generate-yyjson | 2 +- src/deserialize/utf8.rs | 2 +- src/deserialize/yyjson.rs | 2 +- src/error.rs | 3 - src/ffi/mod.rs | 2 + src/{ => ffi}/yyjson.rs | 0 src/lib.rs | 4 - src/serialize/error.rs | 3 +- src/serialize/json.rs | 23 +-- src/serialize/mod.rs | 16 +- src/serialize/{ => per_type}/dataclass.rs | 0 src/serialize/{ => per_type}/datetime.rs | 4 +- src/serialize/{ => per_type}/datetimelike.rs | 0 src/serialize/{ => per_type}/default.rs | 0 src/serialize/{ => per_type}/dict.rs | 10 +- src/serialize/{ => per_type}/float.rs | 0 src/serialize/{ => per_type}/fragment.rs | 0 src/serialize/{ => per_type}/int.rs | 0 src/serialize/{ => per_type}/list.rs | 2 +- src/serialize/per_type/mod.rs | 35 ++++ src/serialize/per_type/none.rs | 21 +++ src/serialize/{ => per_type}/numpy.rs | 7 +- src/serialize/per_type/pybool.rs | 24 +++ src/serialize/{ => per_type}/pyenum.rs | 0 src/serialize/{ => per_type}/tuple.rs | 0 src/serialize/{str.rs => per_type/unicode.rs} | 0 src/serialize/{ => per_type}/uuid.rs | 0 src/serialize/serializer.rs | 152 +++++++----------- src/typeref.rs | 6 +- src/util.rs | 26 +++ 30 files changed, 192 insertions(+), 152 deletions(-) delete mode 100644 src/error.rs rename src/{ => ffi}/yyjson.rs (100%) rename src/serialize/{ => per_type}/dataclass.rs (100%) rename src/serialize/{ => per_type}/datetime.rs (98%) rename src/serialize/{ => per_type}/datetimelike.rs (100%) rename src/serialize/{ => per_type}/default.rs (100%) rename src/serialize/{ => per_type}/dict.rs (98%) rename src/serialize/{ => per_type}/float.rs (100%) rename src/serialize/{ => per_type}/fragment.rs (100%) rename src/serialize/{ => per_type}/int.rs (100%) rename src/serialize/{ => per_type}/list.rs (95%) create mode 100644 src/serialize/per_type/mod.rs create mode 100644 src/serialize/per_type/none.rs rename src/serialize/{ => per_type}/numpy.rs (99%) create mode 100644 src/serialize/per_type/pybool.rs rename src/serialize/{ => per_type}/pyenum.rs (100%) rename src/serialize/{ => per_type}/tuple.rs (100%) rename src/serialize/{str.rs => per_type/unicode.rs} (100%) rename src/serialize/{ => per_type}/uuid.rs (100%) diff --git a/script/generate-yyjson b/script/generate-yyjson index 793ad220..826c4a89 100755 --- a/script/generate-yyjson +++ b/script/generate-yyjson @@ -22,4 +22,4 @@ bindgen \ --allowlist-type=yyjson_val \ --allowlist-var=YYJSON_READ_NOFLAG \ --allowlist-var=YYJSON_READ_SUCCESS \ - > "${_repo}/src/yyjson.rs" + > "${_repo}/src/ffi/yyjson.rs" diff --git a/src/deserialize/utf8.rs b/src/deserialize/utf8.rs index 1791e525..ddb03563 100644 --- a/src/deserialize/utf8.rs +++ b/src/deserialize/utf8.rs @@ -1,10 +1,10 @@ // SPDX-License-Identifier: (Apache-2.0 OR MIT) use crate::deserialize::DeserializeError; -use crate::error::INVALID_STR; use crate::ffi::*; use crate::str::*; use crate::typeref::*; +use crate::util::INVALID_STR; use std::borrow::Cow; use std::os::raw::c_char; diff --git a/src/deserialize/yyjson.rs b/src/deserialize/yyjson.rs index d292e48e..c8c5b774 100644 --- a/src/deserialize/yyjson.rs +++ b/src/deserialize/yyjson.rs @@ -2,9 +2,9 @@ use crate::deserialize::pyobject::*; use crate::deserialize::DeserializeError; +use crate::ffi::yyjson::*; use crate::str::*; use crate::typeref::*; -use crate::yyjson::*; use std::borrow::Cow; use std::os::raw::c_char; use std::ptr::{null, null_mut, NonNull}; diff --git a/src/error.rs b/src/error.rs deleted file mode 100644 index 06c3fe4c..00000000 --- a/src/error.rs +++ /dev/null @@ -1,3 +0,0 @@ -// SPDX-License-Identifier: (Apache-2.0 OR MIT) - -pub const INVALID_STR: &str = "str is not valid UTF-8: surrogates not allowed"; diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index c82cf032..ab9c4192 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -8,6 +8,8 @@ mod fragment; mod immortal; mod list; mod long; +#[cfg(feature = "yyjson")] +pub mod yyjson; pub use buffer::*; pub use bytes::*; diff --git a/src/yyjson.rs b/src/ffi/yyjson.rs similarity index 100% rename from src/yyjson.rs rename to src/ffi/yyjson.rs diff --git a/src/lib.rs b/src/lib.rs index 68fb2aa2..c427586e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,16 +19,12 @@ mod util; mod deserialize; -mod error; mod ffi; mod opt; mod serialize; mod str; mod typeref; -#[cfg(feature = "yyjson")] -mod yyjson; - use pyo3_ffi::*; use std::os::raw::c_char; use std::os::raw::c_int; diff --git a/src/serialize/error.rs b/src/serialize/error.rs index 812e7a84..4810c492 100644 --- a/src/serialize/error.rs +++ b/src/serialize/error.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: (Apache-2.0 OR MIT) -use crate::error::INVALID_STR; use std::ffi::CStr; use std::ptr::NonNull; @@ -33,7 +32,7 @@ impl std::fmt::Display for SerializeError { } SerializeError::Integer53Bits => write!(f, "Integer exceeds 53-bit range"), SerializeError::Integer64Bits => write!(f, "Integer exceeds 64-bit range"), - SerializeError::InvalidStr => write!(f, "{}", INVALID_STR), + SerializeError::InvalidStr => write!(f, "{}", crate::util::INVALID_STR), SerializeError::InvalidFragment => write!(f, "orjson.Fragment's content is not of type bytes or str"), SerializeError::KeyMustBeStr => write!(f, "Dict key must be str"), SerializeError::RecursionLimit => write!(f, "Recursion limit reached"), diff --git a/src/serialize/json.rs b/src/serialize/json.rs index 703155a6..f4147c09 100644 --- a/src/serialize/json.rs +++ b/src/serialize/json.rs @@ -389,31 +389,12 @@ where type Ok = (); type Error = Error; - #[inline(always)] - fn serialize_entry(&mut self, key: &K, value: &V) -> Result<()> + fn serialize_entry(&mut self, _key: &K, _value: &V) -> Result<()> where K: ?Sized + Serialize, V: ?Sized + Serialize, { - self.ser - .formatter - .begin_object_key(&mut self.ser.writer, self.state == State::First) - .map_err(Error::io)?; - key.serialize(MapKeySerializer { ser: self.ser })?; - - self.ser - .formatter - .end_object_key(&mut self.ser.writer) - .map_err(Error::io)?; - self.ser - .formatter - .begin_object_value(&mut self.ser.writer) - .map_err(Error::io)?; - value.serialize(&mut *self.ser)?; - self.ser - .formatter - .end_object_value(&mut self.ser.writer) - .map_err(Error::io) + unreachable!() } #[inline] diff --git a/src/serialize/mod.rs b/src/serialize/mod.rs index aa341cd1..53301410 100644 --- a/src/serialize/mod.rs +++ b/src/serialize/mod.rs @@ -1,23 +1,9 @@ // SPDX-License-Identifier: (Apache-2.0 OR MIT) -mod dataclass; -mod datetime; -#[macro_use] -mod datetimelike; -mod default; -mod dict; mod error; -mod float; -mod fragment; -mod int; mod json; -mod list; -mod numpy; -mod pyenum; +mod per_type; mod serializer; -mod str; -mod tuple; -mod uuid; mod writer; pub use serializer::serialize; diff --git a/src/serialize/dataclass.rs b/src/serialize/per_type/dataclass.rs similarity index 100% rename from src/serialize/dataclass.rs rename to src/serialize/per_type/dataclass.rs diff --git a/src/serialize/datetime.rs b/src/serialize/per_type/datetime.rs similarity index 98% rename from src/serialize/datetime.rs rename to src/serialize/per_type/datetime.rs index adf35fb8..47d0c20b 100644 --- a/src/serialize/datetime.rs +++ b/src/serialize/per_type/datetime.rs @@ -1,8 +1,10 @@ // SPDX-License-Identifier: (Apache-2.0 OR MIT) use crate::opt::*; -use crate::serialize::datetimelike::{DateTimeBuffer, DateTimeError, DateTimeLike, Offset}; use crate::serialize::error::*; +use crate::serialize::per_type::datetimelike::{ + DateTimeBuffer, DateTimeError, DateTimeLike, Offset, +}; use crate::typeref::*; use serde::ser::{Serialize, Serializer}; diff --git a/src/serialize/datetimelike.rs b/src/serialize/per_type/datetimelike.rs similarity index 100% rename from src/serialize/datetimelike.rs rename to src/serialize/per_type/datetimelike.rs diff --git a/src/serialize/default.rs b/src/serialize/per_type/default.rs similarity index 100% rename from src/serialize/default.rs rename to src/serialize/per_type/default.rs diff --git a/src/serialize/dict.rs b/src/serialize/per_type/dict.rs similarity index 98% rename from src/serialize/dict.rs rename to src/serialize/per_type/dict.rs index a2517e06..c5d9448b 100644 --- a/src/serialize/dict.rs +++ b/src/serialize/per_type/dict.rs @@ -2,12 +2,12 @@ use crate::ffi::PyDictIter; use crate::opt::*; -use crate::serialize::datetime::*; -use crate::serialize::datetimelike::*; use crate::serialize::error::*; -use crate::serialize::serializer::pyobject_to_obtype; -use crate::serialize::serializer::*; -use crate::serialize::uuid::*; +use crate::serialize::per_type::datetimelike::{DateTimeBuffer, DateTimeLike}; +use crate::serialize::per_type::*; +use crate::serialize::serializer::{ + pyobject_to_obtype, ObType, PyObjectSerializer, RECURSION_LIMIT, +}; use crate::str::*; use crate::typeref::*; use compact_str::CompactString; diff --git a/src/serialize/float.rs b/src/serialize/per_type/float.rs similarity index 100% rename from src/serialize/float.rs rename to src/serialize/per_type/float.rs diff --git a/src/serialize/fragment.rs b/src/serialize/per_type/fragment.rs similarity index 100% rename from src/serialize/fragment.rs rename to src/serialize/per_type/fragment.rs diff --git a/src/serialize/int.rs b/src/serialize/per_type/int.rs similarity index 100% rename from src/serialize/int.rs rename to src/serialize/per_type/int.rs diff --git a/src/serialize/list.rs b/src/serialize/per_type/list.rs similarity index 95% rename from src/serialize/list.rs rename to src/serialize/per_type/list.rs index d9be248e..9e51bfa9 100644 --- a/src/serialize/list.rs +++ b/src/serialize/per_type/list.rs @@ -3,7 +3,7 @@ use crate::ffi::PyListIter; use crate::opt::*; use crate::serialize::error::*; -use crate::serialize::serializer::*; +use crate::serialize::serializer::{PyObjectSerializer, RECURSION_LIMIT}; use serde::ser::{Serialize, SerializeSeq, Serializer}; use std::ptr::NonNull; diff --git a/src/serialize/per_type/mod.rs b/src/serialize/per_type/mod.rs new file mode 100644 index 00000000..6ab62530 --- /dev/null +++ b/src/serialize/per_type/mod.rs @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: (Apache-2.0 OR MIT) + +mod dataclass; +mod datetime; +mod pybool; +#[macro_use] +mod datetimelike; +mod default; +mod dict; +mod float; +mod fragment; +mod int; +mod list; +mod none; +mod numpy; +mod pyenum; +mod tuple; +mod unicode; +mod uuid; + +pub use dataclass::DataclassGenericSerializer; +pub use datetime::{Date, DateTime, Time}; +pub use default::DefaultSerializer; +pub use dict::DictGenericSerializer; +pub use float::FloatSerializer; +pub use fragment::FragmentSerializer; +pub use int::{Int53Serializer, IntSerializer}; +pub use list::ListSerializer; +pub use none::NoneSerializer; +pub use numpy::{is_numpy_array, is_numpy_scalar, NumpyScalar, NumpySerializer}; +pub use pybool::BoolSerializer; +pub use pyenum::EnumSerializer; +pub use tuple::TupleSerializer; +pub use unicode::{StrSerializer, StrSubclassSerializer}; +pub use uuid::UUID; diff --git a/src/serialize/per_type/none.rs b/src/serialize/per_type/none.rs new file mode 100644 index 00000000..173ce9f5 --- /dev/null +++ b/src/serialize/per_type/none.rs @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: (Apache-2.0 OR MIT) + +use serde::ser::{Serialize, Serializer}; + +pub struct NoneSerializer; + +impl NoneSerializer { + pub fn new() -> Self { + NoneSerializer {} + } +} + +impl Serialize for NoneSerializer { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_unit() + } +} diff --git a/src/serialize/numpy.rs b/src/serialize/per_type/numpy.rs similarity index 99% rename from src/serialize/numpy.rs rename to src/serialize/per_type/numpy.rs index 2ae92040..0bfd60eb 100644 --- a/src/serialize/numpy.rs +++ b/src/serialize/per_type/numpy.rs @@ -1,7 +1,10 @@ use crate::opt::*; -use crate::serialize::datetimelike::{DateTimeBuffer, DateTimeError, DateTimeLike, Offset}; -use crate::serialize::default::*; + use crate::serialize::error::*; +use crate::serialize::per_type::datetimelike::{ + DateTimeBuffer, DateTimeError, DateTimeLike, Offset, +}; +use crate::serialize::per_type::*; use crate::typeref::{load_numpy_types, ARRAY_STRUCT_STR, DESCR_STR, DTYPE_STR, NUMPY_TYPES}; use chrono::{Datelike, NaiveDate, NaiveDateTime, Timelike}; use pyo3_ffi::*; diff --git a/src/serialize/per_type/pybool.rs b/src/serialize/per_type/pybool.rs new file mode 100644 index 00000000..6109693b --- /dev/null +++ b/src/serialize/per_type/pybool.rs @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (Apache-2.0 OR MIT) + +use serde::ser::{Serialize, Serializer}; + +#[repr(transparent)] +pub struct BoolSerializer { + ptr: *mut pyo3_ffi::PyObject, +} + +impl BoolSerializer { + pub fn new(ptr: *mut pyo3_ffi::PyObject) -> Self { + BoolSerializer { ptr: ptr } + } +} + +impl Serialize for BoolSerializer { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bool(unsafe { self.ptr == crate::typeref::TRUE }) + } +} diff --git a/src/serialize/pyenum.rs b/src/serialize/per_type/pyenum.rs similarity index 100% rename from src/serialize/pyenum.rs rename to src/serialize/per_type/pyenum.rs diff --git a/src/serialize/tuple.rs b/src/serialize/per_type/tuple.rs similarity index 100% rename from src/serialize/tuple.rs rename to src/serialize/per_type/tuple.rs diff --git a/src/serialize/str.rs b/src/serialize/per_type/unicode.rs similarity index 100% rename from src/serialize/str.rs rename to src/serialize/per_type/unicode.rs diff --git a/src/serialize/uuid.rs b/src/serialize/per_type/uuid.rs similarity index 100% rename from src/serialize/uuid.rs rename to src/serialize/per_type/uuid.rs diff --git a/src/serialize/serializer.rs b/src/serialize/serializer.rs index 0d7d0b36..24f0464e 100644 --- a/src/serialize/serializer.rs +++ b/src/serialize/serializer.rs @@ -1,19 +1,7 @@ // SPDX-License-Identifier: (Apache-2.0 OR MIT) use crate::opt::*; -use crate::serialize::dataclass::*; -use crate::serialize::datetime::*; -use crate::serialize::default::*; -use crate::serialize::dict::*; -use crate::serialize::float::*; -use crate::serialize::fragment::*; -use crate::serialize::int::*; -use crate::serialize::list::*; -use crate::serialize::numpy::*; -use crate::serialize::pyenum::EnumSerializer; -use crate::serialize::str::*; -use crate::serialize::tuple::*; -use crate::serialize::uuid::*; +use crate::serialize::per_type::*; use crate::serialize::writer::*; use crate::typeref::*; use serde::ser::{Serialize, Serializer}; @@ -74,98 +62,78 @@ pub enum ObType { } pub fn pyobject_to_obtype(obj: *mut pyo3_ffi::PyObject, opts: Opt) -> ObType { - unsafe { - let ob_type = ob_type!(obj); - if ob_type == STR_TYPE { - ObType::Str - } else if ob_type == INT_TYPE { - ObType::Int - } else if ob_type == BOOL_TYPE { - ObType::Bool - } else if ob_type == NONE_TYPE { - ObType::None - } else if ob_type == FLOAT_TYPE { - ObType::Float - } else if ob_type == LIST_TYPE { - ObType::List - } else if ob_type == DICT_TYPE { - ObType::Dict - } else if ob_type == DATETIME_TYPE && opt_disabled!(opts, PASSTHROUGH_DATETIME) { - ObType::Datetime - } else { - pyobject_to_obtype_unlikely(ob_type, opts) - } + let ob_type = ob_type!(obj); + if is_class_by_type!(ob_type, STR_TYPE) { + ObType::Str + } else if is_class_by_type!(ob_type, INT_TYPE) { + ObType::Int + } else if is_class_by_type!(ob_type, BOOL_TYPE) { + ObType::Bool + } else if is_class_by_type!(ob_type, NONE_TYPE) { + ObType::None + } else if is_class_by_type!(ob_type, FLOAT_TYPE) { + ObType::Float + } else if is_class_by_type!(ob_type, LIST_TYPE) { + ObType::List + } else if is_class_by_type!(ob_type, DICT_TYPE) { + ObType::Dict + } else if is_class_by_type!(ob_type, DATETIME_TYPE) && opt_disabled!(opts, PASSTHROUGH_DATETIME) + { + ObType::Datetime + } else { + pyobject_to_obtype_unlikely(ob_type, opts) } } -macro_rules! is_subclass_by_flag { - ($ob_type:expr, $flag:ident) => { - (((*$ob_type).tp_flags & pyo3_ffi::$flag) != 0) - }; -} - -macro_rules! is_subclass_by_type { - ($ob_type:expr, $type:ident) => { - (*($ob_type as *mut pyo3_ffi::PyTypeObject)) - .ob_base - .ob_base - .ob_type - == $type - }; -} - #[cfg_attr(feature = "optimize", optimize(size))] #[inline(never)] pub fn pyobject_to_obtype_unlikely(ob_type: *mut pyo3_ffi::PyTypeObject, opts: Opt) -> ObType { - unsafe { - if ob_type == UUID_TYPE { - return ObType::Uuid; - } else if ob_type == TUPLE_TYPE { - return ObType::Tuple; - } else if ob_type == FRAGMENT_TYPE { - return ObType::Fragment; - } + if is_class_by_type!(ob_type, UUID_TYPE) { + return ObType::Uuid; + } else if is_class_by_type!(ob_type, TUPLE_TYPE) { + return ObType::Tuple; + } else if is_class_by_type!(ob_type, FRAGMENT_TYPE) { + return ObType::Fragment; + } - if opt_disabled!(opts, PASSTHROUGH_DATETIME) { - if ob_type == DATE_TYPE { - return ObType::Date; - } else if ob_type == TIME_TYPE { - return ObType::Time; - } + if opt_disabled!(opts, PASSTHROUGH_DATETIME) { + if is_class_by_type!(ob_type, DATE_TYPE) { + return ObType::Date; + } else if is_class_by_type!(ob_type, TIME_TYPE) { + return ObType::Time; } + } - if opt_disabled!(opts, PASSTHROUGH_SUBCLASS) { - if is_subclass_by_flag!(ob_type, Py_TPFLAGS_UNICODE_SUBCLASS) { - return ObType::StrSubclass; - } else if is_subclass_by_flag!(ob_type, Py_TPFLAGS_LONG_SUBCLASS) { - return ObType::Int; - } else if is_subclass_by_flag!(ob_type, Py_TPFLAGS_LIST_SUBCLASS) { - return ObType::List; - } else if is_subclass_by_flag!(ob_type, Py_TPFLAGS_DICT_SUBCLASS) { - return ObType::Dict; - } + if opt_disabled!(opts, PASSTHROUGH_SUBCLASS) { + if is_subclass_by_flag!(ob_type, Py_TPFLAGS_UNICODE_SUBCLASS) { + return ObType::StrSubclass; + } else if is_subclass_by_flag!(ob_type, Py_TPFLAGS_LONG_SUBCLASS) { + return ObType::Int; + } else if is_subclass_by_flag!(ob_type, Py_TPFLAGS_LIST_SUBCLASS) { + return ObType::List; + } else if is_subclass_by_flag!(ob_type, Py_TPFLAGS_DICT_SUBCLASS) { + return ObType::Dict; } + } - if is_subclass_by_type!(ob_type, ENUM_TYPE) { - return ObType::Enum; - } + if is_subclass_by_type!(ob_type, ENUM_TYPE) { + return ObType::Enum; + } - if opt_disabled!(opts, PASSTHROUGH_DATACLASS) - && pydict_contains!(ob_type, DATACLASS_FIELDS_STR) - { - return ObType::Dataclass; - } + if opt_disabled!(opts, PASSTHROUGH_DATACLASS) && pydict_contains!(ob_type, DATACLASS_FIELDS_STR) + { + return ObType::Dataclass; + } - if unlikely!(opt_enabled!(opts, SERIALIZE_NUMPY)) { - if is_numpy_scalar(ob_type) { - return ObType::NumpyScalar; - } else if is_numpy_array(ob_type) { - return ObType::NumpyArray; - } + if unlikely!(opt_enabled!(opts, SERIALIZE_NUMPY)) { + if is_numpy_scalar(ob_type) { + return ObType::NumpyScalar; + } else if is_numpy_array(ob_type) { + return ObType::NumpyArray; } - - ObType::Unknown } + + ObType::Unknown } pub struct PyObjectSerializer { @@ -209,9 +177,9 @@ impl Serialize for PyObjectSerializer { IntSerializer::new(self.ptr).serialize(serializer) } } - ObType::None => serializer.serialize_unit(), + ObType::None => NoneSerializer::new().serialize(serializer), ObType::Float => FloatSerializer::new(self.ptr).serialize(serializer), - ObType::Bool => serializer.serialize_bool(unsafe { self.ptr == TRUE }), + ObType::Bool => BoolSerializer::new(self.ptr).serialize(serializer), ObType::Datetime => DateTime::new(self.ptr, self.opts).serialize(serializer), ObType::Date => Date::new(self.ptr).serialize(serializer), ObType::Time => Time::new(self.ptr, self.opts).serialize(serializer), diff --git a/src/typeref.rs b/src/typeref.rs index 664f8a39..55dad15c 100644 --- a/src/typeref.rs +++ b/src/typeref.rs @@ -98,7 +98,7 @@ struct YYJSONBuffer(UnsafeCell>); #[cfg(feature = "yyjson")] pub struct YYJSONAlloc { - pub alloc: crate::yyjson::yyjson_alc, + pub alloc: crate::ffi::yyjson::yyjson_alc, _buffer: Box, } @@ -112,14 +112,14 @@ pub fn yyjson_init() -> Box { // we can use that instead. let layout = std::alloc::Layout::new::(); let buffer = unsafe { Box::from_raw(std::alloc::alloc(layout).cast::()) }; - let mut alloc = crate::yyjson::yyjson_alc { + let mut alloc = crate::ffi::yyjson::yyjson_alc { malloc: None, realloc: None, free: None, ctx: null_mut(), }; unsafe { - crate::yyjson::yyjson_alc_pool_init( + crate::ffi::yyjson::yyjson_alc_pool_init( &mut alloc, buffer.0.get().cast::(), YYJSON_BUFFER_SIZE, diff --git a/src/util.rs b/src/util.rs index fa3b7e1d..44884eeb 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: (Apache-2.0 OR MIT) +pub const INVALID_STR: &str = "str is not valid UTF-8: surrogates not allowed"; + macro_rules! is_type { ($obj_ptr:expr, $type_ptr:expr) => { unsafe { $obj_ptr == $type_ptr } @@ -12,6 +14,30 @@ macro_rules! ob_type { }; } +macro_rules! is_class_by_type { + ($ob_type:expr, $type_ptr:ident) => { + unsafe { $ob_type == $type_ptr } + }; +} + +macro_rules! is_subclass_by_flag { + ($ob_type:expr, $flag:ident) => { + unsafe { (((*$ob_type).tp_flags & pyo3_ffi::$flag) != 0) } + }; +} + +macro_rules! is_subclass_by_type { + ($ob_type:expr, $type:ident) => { + unsafe { + (*($ob_type as *mut pyo3_ffi::PyTypeObject)) + .ob_base + .ob_base + .ob_type + == $type + } + }; +} + macro_rules! err { ($msg:expr) => { return Err(serde::ser::Error::custom($msg))