Skip to content

Commit 6b626c9

Browse files
committed
dict, list full impl
1 parent 05fd9e1 commit 6b626c9

File tree

3 files changed

+250
-106
lines changed

3 files changed

+250
-106
lines changed

src/serialize/per_type/dataclass.rs

+19-13
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,17 @@ impl Serialize for DataclassFastSerializer {
106106

107107
pydict_next!(self.ptr, &mut pos, &mut next_key, &mut next_value);
108108

109-
if unlikely!(unsafe { ob_type!(key) != STR_TYPE }) {
110-
err!(SerializeError::KeyMustBeStr)
111-
}
112-
let data = unicode_to_str(key);
113-
if unlikely!(data.is_none()) {
114-
err!(SerializeError::InvalidStr)
115-
}
116-
let key_as_str = data.unwrap();
109+
let key_as_str = {
110+
let key_ob_type = ob_type!(key);
111+
if unlikely!(!is_class_by_type!(key_ob_type, STR_TYPE)) {
112+
err!(SerializeError::KeyMustBeStr)
113+
}
114+
let tmp = unicode_to_str(key);
115+
if unlikely!(tmp.is_none()) {
116+
err!(SerializeError::InvalidStr)
117+
};
118+
tmp.unwrap()
119+
};
117120
if unlikely!(key_as_str.as_bytes()[0] == b'_') {
118121
continue;
119122
}
@@ -179,11 +182,14 @@ impl Serialize for DataclassFallbackSerializer {
179182
if unsafe { field_type as *mut pyo3_ffi::PyTypeObject != FIELD_TYPE } {
180183
continue;
181184
}
182-
let data = unicode_to_str(attr);
183-
if unlikely!(data.is_none()) {
184-
err!(SerializeError::InvalidStr);
185-
}
186-
let key_as_str = data.unwrap();
185+
186+
let key_as_str = {
187+
let tmp = unicode_to_str(attr);
188+
if unlikely!(tmp.is_none()) {
189+
err!(SerializeError::InvalidStr)
190+
};
191+
tmp.unwrap()
192+
};
187193
if key_as_str.as_bytes()[0] == b'_' {
188194
continue;
189195
}

src/serialize/per_type/dict.rs

+137-59
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@
33
use crate::opt::*;
44
use crate::serialize::error::SerializeError;
55
use crate::serialize::obtype::{pyobject_to_obtype, ObType};
6+
use crate::serialize::per_type::datetimelike::DateTimeLike;
67
use crate::serialize::per_type::{
7-
BoolSerializer, Date, DateTime, DateTimeBuffer, DateTimeLike, FloatSerializer, Int53Serializer,
8-
IntSerializer, ListTupleSerializer, NoneSerializer, StrSerializer, Time, ZeroListSerializer,
9-
UUID,
8+
BoolSerializer, DataclassGenericSerializer, Date, DateTime, DateTimeBuffer, DefaultSerializer,
9+
EnumSerializer, FloatSerializer, FragmentSerializer, Int53Serializer, IntSerializer,
10+
ListTupleSerializer, NoneSerializer, NumpyScalar, NumpySerializer, StrSerializer,
11+
StrSubclassSerializer, Time, ZeroListSerializer, UUID,
1012
};
1113
use crate::serialize::serializer::PyObjectSerializer;
1214
use crate::serialize::state::SerializerState;
1315
use crate::str::{unicode_to_str, unicode_to_str_via_ffi};
14-
use crate::typeref::{
15-
BOOL_TYPE, DATETIME_TYPE, DICT_TYPE, FLOAT_TYPE, INT_TYPE, LIST_TYPE, NONE_TYPE, STR_TYPE,
16-
TRUE, VALUE_STR,
17-
};
16+
use crate::typeref::{STR_TYPE, TRUE, VALUE_STR};
1817
use compact_str::CompactString;
1918
use core::ptr::NonNull;
2019
use serde::ser::{Serialize, SerializeMap, Serializer};
@@ -89,6 +88,125 @@ impl Serialize for DictGenericSerializer {
8988
}
9089
}
9190

91+
macro_rules! impl_serialize_entry {
92+
($map:expr, $self:expr, $key:expr, $value:expr) => {
93+
match pyobject_to_obtype($value, $self.state.opts()) {
94+
ObType::Str => {
95+
$map.serialize_key($key).unwrap();
96+
$map.serialize_value(&StrSerializer::new($value))?;
97+
}
98+
ObType::StrSubclass => {
99+
$map.serialize_key($key).unwrap();
100+
$map.serialize_value(&StrSubclassSerializer::new($value))?;
101+
}
102+
ObType::Int => {
103+
if unlikely!(opt_enabled!($self.state.opts(), STRICT_INTEGER)) {
104+
$map.serialize_key($key).unwrap();
105+
$map.serialize_value(&Int53Serializer::new($value))?;
106+
} else {
107+
$map.serialize_key($key).unwrap();
108+
$map.serialize_value(&IntSerializer::new($value))?;
109+
}
110+
}
111+
ObType::None => {
112+
$map.serialize_key($key).unwrap();
113+
$map.serialize_value(&NoneSerializer::new()).unwrap();
114+
}
115+
ObType::Float => {
116+
$map.serialize_key($key).unwrap();
117+
$map.serialize_value(&FloatSerializer::new($value))?;
118+
}
119+
ObType::Bool => {
120+
$map.serialize_key($key).unwrap();
121+
$map.serialize_value(&BoolSerializer::new($value)).unwrap();
122+
}
123+
ObType::Datetime => {
124+
$map.serialize_key($key).unwrap();
125+
$map.serialize_value(&DateTime::new($value, $self.state.opts()))?;
126+
}
127+
ObType::Date => {
128+
$map.serialize_key($key).unwrap();
129+
$map.serialize_value(&Date::new($value))?;
130+
}
131+
ObType::Time => {
132+
$map.serialize_key($key).unwrap();
133+
$map.serialize_value(&Time::new($value, $self.state.opts()))?;
134+
}
135+
ObType::Uuid => {
136+
$map.serialize_key($key).unwrap();
137+
$map.serialize_value(&UUID::new($value)).unwrap();
138+
}
139+
ObType::Dict => {
140+
let pyvalue = DictGenericSerializer::new($value, $self.state, $self.default);
141+
$map.serialize_key($key).unwrap();
142+
$map.serialize_value(&pyvalue)?;
143+
}
144+
ObType::List => {
145+
if ffi!(Py_SIZE($value)) == 0 {
146+
$map.serialize_key($key).unwrap();
147+
$map.serialize_value(&ZeroListSerializer::new()).unwrap();
148+
} else {
149+
let pyvalue =
150+
ListTupleSerializer::from_list($value, $self.state, $self.default);
151+
$map.serialize_key($key).unwrap();
152+
$map.serialize_value(&pyvalue)?;
153+
}
154+
}
155+
ObType::Tuple => {
156+
if ffi!(Py_SIZE($value)) == 0 {
157+
$map.serialize_key($key).unwrap();
158+
$map.serialize_value(&ZeroListSerializer::new()).unwrap();
159+
} else {
160+
let pyvalue =
161+
ListTupleSerializer::from_tuple($value, $self.state, $self.default);
162+
$map.serialize_key($key).unwrap();
163+
$map.serialize_value(&pyvalue)?;
164+
}
165+
}
166+
ObType::Dataclass => {
167+
$map.serialize_key($key).unwrap();
168+
$map.serialize_value(&DataclassGenericSerializer::new(&PyObjectSerializer::new(
169+
$value,
170+
$self.state,
171+
$self.default,
172+
)))?;
173+
}
174+
ObType::Enum => {
175+
$map.serialize_key($key).unwrap();
176+
$map.serialize_value(&EnumSerializer::new(&PyObjectSerializer::new(
177+
$value,
178+
$self.state,
179+
$self.default,
180+
)))?;
181+
}
182+
ObType::NumpyArray => {
183+
$map.serialize_key($key).unwrap();
184+
$map.serialize_value(&NumpySerializer::new(&PyObjectSerializer::new(
185+
$value,
186+
$self.state,
187+
$self.default,
188+
)))?;
189+
}
190+
ObType::NumpyScalar => {
191+
$map.serialize_key($key).unwrap();
192+
$map.serialize_value(&NumpyScalar::new($value, $self.state.opts()))?;
193+
}
194+
ObType::Fragment => {
195+
$map.serialize_key($key).unwrap();
196+
$map.serialize_value(&FragmentSerializer::new($value))?;
197+
}
198+
ObType::Unknown => {
199+
$map.serialize_key($key).unwrap();
200+
$map.serialize_value(&DefaultSerializer::new(&PyObjectSerializer::new(
201+
$value,
202+
$self.state,
203+
$self.default,
204+
)))?;
205+
}
206+
}
207+
};
208+
}
209+
92210
pub struct Dict {
93211
ptr: *mut pyo3_ffi::PyObject,
94212
state: SerializerState,
@@ -119,60 +237,20 @@ impl Serialize for Dict {
119237
pydict_next!(self.ptr, &mut pos, &mut next_key, &mut next_value);
120238

121239
// key
122-
let key_ob_type = ob_type!(key);
123-
if unlikely!(!is_class_by_type!(key_ob_type, STR_TYPE)) {
124-
err!(SerializeError::KeyMustBeStr)
125-
}
126-
let key_as_str = unicode_to_str(key);
127-
if unlikely!(key_as_str.is_none()) {
128-
err!(SerializeError::InvalidStr)
129-
}
240+
let key_as_str = {
241+
let key_ob_type = ob_type!(key);
242+
if unlikely!(!is_class_by_type!(key_ob_type, STR_TYPE)) {
243+
err!(SerializeError::KeyMustBeStr)
244+
}
245+
let tmp = unicode_to_str(key);
246+
if unlikely!(tmp.is_none()) {
247+
err!(SerializeError::InvalidStr)
248+
};
249+
tmp.unwrap()
250+
};
130251

131252
// value
132-
let value_ob_type = ob_type!(value);
133-
if is_class_by_type!(value_ob_type, STR_TYPE) {
134-
map.serialize_key(key_as_str.unwrap()).unwrap();
135-
map.serialize_value(&StrSerializer::new(value))?;
136-
} else if is_class_by_type!(value_ob_type, INT_TYPE) {
137-
if unlikely!(opt_enabled!(self.state.opts(), STRICT_INTEGER)) {
138-
map.serialize_key(key_as_str.unwrap()).unwrap();
139-
map.serialize_value(&Int53Serializer::new(value))?;
140-
} else {
141-
map.serialize_key(key_as_str.unwrap()).unwrap();
142-
map.serialize_value(&IntSerializer::new(value))?;
143-
}
144-
} else if is_class_by_type!(value_ob_type, BOOL_TYPE) {
145-
map.serialize_key(key_as_str.unwrap()).unwrap();
146-
map.serialize_value(&BoolSerializer::new(value))?;
147-
} else if is_class_by_type!(value_ob_type, NONE_TYPE) {
148-
map.serialize_key(key_as_str.unwrap()).unwrap();
149-
map.serialize_value(&NoneSerializer::new())?;
150-
} else if is_class_by_type!(value_ob_type, FLOAT_TYPE) {
151-
map.serialize_key(key_as_str.unwrap()).unwrap();
152-
map.serialize_value(&FloatSerializer::new(value))?;
153-
} else if is_class_by_type!(value_ob_type, DICT_TYPE) {
154-
let pyvalue = DictGenericSerializer::new(value, self.state, self.default);
155-
map.serialize_key(key_as_str.unwrap()).unwrap();
156-
map.serialize_value(&pyvalue)?;
157-
} else if is_class_by_type!(value_ob_type, LIST_TYPE) {
158-
if ffi!(Py_SIZE(value)) == 0 {
159-
map.serialize_key(key_as_str.unwrap()).unwrap();
160-
map.serialize_value(&ZeroListSerializer::new())?;
161-
} else {
162-
let pyvalue = ListTupleSerializer::from_list(value, self.state, self.default);
163-
map.serialize_key(key_as_str.unwrap()).unwrap();
164-
map.serialize_value(&pyvalue)?;
165-
}
166-
} else if is_class_by_type!(value_ob_type, DATETIME_TYPE)
167-
&& opt_disabled!(self.state.opts(), PASSTHROUGH_DATETIME)
168-
{
169-
map.serialize_key(key_as_str.unwrap()).unwrap();
170-
map.serialize_value(&DateTime::new(value, self.state.opts()))?;
171-
} else {
172-
let pyvalue = PyObjectSerializer::new(value, self.state, self.default);
173-
map.serialize_key(key_as_str.unwrap()).unwrap();
174-
map.serialize_value(&pyvalue)?;
175-
}
253+
impl_serialize_entry!(map, self, key_as_str, value);
176254
}
177255

178256
map.end()

0 commit comments

Comments
 (0)