diff --git a/json/bench/Cargo.toml b/json/bench/Cargo.toml index 4852e7f6..2e45284e 100644 --- a/json/bench/Cargo.toml +++ b/json/bench/Cargo.toml @@ -28,7 +28,7 @@ features = ["std"] [dependencies.sval_serde] path = "../../serde" -features = ["std"] +default-features = false [dependencies.serde] version = "1" @@ -40,7 +40,7 @@ version = "1" version = "1" [dependencies.erased-serde] -version = "0.3" +version = "0.4" [dependencies.miniserde] version = "0.1" diff --git a/nested/src/flat.rs b/nested/src/flat.rs index 337e42f2..cfdc7906 100644 --- a/nested/src/flat.rs +++ b/nested/src/flat.rs @@ -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(&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) @@ -192,7 +192,7 @@ impl<'sval, S: Stream<'sval>> sval::Stream<'sval> for FlatStream<'sval, S> { fn value_computed(&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) diff --git a/nested/src/lib.rs b/nested/src/lib.rs index 2fa3e2e4..c2168fe6 100644 --- a/nested/src/lib.rs +++ b/nested/src/lib.rs @@ -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::).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!( @@ -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!( @@ -1617,6 +1676,29 @@ mod tests { ); } + #[test] + #[cfg(feature = "alloc")] + fn stream_number() { + struct Number(N); + + impl sval::Value for Number { + 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() { diff --git a/serde/src/to_serialize.rs b/serde/src/to_serialize.rs index c12d9e12..968a32ed 100644 --- a/serde/src/to_serialize.rs +++ b/serde/src/to_serialize.rs @@ -42,7 +42,7 @@ impl ToSerialize { impl serde::Serialize for ToSerialize { fn serialize(&self, serializer: S) -> Result { Serializer::new(serializer) - .value_computed(&self.0) + .value_ref(&self.0) .unwrap_or_else(|e| Err(S::Error::custom(e))) } } @@ -180,7 +180,9 @@ impl<'sval, S: serde::Serializer> Stream<'sval> for Serializer { _ => { 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)) } @@ -201,7 +203,9 @@ impl<'sval, S: serde::Serializer> Stream<'sval> for Serializer { _ => { 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 @@ -234,9 +238,9 @@ impl<'sval, S: serde::Serializer> Stream<'sval> for Serializer { 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 @@ -266,9 +270,9 @@ impl<'sval, S: serde::Serializer> Stream<'sval> for Serializer { 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 @@ -491,11 +495,13 @@ impl<'sval, S: serde::Serializer> StreamEnum<'sval> for SerializeEnum { ) -> sval_nested::Result { 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 @@ -511,11 +517,13 @@ impl<'sval, S: serde::Serializer> StreamEnum<'sval> for SerializeEnum { ) -> sval_nested::Result { 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, @@ -534,14 +542,16 @@ impl<'sval, S: serde::Serializer> StreamEnum<'sval> for SerializeEnum { ) -> sval_nested::Result { 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( @@ -562,14 +572,16 @@ impl<'sval, S: serde::Serializer> StreamEnum<'sval> for SerializeEnum { ) -> sval_nested::Result { 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( @@ -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)) { diff --git a/src/data/number.rs b/src/data/number.rs index 85fa87e9..107e1910 100644 --- a/src/data/number.rs +++ b/src/data/number.rs @@ -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,)*) => { @@ -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); - - impl<'a, S: Stream<'a>> fmt::Write for Writer { - 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) } diff --git a/src/data/seq.rs b/src/data/seq.rs index 6ab261d2..b917d4fe 100644 --- a/src/data/seq.rs +++ b/src/data/seq.rs @@ -17,15 +17,7 @@ impl Value for [T] { impl 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) } } diff --git a/src/stream.rs b/src/stream.rs index a12823c3..8e8efe6b 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -780,6 +780,11 @@ impl Computed { } impl<'a, 'b, S: Stream<'a> + ?Sized> Stream<'b> for Computed { + #[inline] + fn value(&mut self, v: &'b V) -> Result { + default_stream::value(self, v) + } + #[inline] fn value_computed(&mut self, v: &V) -> Result { self.0.value_computed(v)