Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix buffering in new nested crate #184

Merged
merged 2 commits into from
Dec 22, 2023
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
4 changes: 2 additions & 2 deletions json/bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ features = ["std"]

[dependencies.sval_serde]
path = "../../serde"
features = ["std"]
default-features = false

[dependencies.serde]
version = "1"
Expand All @@ -40,7 +40,7 @@ version = "1"
version = "1"

[dependencies.erased-serde]
version = "0.3"
version = "0.4"

[dependencies.miniserde]
version = "0.1"
4 changes: 2 additions & 2 deletions nested/src/flat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl<'sval, S: Stream<'sval>> FlatStream<'sval, S> {
impl<'sval, S: Stream<'sval>> sval::Stream<'sval> for FlatStream<'sval, S> {
fn value<V: sval::Value + ?Sized>(&mut self, v: &'sval V) -> sval::Result {
self.buffer_or_stream_with(
|buf| buf.value(v),
|buf| sval::Stream::value(buf, v),
|stream| match stream.state {
State::Enum(_) => {
sval::default_stream::value(stream, v)
Expand All @@ -192,7 +192,7 @@ impl<'sval, S: Stream<'sval>> sval::Stream<'sval> for FlatStream<'sval, S> {

fn value_computed<V: sval::Value + ?Sized>(&mut self, v: &V) -> sval::Result {
self.buffer_or_stream_with(
|buf| buf.value_computed(v),
|buf| sval::Stream::value_computed(buf, v),
|stream| match stream.state {
State::Enum(_) => {
sval::default_stream::value_computed(stream, v)
Expand Down
82 changes: 82 additions & 0 deletions nested/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1307,6 +1307,52 @@ mod tests {
);
}

#[test]
fn stream_option() {
#[derive(Value)]
struct Inner {
a: i32,
b: bool,
}

assert_eq!(
Value::Tag(Tag::new(
Some(sval::tags::RUST_OPTION_NONE),
Some(sval::Label::new("None")),
Some(sval::Index::new(0))
)
.unwrap()),
ToValue::default().value_ref(&None::<Inner>).unwrap()
);

assert_eq!(
Value::Tagged(Tagged {
tag: Tag::new(
Some(sval::tags::RUST_OPTION_SOME),
Some(sval::Label::new("Some")),
Some(sval::Index::new(1)),
)
.unwrap(),
value: Box::new(Value::Record(Record {
tag: Tag::new(
None,
Some(sval::Label::new("Inner")),
None,
)
.unwrap(),
entries: vec![
(sval::Label::new("a"), Value::I64(42)),
(sval::Label::new("b"), Value::Bool(true)),
]
}))
}),
ToValue::default().value_ref(&Some(Inner {
a: 42,
b: true,
})).unwrap()
);
}

#[test]
fn stream_text_borrowed() {
assert_eq!(
Expand All @@ -1325,6 +1371,19 @@ mod tests {
);
}

#[test]
fn stream_array() {
assert_eq!(
Value::Tagged(Tagged {
tag: Tag::new(Some(sval::tags::CONSTANT_SIZE), None, None).unwrap(),
value: Box::new(Value::Seq(Seq {
entries: vec![Value::I64(1), Value::I64(2), Value::I64(3),]
})),
}),
ToValue::default().value_ref(&[1, 2, 3] as &[_; 3]).unwrap()
);
}

#[test]
fn stream_seq() {
assert_eq!(
Expand Down Expand Up @@ -1617,6 +1676,29 @@ mod tests {
);
}

#[test]
#[cfg(feature = "alloc")]
fn stream_number() {
struct Number<N>(N);

impl<N: std::fmt::Display> sval::Value for Number<N> {
fn stream<'sval, S: sval::Stream<'sval> + ?Sized>(
&'sval self,
stream: &mut S,
) -> sval::Result {
sval::stream_number(stream, &self.0)
}
}

assert_eq!(
Value::Tagged(Tagged {
tag: Tag::new(Some(sval::tags::NUMBER), None, None).unwrap(),
value: Box::new(Value::Text(Cow::Owned("42".into()))),
}),
ToValue::default().value_ref(&Number(42)).unwrap()
);
}

#[test]
#[cfg(feature = "alloc")]
fn stream_enum_nested_value() {
Expand Down
76 changes: 44 additions & 32 deletions serde/src/to_serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl<V: sval::Value + ?Sized> ToSerialize<V> {
impl<V: sval::Value> serde::Serialize for ToSerialize<V> {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
Serializer::new(serializer)
.value_computed(&self.0)
.value_ref(&self.0)
.unwrap_or_else(|e| Err(S::Error::custom(e)))
}
}
Expand Down Expand Up @@ -180,7 +180,9 @@ impl<'sval, S: serde::Serializer> Stream<'sval> for Serializer<S> {
_ => {
let name = label
.and_then(|label| label.as_static_str())
.ok_or_else(|| sval_nested::Error::invalid_value("unit label must be static"))?;
.ok_or_else(|| {
sval_nested::Error::invalid_value("unit label must be static")
})?;

Ok(self.serializer.serialize_unit_struct(name))
}
Expand All @@ -201,7 +203,9 @@ impl<'sval, S: serde::Serializer> Stream<'sval> for Serializer<S> {
_ => {
let name = label
.and_then(|label| label.as_static_str())
.ok_or_else(|| sval_nested::Error::invalid_value("newtype label must be static"))?;
.ok_or_else(|| {
sval_nested::Error::invalid_value("newtype label must be static")
})?;

Ok(self
.serializer
Expand Down Expand Up @@ -234,9 +238,9 @@ impl<'sval, S: serde::Serializer> Stream<'sval> for Serializer<S> {

match label {
Some(label) => {
let name = label
.as_static_str()
.ok_or_else(|| sval_nested::Error::invalid_value("tuple label must be static"))?;
let name = label.as_static_str().ok_or_else(|| {
sval_nested::Error::invalid_value("tuple label must be static")
})?;

Ok(SerializeTuple {
serializer: self
Expand Down Expand Up @@ -266,9 +270,9 @@ impl<'sval, S: serde::Serializer> Stream<'sval> for Serializer<S> {

match label {
Some(label) => {
let name = label
.as_static_str()
.ok_or_else(|| sval_nested::Error::invalid_value("struct label must be static"))?;
let name = label.as_static_str().ok_or_else(|| {
sval_nested::Error::invalid_value("struct label must be static")
})?;

Ok(SerializeRecord {
serializer: self
Expand Down Expand Up @@ -491,11 +495,13 @@ impl<'sval, S: serde::Serializer> StreamEnum<'sval> for SerializeEnum<S> {
) -> sval_nested::Result<Self::Ok> {
let variant = label
.and_then(|label| label.as_static_str())
.ok_or_else(|| sval_nested::Error::invalid_value("unit variant label must be static"))?;
.ok_or_else(|| {
sval_nested::Error::invalid_value("unit variant label must be static")
})?;

let variant_index = index
.and_then(|index| index.to_u32())
.ok_or_else(|| sval_nested::Error::invalid_value("unit variant index must a 32bit value"))?;
let variant_index = index.and_then(|index| index.to_u32()).ok_or_else(|| {
sval_nested::Error::invalid_value("unit variant index must a 32bit value")
})?;

Ok(self
.serializer
Expand All @@ -511,11 +517,13 @@ impl<'sval, S: serde::Serializer> StreamEnum<'sval> for SerializeEnum<S> {
) -> sval_nested::Result<Self::Ok> {
let variant = label
.and_then(|label| label.as_static_str())
.ok_or_else(|| sval_nested::Error::invalid_value("newtype variant label must be static"))?;
.ok_or_else(|| {
sval_nested::Error::invalid_value("newtype variant label must be static")
})?;

let variant_index = index
.and_then(|index| index.to_u32())
.ok_or_else(|| sval_nested::Error::invalid_value("newtype variant index must be a 32bit value"))?;
let variant_index = index.and_then(|index| index.to_u32()).ok_or_else(|| {
sval_nested::Error::invalid_value("newtype variant index must be a 32bit value")
})?;

Ok(self.serializer.serialize_newtype_variant(
self.name,
Expand All @@ -534,14 +542,16 @@ impl<'sval, S: serde::Serializer> StreamEnum<'sval> for SerializeEnum<S> {
) -> sval_nested::Result<Self::Tuple> {
let variant = label
.and_then(|label| label.as_static_str())
.ok_or_else(|| sval_nested::Error::invalid_value("tuple variant label must be static"))?;
.ok_or_else(|| {
sval_nested::Error::invalid_value("tuple variant label must be static")
})?;

let variant_index = index
.and_then(|index| index.to_u32())
.ok_or_else(|| sval_nested::Error::invalid_value("tuple variant index must be a 32bit value"))?;
let variant_index = index.and_then(|index| index.to_u32()).ok_or_else(|| {
sval_nested::Error::invalid_value("tuple variant index must be a 32bit value")
})?;

let len =
num_entries.ok_or_else(|| sval_nested::Error::invalid_value("missing tuple variant len"))?;
let len = num_entries
.ok_or_else(|| sval_nested::Error::invalid_value("missing tuple variant len"))?;

Ok(SerializeTupleVariant {
serializer: self.serializer.serialize_tuple_variant(
Expand All @@ -562,14 +572,16 @@ impl<'sval, S: serde::Serializer> StreamEnum<'sval> for SerializeEnum<S> {
) -> sval_nested::Result<Self::Record> {
let variant = label
.and_then(|label| label.as_static_str())
.ok_or_else(|| sval_nested::Error::invalid_value("struct variant label must be static"))?;
.ok_or_else(|| {
sval_nested::Error::invalid_value("struct variant label must be static")
})?;

let variant_index = index
.and_then(|index| index.to_u32())
.ok_or_else(|| sval_nested::Error::invalid_value("struct variant index must be a 32bit value"))?;
let variant_index = index.and_then(|index| index.to_u32()).ok_or_else(|| {
sval_nested::Error::invalid_value("struct variant index must be a 32bit value")
})?;

let len =
num_entries.ok_or_else(|| sval_nested::Error::invalid_value("missing struct variant len"))?;
let len = num_entries
.ok_or_else(|| sval_nested::Error::invalid_value("missing struct variant len"))?;

Ok(SerializeRecordVariant {
serializer: self.serializer.serialize_struct_variant(
Expand Down Expand Up @@ -611,9 +623,9 @@ impl<'sval, S: serde::ser::SerializeStructVariant> StreamRecord<'sval>
label: sval::Label,
value: V,
) -> sval_nested::Result {
let field = label
.as_static_str()
.ok_or_else(|| sval_nested::Error::invalid_value("struct variant field label must be static"))?;
let field = label.as_static_str().ok_or_else(|| {
sval_nested::Error::invalid_value("struct variant field label must be static")
})?;

if let Ok(ref mut serializer) = self.serializer {
match serializer.serialize_field(field, &ToSerialize::new(value)) {
Expand Down
26 changes: 3 additions & 23 deletions src/data/number.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
use crate::{
std::{
fmt::{self, Write as _},
write,
},
tags, Result, Stream, Value,
};
use crate::{std::fmt, tags, Result, Stream, Value};

macro_rules! stream_default {
($($fi:ident => $i:ty, $fu:ident => $u:ty,)*) => {
Expand Down Expand Up @@ -63,25 +57,11 @@ Stream an arbitrary precision number conforming to [`tags::NUMBER`]
using its [`fmt::Display`] implementation.
*/
pub fn stream_number<'sval>(
mut stream: &mut (impl Stream<'sval> + ?Sized),
stream: &mut (impl Stream<'sval> + ?Sized),
number: impl fmt::Display,
) -> Result {
struct Writer<S>(S);

impl<'a, S: Stream<'a>> fmt::Write for Writer<S> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.0.text_fragment_computed(s).map_err(|_| fmt::Error)?;

Ok(())
}
}

stream.tagged_begin(Some(&tags::NUMBER), None, None)?;
stream.text_begin(None)?;

write!(Writer(&mut stream), "{}", number).map_err(|_| crate::Error::new())?;

stream.text_end()?;
stream.value_computed(&crate::Display::new(number))?;
stream.tagged_end(Some(&tags::NUMBER), None, None)
}

Expand Down
10 changes: 1 addition & 9 deletions src/data/seq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,7 @@ impl<T: Value> Value for [T] {
impl<T: Value, const N: usize> Value for [T; N] {
fn stream<'a, S: Stream<'a> + ?Sized>(&'a self, stream: &mut S) -> Result {
stream.tagged_begin(Some(&tags::CONSTANT_SIZE), None, None)?;
stream.seq_begin(Some(self.len()))?;

for elem in self {
stream.seq_value_begin()?;
stream.value(elem)?;
stream.seq_value_end()?;
}

stream.seq_end()?;
stream.value(self as &'a [T])?;
stream.tagged_end(Some(&tags::CONSTANT_SIZE), None, None)
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,11 @@ impl<S: ?Sized> Computed<S> {
}

impl<'a, 'b, S: Stream<'a> + ?Sized> Stream<'b> for Computed<S> {
#[inline]
fn value<V: Value + ?Sized>(&mut self, v: &'b V) -> Result {
default_stream::value(self, v)
}

#[inline]
fn value_computed<V: Value + ?Sized>(&mut self, v: &V) -> Result {
self.0.value_computed(v)
Expand Down