Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions simd-json-derive-int/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl Parse for FieldAttrs {
other => {
return Err(syn::Error::new(
attr.span(),
format!("unexpected attribute `{}`", other),
format!("unexpected attribute `{other}`"),
))
}
}
Expand Down Expand Up @@ -114,7 +114,7 @@ impl Parse for StructAttrs {
other => {
return Err(syn::Error::new(
attr.span(),
format!("unexpected rename_all type `{}`", other),
format!("unexpected rename_all type `{other}`"),
))
}
}
Expand All @@ -125,7 +125,7 @@ impl Parse for StructAttrs {
other => {
return Err(syn::Error::new(
attr.span(),
format!("unexpected field attribute `{}`", other),
format!("unexpected field attribute `{other}`",),
))
}
}
Expand Down
2 changes: 1 addition & 1 deletion simd-json-derive-int/src/serialize/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub(crate) fn derive(
(
&v.ident,
(0..v.fields.len())
.map(|i| Ident::new(&format!("v{}", i), Span::call_site()))
.map(|i| Ident::new(&format!("v{i}"), Span::call_site()))
.collect::<Vec<_>>(),
),
format!(
Expand Down
4 changes: 2 additions & 2 deletions simd-json-derive-int/src/serialize/struct/named.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ pub(crate) fn derive(
}
let expanded = if skip_if.iter().all(Option::is_none) {
if let Some((first, rest)) = keys.split_first_mut() {
*first = format!("{{{}", first);
*first = format!("{{{first}");
for r in rest {
*r = format!(",{}", r);
*r = format!(",{r}");
}
};

Expand Down
30 changes: 30 additions & 0 deletions src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,33 @@ pub enum Error {
expected(possible_field_names)
)]
UnknownField {
/// Unknown field that was encountered
unknown_field: String,
/// Possible fields that are expected
possible_field_names: &'static [&'static str],
},
/// unnamed enum field is not an array
#[error("unnamed enum field `{0}` is not an array")]
FieldNotAnArray(&'static str),
/// unknwon enum variant
#[error("unknwon enum variant `{0}`")]
UnknownEnumVariant(String),
/// invalid enum representation, needs to be either a string or an object
#[error("invalid enum representation, needs to be either a string or an object")]
InvalidEnumRepresentation,
/// invalid struct representation, needs to be an object
#[error("invalid struct representation, needs to be an object")]
InvalidStructRepresentation,
/// Unexpected e,nd of input
#[error("Unexpected e,nd of input")]
EOF,
/// Invalid integer number
#[error("Invalid integer number")]
InvalidNumber(#[from] TryFromIntError),
/// Custom error
#[error("Custom error: {0}")]
Custom(String),
/// The universe is broken
#[error("The universe is broken: {0}")]
BrokenUniverse(#[from] std::convert::Infallible),
}
Expand All @@ -58,43 +68,58 @@ impl Error {
Error::Custom(msg.to_string())
}
/// Expected String error
#[must_use]
pub const fn expected_string() -> Self {
Error::Json(simd_json::ErrorType::ExpectedString)
}
/// Expected Map error
#[must_use]
pub const fn expected_map() -> Self {
Error::Json(simd_json::ErrorType::ExpectedMap)
}
/// Expected Array error
#[must_use]
pub const fn expected_array() -> Self {
Error::Json(simd_json::ErrorType::ExpectedArray)
}
/// Expected Float error
#[must_use]
pub const fn expected_float() -> Self {
Error::Json(simd_json::ErrorType::ExpectedFloat)
}
/// Expected Null error
#[must_use]
pub fn expected_null() -> Self {
Error::Json(simd_json::ErrorType::ExpectedNull)
}
/// Expected Integer error
#[must_use]
pub fn expected_integer() -> Self {
Error::Json(simd_json::ErrorType::ExpectedInteger)
}
/// Expected Boolean error
#[must_use]
pub fn expected_boolean() -> Self {
Error::Json(simd_json::ErrorType::ExpectedBoolean)
}
}

// Deserialisation result
/// Deserializer result
pub type Result<T> = std::result::Result<T, Error>;

/// Deserialisation trait for simd-json
pub trait Deserialize<'input> {
/// Deserializes from a tape
/// # Errors
/// if deserialisation fails
fn from_tape(tape: &mut Tape<'input>) -> Result<Self>
where
Self: Sized + 'input;

/// Deserializes from a u8 slice
/// # Errors
/// if deserialisation fails
#[inline]
fn from_slice(json: &'input mut [u8]) -> Result<Self>
where
Expand All @@ -105,6 +130,9 @@ pub trait Deserialize<'input> {
Self::from_tape(&mut itr)
}

/// Deserializes from a u8 slice using pre-allocated buffers
/// # Errors
/// if deserialisation fails
#[inline]
fn from_slice_with_buffers(json: &'input mut [u8], buffers: &mut Buffers) -> Result<Self>
where
Expand All @@ -116,6 +144,8 @@ pub trait Deserialize<'input> {
}

#[inline]
/// # Errors
/// if deserialisation fails
/// # Safety
///
/// user must not use the string afterwards
Expand Down
2 changes: 1 addition & 1 deletion src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod primitives;
mod simdjson;
mod string;
mod tpl;
use crate::{de, *};
use crate::{de, io, Deserialize, DummyGenerator, Serialize, Tape, Write};
use value_trait::generator::BaseGenerator;

impl<T> Serialize for Option<T>
Expand Down
25 changes: 14 additions & 11 deletions src/impls/array.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::*;
use crate::{de, io, Deserialize, Node, Serialize, Tape, Write};
use std::mem::MaybeUninit;
use std::ptr;

Expand Down Expand Up @@ -27,8 +27,10 @@ impl<T, const N: usize> Drop for Guard<'_, T, N> {

// SAFETY: this slice will contain only initialized objects.
unsafe {
let slice =
ptr::slice_from_raw_parts_mut(self.array.as_mut_ptr() as *mut T, self.initialized);
let slice = ptr::slice_from_raw_parts_mut(
self.array.as_mut_ptr().cast::<T>(),
self.initialized,
);
ptr::drop_in_place(slice);
}
}
Expand All @@ -52,6 +54,7 @@ where

if N == 0 {
// Safety: N is 0, and so *const [T; N] is *const [T; 0]
#[allow(clippy::ref_as_ptr)]
return Ok(unsafe { ptr::read((&[]) as *const [T; N]) });
}

Expand Down Expand Up @@ -116,10 +119,10 @@ mod test {
#[test]
fn arr() {
let s: [u8; 0] = [];
assert_eq!(s.json_string().unwrap(), "[]");
assert_eq!([1].json_string().unwrap(), "[1]");
assert_eq!([1, 2].json_string().unwrap(), "[1,2]");
assert_eq!([1, 2, 3].json_string().unwrap(), "[1,2,3]");
assert_eq!(s.json_string().expect("invalid "), "[]");
assert_eq!([1].json_string().expect("invalid "), "[1]");
assert_eq!([1, 2].json_string().expect("invalid "), "[1,2]");
assert_eq!([1, 2, 3].json_string().expect("invalid "), "[1,2,3]");
}
#[test]
fn arr2() {
Expand All @@ -143,9 +146,9 @@ mod test {
#[test]
fn slice() {
let s: [u8; 0] = [];
assert_eq!(s.json_string().unwrap(), "[]");
assert_eq!([1].json_string().unwrap(), "[1]");
assert_eq!([1, 2].json_string().unwrap(), "[1,2]");
assert_eq!([1, 2, 3].json_string().unwrap(), "[1,2,3]");
assert_eq!(s.json_string().expect("invalid data"), "[]");
assert_eq!([1].json_string().expect("invalid data"), "[1]");
assert_eq!([1, 2].json_string().expect("invalid data"), "[1,2]");
assert_eq!([1, 2, 3].json_string().expect("invalid data"), "[1,2,3]");
}
}
2 changes: 1 addition & 1 deletion src/impls/chrono.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{BaseGenerator, DummyGenerator};
use crate::*;
use crate::{de, Deserialize, Serialize, Tape, Write};
use chrono::{DateTime, FixedOffset, TimeZone};
use std::{fmt, io};

Expand Down
22 changes: 11 additions & 11 deletions src/impls/collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ where
if let Some(simd_json::Node::Array { len, .. }) = tape.next() {
let mut v = collections::VecDeque::new();
for _ in 0..len {
v.push_back(T::from_tape(tape)?)
v.push_back(T::from_tape(tape)?);
}
Ok(v)
} else {
Expand All @@ -95,7 +95,7 @@ where
if let Some(simd_json::Node::Array { len, .. }) = tape.next() {
let mut v = collections::BinaryHeap::new();
for _ in 0..len {
v.push(T::from_tape(tape)?)
v.push(T::from_tape(tape)?);
}
Ok(v)
} else {
Expand Down Expand Up @@ -349,33 +349,33 @@ mod test {
#[test]
fn vec() {
let mut v: Vec<u8> = Vec::new();
assert_eq!(v.json_string().unwrap(), "[]");
assert_eq!(v.json_string().expect("invalid data"), "[]");

v.push(1);
let mut s = v.json_string().unwrap();
let mut s = v.json_string().expect("invalid data");
assert_eq!(s, "[1]");
let s: Vec<u8> = unsafe { Vec::from_str(s.as_mut_str()) }.unwrap();
let s: Vec<u8> = unsafe { Vec::from_str(s.as_mut_str()) }.expect("invalid data");
assert_eq!(s, v);

v.push(2);
let mut s = v.json_string().unwrap();
let mut s = v.json_string().expect("invalid test data");
assert_eq!(s, "[1,2]");
let s: Vec<u8> = unsafe { Vec::from_str(s.as_mut_str()) }.unwrap();
let s: Vec<u8> = unsafe { Vec::from_str(s.as_mut_str()) }.expect("invalid test data");
assert_eq!(s, v);

v.push(3);
let mut s = v.json_string().unwrap();
let mut s = v.json_string().expect("invalid test data");
assert_eq!(s, "[1,2,3]");
let s: Vec<u8> = unsafe { Vec::from_str(s.as_mut_str()) }.unwrap();
let s: Vec<u8> = unsafe { Vec::from_str(s.as_mut_str()) }.expect("invalid test data");
assert_eq!(s, v);
}

#[test]
fn range() {
let r = 1..42;
let mut v = r.json_vec().unwrap();
let mut v = r.json_vec().expect("invalid test data");
assert_eq!(br#"{"start":1,"end":42}"#, v.as_slice());
let r1 = Range::from_slice(v.as_mut_slice()).unwrap();
let r1 = Range::from_slice(v.as_mut_slice()).expect("invalid test data");
assert_eq!(r, r1);
}
}
9 changes: 6 additions & 3 deletions src/impls/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ use std::convert::TryFrom;
impl Serialize for bool {
#[inline]
fn json_write<W: Write>(&self, writer: &mut W) -> Result {
match *self {
true => writer.write_all(b"true"),
false => writer.write_all(b"false"),
if *self {
writer.write_all(b"true")
} else {
writer.write_all(b"false")
}
}
}
Expand Down Expand Up @@ -96,6 +97,7 @@ ryu!(f32);

impl<'input> Deserialize<'input> for f64 {
#[inline]
#[allow(clippy::cast_precision_loss)]
fn from_tape(tape: &mut Tape<'input>) -> de::Result<Self>
where
Self: Sized + 'input,
Expand All @@ -115,6 +117,7 @@ impl<'input> Deserialize<'input> for f64 {

impl<'input> Deserialize<'input> for f32 {
#[inline]
#[allow(clippy::cast_precision_loss, clippy::cast_possible_truncation)]
fn from_tape(tape: &mut Tape<'input>) -> de::Result<Self>
where
Self: Sized + 'input,
Expand Down
8 changes: 1 addition & 7 deletions src/impls/simdjson.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ impl Serialize for BorrowedValue<'_> {
struct OwnedDeser<'input, 'tape>(&'tape mut crate::Tape<'input>);

impl OwnedDeser<'_, '_> {
#[inline(always)]
fn parse(&mut self) -> OwnedValue {
match self.0.next() {
Some(Node::Static(s)) => OwnedValue::Static(s),
Expand All @@ -32,19 +31,17 @@ impl OwnedDeser<'_, '_> {
None => unreachable!("We have validated the tape in the second stage of parsing, this should never happen"),
}
}
#[inline(always)]
fn parse_array(&mut self, len: usize) -> OwnedValue {
let mut res: Vec<OwnedValue> = Vec::with_capacity(len);
// Rust doesn't optimize the normal loop away here
// so we write our own avoiding the length
// checks during push
for _ in 0..len {
res.push(self.parse())
res.push(self.parse());
}
OwnedValue::Array(Box::new(res))
}

#[inline(always)]
fn parse_map(&mut self, len: usize) -> OwnedValue {
let mut res = OwnedValue::object_with_capacity(len);

Expand Down Expand Up @@ -76,7 +73,6 @@ impl<'input> Deserialize<'input> for OwnedValue {
struct BorrowedDeser<'input, 'tape>(&'tape mut crate::Tape<'input>);

impl<'input> BorrowedDeser<'input, '_> {
#[inline(always)]
fn parse(&mut self) -> BorrowedValue<'input> {
match self.0.next() {
Some(Node::Static(s)) => BorrowedValue::Static(s),
Expand All @@ -86,7 +82,6 @@ impl<'input> BorrowedDeser<'input, '_> {
None => unreachable!("We have validated the tape in the second stage of parsing, this should never happen"),
}
}
#[inline(always)]
fn parse_array(&mut self, len: usize) -> BorrowedValue<'input> {
let mut res: Vec<BorrowedValue<'input>> = Vec::with_capacity(len);
for _ in 0..len {
Expand All @@ -95,7 +90,6 @@ impl<'input> BorrowedDeser<'input, '_> {
BorrowedValue::Array(Box::new(res))
}

#[inline(always)]
fn parse_map(&mut self, len: usize) -> BorrowedValue<'input> {
let mut res = BorrowedValue::object_with_capacity(len);

Expand Down
9 changes: 6 additions & 3 deletions src/impls/tpl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,11 @@ mod test {

#[test]
fn tpl() {
assert_eq!((1).json_string().unwrap(), "1");
assert_eq!((1, 2).json_string().unwrap(), "[1,2]");
assert_eq!((1, 2, 3).json_string().unwrap(), "[1,2,3]");
assert_eq!((1).json_string().expect("invalid test data"), "1");
assert_eq!((1, 2).json_string().expect("invalid test data"), "[1,2]");
assert_eq!(
(1, 2, 3).json_string().expect("invalid test data"),
"[1,2,3]"
);
}
}
Loading
Loading