|
3 | 3 | use crate::opt::*;
|
4 | 4 | use crate::serialize::error::SerializeError;
|
5 | 5 | use crate::serialize::obtype::{pyobject_to_obtype, ObType};
|
| 6 | +use crate::serialize::per_type::datetimelike::DateTimeLike; |
6 | 7 | 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, |
10 | 12 | };
|
11 | 13 | use crate::serialize::serializer::PyObjectSerializer;
|
12 | 14 | use crate::serialize::state::SerializerState;
|
13 | 15 | 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}; |
18 | 17 | use compact_str::CompactString;
|
19 | 18 | use core::ptr::NonNull;
|
20 | 19 | use serde::ser::{Serialize, SerializeMap, Serializer};
|
@@ -89,6 +88,125 @@ impl Serialize for DictGenericSerializer {
|
89 | 88 | }
|
90 | 89 | }
|
91 | 90 |
|
| 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 | + |
92 | 210 | pub struct Dict {
|
93 | 211 | ptr: *mut pyo3_ffi::PyObject,
|
94 | 212 | state: SerializerState,
|
@@ -119,60 +237,20 @@ impl Serialize for Dict {
|
119 | 237 | pydict_next!(self.ptr, &mut pos, &mut next_key, &mut next_value);
|
120 | 238 |
|
121 | 239 | // 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 | + }; |
130 | 251 |
|
131 | 252 | // 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); |
176 | 254 | }
|
177 | 255 |
|
178 | 256 | map.end()
|
|
0 commit comments