From 9c42a689f15c18b004ca782e894cd7fa59748746 Mon Sep 17 00:00:00 2001 From: liuq19 Date: Thu, 11 Jan 2024 11:40:14 +0800 Subject: [PATCH] fix: add default, debug, diplay for lazyvalue --- examples/lazyvalue.rs | 27 ++++++-- fuzz/fuzz_targets/from_slice.rs | 2 + src/format.rs | 2 + src/lazyvalue/mod.rs | 2 + src/lazyvalue/owned.rs | 105 +++++++++++++++++++++----------- src/lazyvalue/value.rs | 25 +++++++- src/lib.rs | 2 +- src/serde/mod.rs | 2 + src/util/simd/mod.rs | 1 + src/util/simd/neon.rs | 2 +- src/value/array.rs | 1 + src/value/mod.rs | 7 ++- src/value/object.rs | 1 + src/value/tls_buffer.rs | 2 +- src/value/value_trait.rs | 1 + src/writer.rs | 6 +- 16 files changed, 137 insertions(+), 51 deletions(-) diff --git a/examples/lazyvalue.rs b/examples/lazyvalue.rs index f9761d0..edfa6b3 100644 --- a/examples/lazyvalue.rs +++ b/examples/lazyvalue.rs @@ -1,15 +1,30 @@ use serde::{Deserialize, Serialize}; +use serde_json::value::RawValue; use sonic_rs::{LazyValue, OwnedLazyValue}; fn main() { - #[derive(Debug, Deserialize, Serialize, PartialEq)] + let input = r#"{ "borrowed": "hello", "owned": "world" }"#; + + // use sonic_rs + #[derive(Debug, Deserialize, Serialize)] struct TestLazyValue<'a> { #[serde(borrow)] - borrowed_lv: LazyValue<'a>, - owned_lv: OwnedLazyValue, + borrowed: LazyValue<'a>, + owned: OwnedLazyValue, } - let input = r#"{ "borrowed_lv": "hello", "owned_lv": "world" }"#; let data: TestLazyValue = sonic_rs::from_str(input).unwrap(); - assert_eq!(data.borrowed_lv.as_raw_str(), "\"hello\""); - assert_eq!(data.owned_lv.as_raw_str(), "\"world\""); + assert_eq!(data.borrowed.as_raw_str(), "\"hello\""); + assert_eq!(data.owned.as_raw_str(), "\"world\""); + + // use serde_json + #[derive(Debug, Deserialize, Serialize)] + struct TestRawValue<'a> { + #[serde(borrow)] + borrowed: &'a RawValue, + owned: Box, + } + + let data: TestRawValue = serde_json::from_str(input).unwrap(); + assert_eq!(data.borrowed.get(), "\"hello\""); + assert_eq!(data.owned.get(), "\"world\""); } diff --git a/fuzz/fuzz_targets/from_slice.rs b/fuzz/fuzz_targets/from_slice.rs index da2f802..634ff06 100644 --- a/fuzz/fuzz_targets/from_slice.rs +++ b/fuzz/fuzz_targets/from_slice.rs @@ -103,6 +103,8 @@ fuzz_target!(|data: &[u8]| { test_struct!(Enum, data); test_struct!(String, data); test_struct!(f64, data); + test_struct!(u64, data); + test_struct!(i64, data); }); fn compare_lazyvalue(jv: &JValue, sv: &sonic_rs::LazyValue) { diff --git a/src/format.rs b/src/format.rs index a03e156..3d37da4 100644 --- a/src/format.rs +++ b/src/format.rs @@ -1,3 +1,5 @@ +//! Formtter for JSON serialization. + // The code is cloned from [serde_json](https://github.com/serde-rs/json) and modified necessary parts. use std::io::{self, Write}; diff --git a/src/lazyvalue/mod.rs b/src/lazyvalue/mod.rs index ad032c5..dc86f0a 100644 --- a/src/lazyvalue/mod.rs +++ b/src/lazyvalue/mod.rs @@ -1,3 +1,5 @@ +//! A lazy type to representing a unparsed raw JSON text for lazy operators. + mod get; mod iterator; mod owned; diff --git a/src/lazyvalue/owned.rs b/src/lazyvalue/owned.rs index f88251e..321282c 100644 --- a/src/lazyvalue/owned.rs +++ b/src/lazyvalue/owned.rs @@ -1,4 +1,10 @@ -use std::{hash::Hash, str::from_utf8_unchecked, sync::Arc}; +use std::{ + fmt, + fmt::{Debug, Display}, + hash::Hash, + str::from_utf8_unchecked, + sync::Arc, +}; use faststr::FastStr; @@ -11,6 +17,8 @@ use crate::{ /// /// It can be converted from [`LazyValue`](crate::lazyvalue::LazyValue). It can be used for serde. /// +/// Default value is a raw JSON text `null`. +/// /// # Examples /// /// ``` @@ -58,48 +66,12 @@ use crate::{ /// assert_eq!(data.borrowed_lv.as_raw_str(), "\"hello\""); /// assert_eq!(data.owned_lv.as_raw_str(), "\"world\""); /// ``` -#[derive(Debug)] pub struct OwnedLazyValue { // the raw slice from origin json pub(crate) raw: FastStr, unescape: Option>, } -impl PartialEq for OwnedLazyValue { - fn eq(&self, other: &Self) -> bool { - self.raw == other.raw - } -} - -impl Clone for OwnedLazyValue { - fn clone(&self) -> Self { - Self { - raw: self.raw.clone(), - unescape: self.unescape.clone(), - } - } -} - -impl PartialOrd for OwnedLazyValue { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for OwnedLazyValue { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.raw.cmp(&other.raw) - } -} - -impl Eq for OwnedLazyValue {} - -impl Hash for OwnedLazyValue { - fn hash(&self, state: &mut H) { - self.raw.hash(state) - } -} - impl JsonValueTrait for OwnedLazyValue { type ValueType<'v> = OwnedLazyValue; @@ -247,3 +219,62 @@ impl<'de> From> for OwnedLazyValue { } } } + +impl Debug for OwnedLazyValue { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_tuple("OwnedLazyValue") + .field(&format_args!("{}", &self.as_raw_str())) + .finish() + } +} + +impl Display for OwnedLazyValue { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.as_raw_str()) + } +} + +impl Default for OwnedLazyValue { + fn default() -> Self { + Self { + raw: FastStr::new("null"), + unescape: None, + } + } +} + +impl PartialEq for OwnedLazyValue { + fn eq(&self, other: &Self) -> bool { + self.raw == other.raw + } +} + +impl Clone for OwnedLazyValue { + fn clone(&self) -> Self { + Self { + raw: self.raw.clone(), + unescape: self.unescape.clone(), + } + } +} + +impl PartialOrd for OwnedLazyValue { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for OwnedLazyValue { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.raw.cmp(&other.raw) + } +} + +impl Eq for OwnedLazyValue {} + +impl Hash for OwnedLazyValue { + fn hash(&self, state: &mut H) { + self.raw.hash(state) + } +} diff --git a/src/lazyvalue/value.rs b/src/lazyvalue/value.rs index e328f06..3fe6b99 100644 --- a/src/lazyvalue/value.rs +++ b/src/lazyvalue/value.rs @@ -1,4 +1,11 @@ -use std::{borrow::Cow, hash::Hash, str::from_utf8_unchecked, sync::Arc}; +use std::{ + borrow::Cow, + fmt, + fmt::{Debug, Display}, + hash::Hash, + str::from_utf8_unchecked, + sync::Arc, +}; use faststr::FastStr; @@ -59,7 +66,6 @@ use crate::{ /// let data: TestLazyValue = sonic_rs::from_str(input).unwrap(); /// assert_eq!(data.borrowed_lv.as_raw_str(), "\"hello\""); /// ``` -#[derive(Debug)] pub struct LazyValue<'a> { // the raw slice from origin json pub(crate) raw: JsonSlice<'a>, @@ -75,6 +81,21 @@ impl Default for LazyValue<'_> { } } +impl<'a> Debug for LazyValue<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_tuple("LazyValue") + .field(&format_args!("{}", &self.as_raw_str())) + .finish() + } +} + +impl<'a> Display for LazyValue<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.as_raw_str()) + } +} + impl PartialEq for LazyValue<'_> { fn eq(&self, other: &Self) -> bool { self.raw.as_ref() == other.raw.as_ref() diff --git a/src/lib.rs b/src/lib.rs index 7ce8db5..09beed6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ #![doc(test(attr(warn(unused))))] mod error; +mod index; mod input; mod parser; mod pointer; @@ -10,7 +11,6 @@ mod reader; mod util; pub mod format; -pub mod index; pub mod lazyvalue; pub mod serde; pub mod value; diff --git a/src/serde/mod.rs b/src/serde/mod.rs index e161d2b..922be43 100644 --- a/src/serde/mod.rs +++ b/src/serde/mod.rs @@ -1,3 +1,5 @@ +//! Serde between JSON text and Rust data structure. + mod de; pub(crate) mod number; pub(crate) mod rawnumber; diff --git a/src/util/simd/mod.rs b/src/util/simd/mod.rs index 90eaa15..2c05b75 100644 --- a/src/util/simd/mod.rs +++ b/src/util/simd/mod.rs @@ -1,5 +1,6 @@ mod traits; +#[doc(hidden)] #[macro_export] macro_rules! impl_lanes { ($simd: ty, $lane: expr) => { diff --git a/src/util/simd/neon.rs b/src/util/simd/neon.rs index ea4425b..2ce385c 100644 --- a/src/util/simd/neon.rs +++ b/src/util/simd/neon.rs @@ -101,7 +101,7 @@ impl Mask for Mask128 { #[inline(always)] fn bitmask(self) -> Self::BitMap { // TODO: optimize bitmask like this - // neon doesn't have instrution same as movemask, to_bitmask uses shrn to + // neon doesn't have instruction same as movemask, to_bitmask uses shrn to // reduce 128bits -> 64bits. If a 128bits bool vector in x86 can convert // as 0101, neon shrn will convert it as 0000111100001111. // unsafe { diff --git a/src/value/array.rs b/src/value/array.rs index 220a1f7..a71dbd8 100644 --- a/src/value/array.rs +++ b/src/value/array.rs @@ -1,3 +1,4 @@ +//! Represents a parsed JSON array. Its APIs are likes `Vec`. use std::{ fmt::Debug, iter::FusedIterator, diff --git a/src/value/mod.rs b/src/value/mod.rs index 1d55858..5a5cb0d 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -1,8 +1,11 @@ +//! A dynamic type to representing any valid JSON value. + mod allocator; pub mod array; pub(crate) mod de; mod from; pub(crate) mod node; +#[doc(hidden)] pub mod shared; mod tryfrom; #[macro_use] @@ -23,7 +26,9 @@ pub use self::node::{Value, ValueRef}; #[doc(inline)] pub use self::object::Object; #[doc(inline)] -pub use self::ser::{to_value, to_value_in}; +pub use self::ser::to_value; +#[doc(hidden)] +pub use self::ser::to_value_in; #[doc(inline)] pub use self::value_trait::{JsonContainerTrait, JsonType, JsonValueMutTrait, JsonValueTrait}; diff --git a/src/value/object.rs b/src/value/object.rs index 9786d95..9f2d871 100644 --- a/src/value/object.rs +++ b/src/value/object.rs @@ -1,3 +1,4 @@ +//! Represents a parsed JSON object. use std::marker::PhantomData; use super::{ diff --git a/src/value/tls_buffer.rs b/src/value/tls_buffer.rs index ad5e3da..6727be1 100644 --- a/src/value/tls_buffer.rs +++ b/src/value/tls_buffer.rs @@ -11,7 +11,7 @@ thread_local! { static NODE_BUF: std::cell::RefCell>> = std::cell::RefCell::new(Vec::new()); } -/// A thread-local buffer for temporary nodes. Avoid allocating temporay memory multiple times. +/// A thread-local buffer for temporary nodes. Avoid allocating temporary memory multiple times. pub struct TlsBuf { buf: NonNull>>, need_drop: bool, diff --git a/src/value/value_trait.rs b/src/value/value_trait.rs index 07f462b..dcc67b1 100644 --- a/src/value/value_trait.rs +++ b/src/value/value_trait.rs @@ -37,6 +37,7 @@ impl From for JsonType { } /// A trait for all JSON values. Used by `Value` and `LazyValue`. +/// /// The `Option` and `Result` also implement this trait. /// The `Option::None` or `Result::Err(_)` will be viewed as a null value. pub trait JsonValueTrait { diff --git a/src/writer.rs b/src/writer.rs index 2def9a6..bfa5026 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -1,4 +1,6 @@ -use std::{io, io::BufWriter, mem::MaybeUninit, slice::from_raw_parts_mut}; +//! Extend trait from io::Write for JSON serializing. + +use std::{io, io::BufWriter as IoBufWriter, mem::MaybeUninit, slice::from_raw_parts_mut}; use bytes::{buf::Writer, BytesMut}; @@ -56,7 +58,7 @@ impl WriteExt for Writer { } } -impl WriteExt for BufWriter { +impl WriteExt for IoBufWriter { fn reserve_with(&mut self, additional: usize) -> io::Result<&mut [MaybeUninit]> { self.get_mut().reserve_with(additional) }