diff --git a/data/issue331_1.json.xz b/data/issue331_1.json.xz new file mode 100644 index 00000000..c61ee5fe Binary files /dev/null and b/data/issue331_1.json.xz differ diff --git a/data/issue331_2.json.xz b/data/issue331_2.json.xz new file mode 100644 index 00000000..ad742f03 Binary files /dev/null and b/data/issue331_2.json.xz differ diff --git a/src/serialize/json.rs b/src/serialize/json.rs index c8c806e0..9308d757 100644 --- a/src/serialize/json.rs +++ b/src/serialize/json.rs @@ -1,62 +1,11 @@ // SPDX-License-Identifier: (Apache-2.0 OR MIT) // This is an adaptation of `src/value/ser.rs` from serde-json. +use crate::serialize::writer::WriteExt; use serde::ser::{self, Impossible, Serialize}; use serde_json::error::{Error, Result}; use std::io; -#[allow(missing_docs)] -// hack based on saethlin's research and patch in https://github.com/serde-rs/json/issues/766 -pub trait WriteExt: io::Write { - #[inline] - fn as_mut_buffer_ptr(&mut self) -> *mut u8 { - std::ptr::null_mut() - } - - #[inline] - fn reserve(&mut self, len: usize) { - let _ = len; - } - - #[inline] - fn set_written(&mut self, len: usize) { - let _ = len; - } - - #[inline] - fn write_str(&mut self, val: &str) -> std::result::Result<(), std::io::Error> { - let _ = val; - Ok(()) - } - - #[inline] - unsafe fn write_reserved_fragment( - &mut self, - val: &[u8], - ) -> std::result::Result<(), std::io::Error> { - let _ = val; - Ok(()) - } - - #[inline] - unsafe fn write_reserved_punctuation( - &mut self, - val: u8, - ) -> std::result::Result<(), std::io::Error> { - let _ = val; - Ok(()) - } - - #[inline] - unsafe fn write_reserved_indent( - &mut self, - len: usize, - ) -> std::result::Result<(), std::io::Error> { - let _ = len; - Ok(()) - } -} - pub struct Serializer { writer: W, formatter: F, diff --git a/src/serialize/mod.rs b/src/serialize/mod.rs index 268e5627..9bb4d93c 100644 --- a/src/serialize/mod.rs +++ b/src/serialize/mod.rs @@ -9,7 +9,6 @@ mod dict; mod error; mod float; mod int; -mod json; mod list; mod numpy; mod pyenum; @@ -19,4 +18,7 @@ mod tuple; mod uuid; mod writer; +#[cfg(not(target_os = "windows"))] +mod json; + pub use serializer::serialize; diff --git a/src/serialize/serializer.rs b/src/serialize/serializer.rs index 0287f213..2cbf5c2e 100644 --- a/src/serialize/serializer.rs +++ b/src/serialize/serializer.rs @@ -21,6 +21,12 @@ use serde::ser::{Serialize, SerializeMap, Serializer}; use std::io::Write; use std::ptr::NonNull; +#[cfg(target_os = "windows")] +use serde_json::{to_writer, to_writer_pretty}; + +#[cfg(not(target_os = "windows"))] +use crate::serialize::json::{to_writer, to_writer_pretty}; + pub const RECURSION_LIMIT: u8 = 255; pub fn serialize( @@ -31,9 +37,9 @@ pub fn serialize( let mut buf = BytesWriter::default(); let obj = PyObjectSerializer::new(ptr, opts, 0, 0, default); let res = if opts & INDENT_2 != INDENT_2 { - crate::serialize::json::to_writer(&mut buf, &obj) + to_writer(&mut buf, &obj) } else { - crate::serialize::json::to_writer_pretty(&mut buf, &obj) + to_writer_pretty(&mut buf, &obj) }; match res { Ok(_) => { diff --git a/src/serialize/writer.rs b/src/serialize/writer.rs index 1e8c0f60..09a6cb25 100644 --- a/src/serialize/writer.rs +++ b/src/serialize/writer.rs @@ -1,7 +1,6 @@ // SPDX-License-Identifier: (Apache-2.0 OR MIT) use crate::ffi::PyBytesObject; -use crate::serialize::json::WriteExt; use pyo3_ffi::*; use std::os::raw::c_char; use std::ptr::NonNull; @@ -94,6 +93,59 @@ impl std::io::Write for BytesWriter { } } +#[allow(dead_code)] +// hack based on saethlin's research and patch in https://github.com/serde-rs/json/issues/766 +pub trait WriteExt: std::io::Write { + #[inline] + fn as_mut_buffer_ptr(&mut self) -> *mut u8 { + std::ptr::null_mut() + } + + #[inline] + fn reserve(&mut self, len: usize) { + let _ = len; + } + + #[inline] + fn set_written(&mut self, len: usize) { + let _ = len; + } + + #[inline] + fn write_str(&mut self, val: &str) -> std::result::Result<(), std::io::Error> { + let _ = val; + Ok(()) + } + + #[inline] + unsafe fn write_reserved_fragment( + &mut self, + val: &[u8], + ) -> std::result::Result<(), std::io::Error> { + let _ = val; + Ok(()) + } + + #[inline] + unsafe fn write_reserved_punctuation( + &mut self, + val: u8, + ) -> std::result::Result<(), std::io::Error> { + let _ = val; + Ok(()) + } + + #[inline] + unsafe fn write_reserved_indent( + &mut self, + len: usize, + ) -> std::result::Result<(), std::io::Error> { + let _ = len; + Ok(()) + } +} + +#[allow(dead_code)] impl WriteExt for &mut BytesWriter { #[inline(always)] fn as_mut_buffer_ptr(&mut self) -> *mut u8 { diff --git a/test/test_issue331.py b/test/test_issue331.py new file mode 100644 index 00000000..1f2cda1e --- /dev/null +++ b/test/test_issue331.py @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +import orjson + +from .util import read_fixture_bytes + +def test_issue331_1(): + as_bytes = read_fixture_bytes("issue331_1.json.xz") + as_obj = orjson.loads(as_bytes) + for i in range(1000): + assert orjson.loads(orjson.dumps(as_obj)) == as_obj + +def test_issue331_2(): + as_bytes = read_fixture_bytes("issue331_2.json.xz") + as_obj = orjson.loads(as_bytes) + for i in range(1000): + assert orjson.loads(orjson.dumps(as_obj)) == as_obj