Skip to content

Commit ebb98fb

Browse files
committed
More code reuse
1 parent 03d55e9 commit ebb98fb

4 files changed

Lines changed: 186 additions & 218 deletions

File tree

src/decode.rs

Lines changed: 28 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
22

33
use crate::exc::*;
4-
use crate::typeref;
4+
use crate::typeref::*;
55
use pyo3::prelude::*;
66
use serde::de::{self, DeserializeSeed, Deserializer, MapAccess, SeqAccess, Visitor};
77
use smallvec::SmallVec;
@@ -14,18 +14,16 @@ use std::ptr::NonNull;
1414
pub fn deserialize(ptr: *mut pyo3::ffi::PyObject) -> PyResult<NonNull<pyo3::ffi::PyObject>> {
1515
let obj_type_ptr = unsafe { (*ptr).ob_type };
1616
let data: Cow<str>;
17-
if unsafe { obj_type_ptr == typeref::STR_PTR } {
17+
if is_type!(obj_type_ptr, STR_PTR) {
1818
let mut str_size: pyo3::ffi::Py_ssize_t = 0;
19-
let uni = unsafe { pyo3::ffi::PyUnicode_AsUTF8AndSize(ptr, &mut str_size) as *const u8 };
20-
if unsafe { std::intrinsics::unlikely(uni.is_null()) } {
19+
let uni = ffi!(PyUnicode_AsUTF8AndSize(ptr, &mut str_size)) as *const u8;
20+
if unlikely!(uni.is_null()) {
2121
return Err(JSONDecodeError::py_err((INVALID_STR, "", 0)));
2222
}
23-
data = Cow::Borrowed(unsafe {
24-
std::str::from_utf8_unchecked(std::slice::from_raw_parts(uni, str_size as usize))
25-
});
26-
} else if unsafe { obj_type_ptr == typeref::BYTES_PTR } {
27-
let buffer = unsafe { pyo3::ffi::PyBytes_AsString(ptr) as *const u8 };
28-
let length = unsafe { pyo3::ffi::PyBytes_Size(ptr) as usize };
23+
data = Cow::Borrowed(str_from_slice!(uni, str_size));
24+
} else if is_type!(obj_type_ptr, BYTES_PTR) {
25+
let buffer = ffi!(PyBytes_AsString(ptr)) as *const u8;
26+
let length = ffi!(PyBytes_Size(ptr)) as usize;
2927
let slice = unsafe { std::slice::from_raw_parts(buffer, length) };
3028
if encoding_rs::Encoding::utf8_valid_up_to(slice) != length {
3129
return Err(JSONDecodeError::py_err((INVALID_STR, "", 0)));
@@ -74,24 +72,20 @@ impl<'de, 'a> Visitor<'de> for JsonValue {
7472
}
7573

7674
fn visit_unit<E>(self) -> Result<Self::Value, E> {
77-
unsafe { pyo3::ffi::Py_INCREF(typeref::NONE) };
78-
Ok(unsafe { typeref::NONE })
75+
ffi!(Py_INCREF(NONE));
76+
Ok(unsafe { NONE })
7977
}
8078

8179
fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
8280
where
8381
E: de::Error,
8482
{
8583
if value {
86-
unsafe {
87-
pyo3::ffi::Py_INCREF(typeref::TRUE);
88-
Ok(typeref::TRUE)
89-
}
84+
ffi!(Py_INCREF(TRUE));
85+
Ok(unsafe { TRUE })
9086
} else {
91-
unsafe {
92-
pyo3::ffi::Py_INCREF(typeref::FALSE);
93-
Ok(typeref::FALSE)
94-
}
87+
ffi!(Py_INCREF(FALSE));
88+
Ok(unsafe { FALSE })
9589
}
9690
}
9791

@@ -101,11 +95,11 @@ impl<'de, 'a> Visitor<'de> for JsonValue {
10195
{
10296
#[cfg(target_os = "windows")]
10397
{
104-
Ok(unsafe { pyo3::ffi::PyLong_FromLongLong(value) })
98+
Ok(ffi!(PyLong_FromLongLong(value)))
10599
}
106100
#[cfg(not(target_os = "windows"))]
107101
{
108-
Ok(unsafe { pyo3::ffi::PyLong_FromLong(value) })
102+
Ok(ffi!(PyLong_FromLong(value)))
109103
}
110104
}
111105

@@ -115,43 +109,33 @@ impl<'de, 'a> Visitor<'de> for JsonValue {
115109
{
116110
#[cfg(target_os = "windows")]
117111
{
118-
Ok(unsafe { pyo3::ffi::PyLong_FromUnsignedLongLong(value) })
112+
Ok(ffi!(PyLong_FromUnsignedLongLong(value)))
119113
}
120114
#[cfg(not(target_os = "windows"))]
121115
{
122-
Ok(unsafe { pyo3::ffi::PyLong_FromUnsignedLong(value) })
116+
Ok(ffi!(PyLong_FromUnsignedLong(value)))
123117
}
124118
}
125119

126120
fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
127121
where
128122
E: de::Error,
129123
{
130-
Ok(unsafe { pyo3::ffi::PyFloat_FromDouble(value) })
124+
Ok(ffi!(PyFloat_FromDouble(value)))
131125
}
132126

133127
fn visit_borrowed_str<E>(self, value: &str) -> Result<Self::Value, E>
134128
where
135129
E: de::Error,
136130
{
137-
Ok(unsafe {
138-
pyo3::ffi::PyUnicode_FromStringAndSize(
139-
value.as_ptr() as *const c_char,
140-
value.len() as pyo3::ffi::Py_ssize_t,
141-
)
142-
})
131+
Ok(str_to_pyobject!(value))
143132
}
144133

145134
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
146135
where
147136
E: de::Error,
148137
{
149-
Ok(unsafe {
150-
pyo3::ffi::PyUnicode_FromStringAndSize(
151-
value.as_ptr() as *const c_char,
152-
value.len() as pyo3::ffi::Py_ssize_t,
153-
)
154-
})
138+
Ok(str_to_pyobject!(value))
155139
}
156140

157141
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
@@ -162,9 +146,9 @@ impl<'de, 'a> Visitor<'de> for JsonValue {
162146
while let Some(elem) = seq.next_element_seed(self)? {
163147
elements.push(elem);
164148
}
165-
let ptr = unsafe { pyo3::ffi::PyList_New(elements.len() as pyo3::ffi::Py_ssize_t) };
149+
let ptr = ffi!(PyList_New(elements.len() as pyo3::ffi::Py_ssize_t));
166150
for (i, obj) in elements.iter().enumerate() {
167-
unsafe { pyo3::ffi::PyList_SET_ITEM(ptr, i as pyo3::ffi::Py_ssize_t, *obj) };
151+
ffi!(PyList_SET_ITEM(ptr, i as pyo3::ffi::Py_ssize_t, *obj));
168152
}
169153
Ok(ptr)
170154
}
@@ -173,20 +157,13 @@ impl<'de, 'a> Visitor<'de> for JsonValue {
173157
where
174158
A: MapAccess<'de>,
175159
{
176-
let dict_ptr = unsafe { pyo3::ffi::PyDict_New() };
160+
let dict_ptr = ffi!(PyDict_New());
177161
while let Some((key, value)) = map.next_entry_seed(PhantomData::<Cow<str>>, self)? {
178-
let pykey = unsafe {
179-
pyo3::ffi::PyUnicode_FromStringAndSize(
180-
key.as_ptr() as *const c_char,
181-
key.len() as pyo3::ffi::Py_ssize_t,
182-
)
183-
};
184-
let _ = unsafe { pyo3::ffi::PyDict_SetItem(dict_ptr, pykey, value) };
162+
let pykey = str_to_pyobject!(key);
163+
let _ = ffi!(PyDict_SetItem(dict_ptr, pykey, value));
185164
// counter Py_INCREF in insertdict
186-
unsafe {
187-
pyo3::ffi::Py_DECREF(pykey);
188-
pyo3::ffi::Py_DECREF(value);
189-
};
165+
ffi!(Py_DECREF(pykey));
166+
ffi!(Py_DECREF(value));
190167
}
191168
Ok(dict_ptr)
192169
}

0 commit comments

Comments
 (0)