From 338ef0e4fb66a9b15835c83a7a72290529570de1 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Wed, 20 Dec 2023 14:04:26 +1000 Subject: [PATCH] use ValueRef in buffering Stream trait --- buffer/src/stream.rs | 343 ++++++++++++++++++++++++--------- buffer/src/stream/flat.rs | 27 +-- buffer/src/stream/flat_enum.rs | 40 ++-- ref/src/lib.rs | 59 ++++++ serde/src/to_serialize.rs | 32 +-- 5 files changed, 360 insertions(+), 141 deletions(-) diff --git a/buffer/src/stream.rs b/buffer/src/stream.rs index 70c2b7b0..ea3fc272 100644 --- a/buffer/src/stream.rs +++ b/buffer/src/stream.rs @@ -20,14 +20,21 @@ pub trait Stream<'sval> { type Enum: StreamEnum<'sval, Ok = Self::Ok>; - fn value(self, value: &'sval V) -> Result + fn value>(self, value: V) -> Result where Self: Sized, { default_stream::value(self, value) } - fn value_computed(self, value: &V) -> Result + fn value_ref(self, value: &'sval V) -> Result + where + Self: Sized, + { + default_stream::value_ref(self, value) + } + + fn value_computed(self, value: V) -> Result where Self: Sized, { @@ -142,7 +149,20 @@ pub trait Stream<'sval> { index: Option, ) -> Result; - fn tagged( + fn tagged>( + self, + tag: Option, + label: Option, + index: Option, + value: V, + ) -> Result + where + Self: Sized, + { + default_stream::tagged(self, tag, label, index, value) + } + + fn tagged_ref( self, tag: Option, label: Option, @@ -152,15 +172,15 @@ pub trait Stream<'sval> { where Self: Sized, { - self.tagged_computed(tag, label, index, value) + default_stream::tagged_ref(self, tag, label, index, value) } - fn tagged_computed( + fn tagged_computed( self, tag: Option, label: Option, index: Option, - value: &V, + value: V, ) -> Result; fn seq_begin(self, num_entries: Option) -> Result; @@ -194,11 +214,15 @@ pub trait Stream<'sval> { pub trait StreamSeq<'sval> { type Ok; - fn value(&mut self, value: &'sval V) -> Result { + fn value>(&mut self, value: V) -> Result { default_stream::seq_value(self, value) } - fn value_computed(&mut self, value: &V) -> Result; + fn value_ref(&mut self, value: &'sval V) -> Result { + default_stream::seq_value_ref(self, value) + } + + fn value_computed(&mut self, value: V) -> Result; fn end(self) -> Result; } @@ -206,17 +230,25 @@ pub trait StreamSeq<'sval> { pub trait StreamMap<'sval> { type Ok; - fn key(&mut self, key: &'sval V) -> Result { + fn key>(&mut self, key: V) -> Result { default_stream::map_key(self, key) } - fn key_computed(&mut self, key: &V) -> Result; + fn key_ref(&mut self, key: &'sval V) -> Result { + default_stream::map_key_ref(self, key) + } + + fn key_computed(&mut self, key: V) -> Result; - fn value(&mut self, value: &'sval V) -> Result { + fn value>(&mut self, value: V) -> Result { default_stream::map_value(self, value) } - fn value_computed(&mut self, value: &V) -> Result; + fn value_ref(&mut self, value: &'sval V) -> Result { + default_stream::map_value_ref(self, value) + } + + fn value_computed(&mut self, value: V) -> Result; fn end(self) -> Result; } @@ -224,20 +256,29 @@ pub trait StreamMap<'sval> { pub trait StreamTuple<'sval> { type Ok; - fn value( + fn value>( &mut self, tag: Option, index: sval::Index, - value: &'sval V, + value: V, ) -> Result { default_stream::tuple_value(self, tag, index, value) } - fn value_computed( + fn value_ref( &mut self, tag: Option, index: sval::Index, - value: &V, + value: &'sval V, + ) -> Result { + default_stream::tuple_value_ref(self, tag, index, value) + } + + fn value_computed( + &mut self, + tag: Option, + index: sval::Index, + value: V, ) -> Result; fn end(self) -> Result; @@ -246,20 +287,29 @@ pub trait StreamTuple<'sval> { pub trait StreamRecord<'sval> { type Ok; - fn value( + fn value>( &mut self, tag: Option, label: sval::Label, - value: &'sval V, + value: V, ) -> Result { default_stream::record_value(self, tag, label, value) } - fn value_computed( + fn value_ref( &mut self, tag: Option, label: sval::Label, - value: &V, + value: &'sval V, + ) -> Result { + default_stream::record_value_ref(self, tag, label, value) + } + + fn value_computed( + &mut self, + tag: Option, + label: sval::Label, + value: V, ) -> Result; fn end(self) -> Result; @@ -279,12 +329,12 @@ pub trait StreamEnum<'sval> { index: Option, ) -> Result; - fn tagged( + fn tagged>( self, tag: Option, label: Option, index: Option, - value: &'sval V, + value: V, ) -> Result where Self: Sized, @@ -292,12 +342,25 @@ pub trait StreamEnum<'sval> { default_stream::enum_tagged(self, tag, label, index, value) } - fn tagged_computed( + fn tagged_ref( + self, + tag: Option, + label: Option, + index: Option, + value: &'sval V, + ) -> Result + where + Self: Sized, + { + default_stream::enum_tagged_ref(self, tag, label, index, value) + } + + fn tagged_computed( self, tag: Option, label: Option, index: Option, - value: &V, + value: V, ) -> Result; fn tuple_begin( @@ -373,12 +436,12 @@ impl<'sval, Ok> Stream<'sval> for Unsupported { Err(Error::invalid_value("tags are unsupported")) } - fn tagged_computed( + fn tagged_computed( self, _: Option, _: Option, _: Option, - _: &V, + _: V, ) -> Result { Err(Error::invalid_value("tagged values are unsupported")) } @@ -424,7 +487,7 @@ impl<'sval, Ok> Stream<'sval> for Unsupported { impl<'sval, Ok> StreamSeq<'sval> for Unsupported { type Ok = Ok; - fn value_computed(&mut self, _: &V) -> Result { + fn value_computed(&mut self, _: V) -> Result { Err(Error::invalid_value("sequences are unsupported")) } @@ -436,11 +499,11 @@ impl<'sval, Ok> StreamSeq<'sval> for Unsupported { impl<'sval, Ok> StreamMap<'sval> for Unsupported { type Ok = Ok; - fn key_computed(&mut self, _: &V) -> Result { + fn key_computed(&mut self, _: V) -> Result { Err(Error::invalid_value("maps are unsupported")) } - fn value_computed(&mut self, _: &V) -> Result { + fn value_computed(&mut self, _: V) -> Result { Err(Error::invalid_value("maps are unsupported")) } @@ -452,11 +515,11 @@ impl<'sval, Ok> StreamMap<'sval> for Unsupported { impl<'sval, Ok> StreamTuple<'sval> for Unsupported { type Ok = Ok; - fn value_computed( + fn value_computed( &mut self, _: Option, _: sval::Index, - _: &V, + _: V, ) -> Result { Err(Error::invalid_value("tuples are unsupported")) } @@ -469,11 +532,11 @@ impl<'sval, Ok> StreamTuple<'sval> for Unsupported { impl<'sval, Ok> StreamRecord<'sval> for Unsupported { type Ok = Ok; - fn value_computed( + fn value_computed( &mut self, _: Option, _: sval::Label, - _: &V, + _: V, ) -> Result { Err(Error::invalid_value("records are unsupported")) } @@ -499,12 +562,12 @@ impl<'sval, Ok> StreamEnum<'sval> for Unsupported { Err(Error::invalid_value("enums are unsupported")) } - fn tagged_computed( + fn tagged_computed( self, _: Option, _: Option, _: Option, - _: &V, + _: V, ) -> Result { Err(Error::invalid_value("enums are unsupported")) } @@ -566,21 +629,28 @@ fn owned_label_ref(label: &sval::Label) -> Result> { pub mod default_stream { use super::*; - pub fn value<'sval, S: Stream<'sval>, V: sval::Value + ?Sized>( + pub fn value<'sval, S: Stream<'sval>, V: sval_ref::ValueRef<'sval>>( stream: S, - value: &'sval V, + value: V, ) -> Result { let mut stream = FlatStream::new(stream); - let _ = sval::default_stream::value(&mut stream, value); + let _ = sval_ref::stream_ref(&mut stream, value); stream.finish() } - pub fn value_computed<'sval, S: Stream<'sval>, V: sval::Value + ?Sized>( + pub fn value_ref<'sval, S: Stream<'sval>, V: sval::Value + ?Sized>( stream: S, - value: &V, + value: &'sval V, + ) -> Result { + stream.value(sval_ref::to_ref(value)) + } + + pub fn value_computed<'sval, S: Stream<'sval>, V: sval::Value>( + stream: S, + value: V, ) -> Result { let mut stream = FlatStream::new(stream); - let _ = sval::default_stream::value_computed(&mut stream, value); + let _ = sval::default_stream::value_computed(&mut stream, &value); stream.finish() } @@ -654,54 +724,123 @@ pub mod default_stream { seq.end() } - pub fn seq_value<'sval, S: StreamSeq<'sval> + ?Sized, V: sval::Value + ?Sized>( - seq: &mut S, + pub fn tagged<'sval, S: Stream<'sval>, V: sval_ref::ValueRef<'sval>>( + stream: S, + tag: Option, + label: Option, + index: Option, + value: V, + ) -> Result { + stream.tagged_computed(tag, label, index, value) + } + + pub fn tagged_ref<'sval, S: Stream<'sval>, V: sval::Value + ?Sized>( + stream: S, + tag: Option, + label: Option, + index: Option, value: &'sval V, + ) -> Result { + stream.tagged(tag, label, index, sval_ref::to_ref(value)) + } + + pub fn seq_value<'sval, S: StreamSeq<'sval> + ?Sized, V: sval_ref::ValueRef<'sval>>( + seq: &mut S, + value: V, ) -> Result { seq.value_computed(value) } - pub fn map_key<'sval, S: StreamMap<'sval> + ?Sized, V: sval::Value + ?Sized>( + pub fn seq_value_ref<'sval, S: StreamSeq<'sval> + ?Sized, V: sval::Value + ?Sized>( + seq: &mut S, + value: &'sval V, + ) -> Result { + seq.value(sval_ref::to_ref(value)) + } + + pub fn map_key<'sval, S: StreamMap<'sval> + ?Sized, V: sval_ref::ValueRef<'sval>>( map: &mut S, - key: &'sval V, + key: V, ) -> Result { map.key_computed(key) } - pub fn map_value<'sval, S: StreamMap<'sval> + ?Sized, V: sval::Value + ?Sized>( + pub fn map_key_ref<'sval, S: StreamMap<'sval> + ?Sized, V: sval::Value + ?Sized>( map: &mut S, - value: &'sval V, + key: &'sval V, + ) -> Result { + map.key(sval_ref::to_ref(key)) + } + + pub fn map_value<'sval, S: StreamMap<'sval> + ?Sized, V: sval_ref::ValueRef<'sval>>( + map: &mut S, + value: V, ) -> Result { map.value_computed(value) } - pub fn tuple_value<'sval, S: StreamTuple<'sval> + ?Sized, V: sval::Value + ?Sized>( + pub fn map_value_ref<'sval, S: StreamMap<'sval> + ?Sized, V: sval::Value + ?Sized>( + map: &mut S, + value: &'sval V, + ) -> Result { + map.value(sval_ref::to_ref(value)) + } + + pub fn tuple_value<'sval, S: StreamTuple<'sval> + ?Sized, V: sval_ref::ValueRef<'sval>>( tuple: &mut S, tag: Option, index: sval::Index, - value: &'sval V, + value: V, ) -> Result { tuple.value_computed(tag, index, value) } - pub fn record_value<'sval, S: StreamRecord<'sval> + ?Sized, V: sval::Value + ?Sized>( + pub fn tuple_value_ref<'sval, S: StreamTuple<'sval> + ?Sized, V: sval::Value + ?Sized>( + tuple: &mut S, + tag: Option, + index: sval::Index, + value: &'sval V, + ) -> Result { + tuple.value(tag, index, sval_ref::to_ref(value)) + } + + pub fn record_value<'sval, S: StreamRecord<'sval> + ?Sized, V: sval_ref::ValueRef<'sval>>( record: &mut S, tag: Option, label: sval::Label, - value: &'sval V, + value: V, ) -> Result { record.value_computed(tag, label, value) } - pub fn enum_tagged<'sval, S: StreamEnum<'sval>, V: sval::Value + ?Sized>( + pub fn record_value_ref<'sval, S: StreamRecord<'sval> + ?Sized, V: sval::Value + ?Sized>( + record: &mut S, + tag: Option, + label: sval::Label, + value: &'sval V, + ) -> Result { + record.value(tag, label, sval_ref::to_ref(value)) + } + + pub fn enum_tagged<'sval, S: StreamEnum<'sval>, V: sval_ref::ValueRef<'sval>>( stream: S, tag: Option, label: Option, index: Option, - value: &'sval V, + value: V, ) -> Result { stream.tagged_computed(tag, label, index, value) } + + pub fn enum_tagged_ref<'sval, S: StreamEnum<'sval>, V: sval::Value + ?Sized>( + stream: S, + tag: Option, + label: Option, + index: Option, + value: &'sval V, + ) -> Result { + stream.tagged(tag, label, index, sval_ref::to_ref(value)) + } } #[cfg(test)] @@ -783,7 +922,7 @@ mod tests { ] }), ToValue::default() - .value(&DeriveRecord { + .value_ref(&DeriveRecord { a: 1, b: DeriveTuple( 2, @@ -799,17 +938,29 @@ mod tests { #[test] fn stream_primitive() { - assert_eq!(Value::Null, ToValue::default().value(&sval::Null).unwrap()); - assert_eq!(Value::I64(42), ToValue::default().value(&42i64).unwrap()); - assert_eq!(Value::F64(42.1), ToValue::default().value(&42.1).unwrap()); - assert_eq!(Value::Bool(true), ToValue::default().value(&true).unwrap()); + assert_eq!( + Value::Null, + ToValue::default().value_ref(&sval::Null).unwrap() + ); + assert_eq!( + Value::I64(42), + ToValue::default().value_ref(&42i64).unwrap() + ); + assert_eq!( + Value::F64(42.1), + ToValue::default().value_ref(&42.1).unwrap() + ); + assert_eq!( + Value::Bool(true), + ToValue::default().value_ref(&true).unwrap() + ); } #[test] fn stream_text_borrowed() { assert_eq!( Value::Text(Cow::Borrowed("borrowed")), - ToValue::default().value("borrowed").unwrap() + ToValue::default().value_ref("borrowed").unwrap() ); } @@ -818,7 +969,7 @@ mod tests { assert_eq!( Value::Binary(Cow::Borrowed(b"borrowed")), ToValue::default() - .value(sval::BinarySlice::new(b"borrowed")) + .value_ref(sval::BinarySlice::new(b"borrowed")) .unwrap() ); } @@ -829,7 +980,7 @@ mod tests { Value::Seq(Seq { entries: vec![Value::I64(1), Value::I64(2), Value::I64(3),] }), - ToValue::default().value(&[1, 2, 3] as &[_]).unwrap() + ToValue::default().value_ref(&[1, 2, 3] as &[_]).unwrap() ); } @@ -844,7 +995,7 @@ mod tests { ] }), ToValue::default() - .value(sval::MapSlice::new(&[("a", 1), ("b", 2), ("c", 3),])) + .value_ref(sval::MapSlice::new(&[("a", 1), ("b", 2), ("c", 3),])) .unwrap() ); } @@ -860,7 +1011,7 @@ mod tests { ] }), ToValue::default() - .value(&{ + .value_ref(&{ struct Tuple; impl sval::Value for Tuple { @@ -912,7 +1063,7 @@ mod tests { })), }), ToValue::default() - .value(&{ + .value_ref(&{ struct TupleVariant; impl sval::Value for TupleVariant { @@ -964,7 +1115,7 @@ mod tests { ] }), ToValue::default() - .value(&{ + .value_ref(&{ struct Record; impl sval::Value for Record { @@ -1016,7 +1167,7 @@ mod tests { })), }), ToValue::default() - .value(&{ + .value_ref(&{ struct RecordVariant; impl sval::Value for RecordVariant { @@ -1063,7 +1214,7 @@ mod tests { assert_eq!( Value::Text(Cow::Owned("owned".into())), ToValue::default() - .value(&{ + .value_ref(&{ struct Text; impl sval::Value for Text { @@ -1092,7 +1243,7 @@ mod tests { assert_eq!( Value::Binary(Cow::Owned(b"owned".into())), ToValue::default() - .value(&{ + .value_ref(&{ struct Binary; impl sval::Value for Binary { @@ -1157,7 +1308,7 @@ mod tests { })) }))) }), - ToValue::default().value(&Layer).unwrap() + ToValue::default().value_ref(&Layer).unwrap() ); } @@ -1225,7 +1376,7 @@ mod tests { }))) }))) }), - ToValue::default().value(&Layer).unwrap() + ToValue::default().value_ref(&Layer).unwrap() ); } @@ -1406,12 +1557,12 @@ mod tests { Ok(Value::Tag(tag)) } - fn tagged_computed( + fn tagged_computed( self, tag: Option, label: Option, index: Option, - value: &V, + value: V, ) -> Result { let tag = Tag::new(tag, label, index)?; let value = ToValue::default().value_computed(value)?; @@ -1485,7 +1636,7 @@ mod tests { impl<'sval> StreamSeq<'sval> for ToSeq<'sval> { type Ok = Value<'sval>; - fn value(&mut self, value: &'sval V) -> Result { + fn value>(&mut self, value: V) -> Result { let value = ToValue::default().value(value)?; self.seq.entries.push(value); @@ -1493,7 +1644,7 @@ mod tests { Ok(()) } - fn value_computed(&mut self, value: &V) -> Result { + fn value_computed(&mut self, value: V) -> Result { let value = ToValue::default().value_computed(value)?; self.seq.entries.push(value); @@ -1509,19 +1660,19 @@ mod tests { impl<'sval> StreamMap<'sval> for ToMap<'sval> { type Ok = Value<'sval>; - fn key(&mut self, key: &'sval V) -> Result { + fn key>(&mut self, key: V) -> Result { self.key = Some(ToValue::default().value(key)?); Ok(()) } - fn key_computed(&mut self, key: &V) -> Result { + fn key_computed(&mut self, key: V) -> Result { self.key = Some(ToValue::default().value_computed(key)?); Ok(()) } - fn value(&mut self, value: &'sval V) -> Result { + fn value>(&mut self, value: V) -> Result { let key = self.key.take().unwrap(); let value = ToValue::default().value(value)?; @@ -1530,7 +1681,7 @@ mod tests { Ok(()) } - fn value_computed(&mut self, value: &V) -> Result { + fn value_computed(&mut self, value: V) -> Result { let key = self.key.take().unwrap(); let value = ToValue::default().value_computed(value)?; @@ -1547,11 +1698,11 @@ mod tests { impl<'sval> StreamTuple<'sval> for ToTuple<'sval> { type Ok = Value<'sval>; - fn value( + fn value>( &mut self, _: Option, index: sval::Index, - value: &'sval V, + value: V, ) -> Result { let value = ToValue::default().value(value)?; @@ -1560,11 +1711,11 @@ mod tests { Ok(()) } - fn value_computed( + fn value_computed( &mut self, _: Option, index: sval::Index, - value: &V, + value: V, ) -> Result { let value = ToValue::default().value_computed(value)?; @@ -1581,11 +1732,11 @@ mod tests { impl<'sval> StreamRecord<'sval> for ToRecord<'sval> { type Ok = Value<'sval>; - fn value( + fn value>( &mut self, _: Option, label: sval::Label, - value: &'sval V, + value: V, ) -> Result { let label = owned_label(label)?; let value = ToValue::default().value(value)?; @@ -1595,11 +1746,11 @@ mod tests { Ok(()) } - fn value_computed( + fn value_computed( &mut self, _: Option, label: sval::Label, - value: &V, + value: V, ) -> Result { let label = owned_label(label)?; let value = ToValue::default().value_computed(value)?; @@ -1635,12 +1786,12 @@ mod tests { })) } - fn tagged_computed( + fn tagged_computed( self, tag: Option, label: Option, index: Option, - value: &V, + value: V, ) -> Result { let tag = Tag::new(tag, label, index)?; let value = ToValue::default().value_computed(value)?; @@ -1720,20 +1871,20 @@ mod tests { impl<'sval> StreamTuple<'sval> for ToVariant> { type Ok = Value<'sval>; - fn value( + fn value>( &mut self, tag: Option, index: sval::Index, - value: &'sval V, + value: V, ) -> Result { self.stream.value(tag, index, value) } - fn value_computed( + fn value_computed( &mut self, tag: Option, index: sval::Index, - value: &V, + value: V, ) -> Result { self.stream.value_computed(tag, index, value) } @@ -1749,20 +1900,20 @@ mod tests { impl<'sval> StreamRecord<'sval> for ToVariant> { type Ok = Value<'sval>; - fn value( + fn value>( &mut self, tag: Option, label: sval::Label, - value: &'sval V, + value: V, ) -> Result { self.stream.value(tag, label, value) } - fn value_computed( + fn value_computed( &mut self, tag: Option, label: sval::Label, - value: &V, + value: V, ) -> Result { self.stream.value_computed(tag, label, value) } diff --git a/buffer/src/stream/flat.rs b/buffer/src/stream/flat.rs index 25a59743..c59e0078 100644 --- a/buffer/src/stream/flat.rs +++ b/buffer/src/stream/flat.rs @@ -186,7 +186,7 @@ impl<'sval, S: Stream<'sval>> sval::Stream<'sval> for FlatStream<'sval, S> { .map_err(|_| Error::invalid_value("failed to stream value"))?; Ok(None) } - ref mut state => state.value(v, |stream, v| stream.value(v)), + ref mut state => state.value(&sval_ref::to_ref(v), |stream, v| stream.value(v)), }, ) } @@ -564,7 +564,11 @@ impl<'sval, S: Stream<'sval>> sval::Stream<'sval> for FlatStream<'sval, S> { fn null(&mut self) -> sval::Result { self.buffer_or_stream_with( |buf| buf.null(), - |stream| stream.state.value(&sval::Null, |stream, _| stream.null()), + |stream| { + stream + .state + .value(&sval_ref::to_ref(&sval::Null), |stream, _| stream.null()) + }, ) } @@ -739,7 +743,9 @@ impl<'sval, S: Stream<'sval>> sval::Stream<'sval> for FlatStream<'sval, S> { let buf = stream.take_text()?; if let Some(text) = buf.as_borrowed_str() { - stream.state.value(text, |stream, text| stream.text(text)) + stream.state.value(&sval_ref::to_ref(text), |stream, text| { + stream.text(text.into_inner()) + }) } else { stream .state @@ -777,11 +783,10 @@ impl<'sval, S: Stream<'sval>> sval::Stream<'sval> for FlatStream<'sval, S> { let buf = stream.take_binary()?; if let Some(binary) = buf.as_borrowed_slice() { - stream - .state - .value(sval::BinarySlice::new(binary), |stream, binary| { - stream.binary(binary.as_slice()) - }) + stream.state.value( + &sval_ref::to_ref(sval::BinarySlice::new(binary)), + |stream, binary| stream.binary(binary.into_inner().as_slice()), + ) } else { stream .state @@ -809,10 +814,10 @@ fn try_catch<'sval, T, S: Stream<'sval>>( } impl<'sval, S: Stream<'sval>> State<'sval, S> { - fn value( + fn value + ?Sized>( &mut self, - value: &'sval V, - any: impl FnOnce(S, &'sval V) -> Result, + value: &V, + any: impl FnOnce(S, &V) -> Result, ) -> Result> { self.value_with( |stream| any(stream, value), diff --git a/buffer/src/stream/flat_enum.rs b/buffer/src/stream/flat_enum.rs index 7fe415d8..103413c3 100644 --- a/buffer/src/stream/flat_enum.rs +++ b/buffer/src/stream/flat_enum.rs @@ -80,19 +80,19 @@ impl<'sval, S: StreamEnum<'sval>> Stream<'sval> for FlatStreamEnum { type Enum = Unsupported; - fn value(self, value: &'sval V) -> Result { + fn value>(self, value: V) -> Result { self.value_or_recurse( - |stream, _| default_stream::value(stream, value), - |stream, _| stream.value(value), - (), + |stream, value| default_stream::value(stream, value), + |stream, value| stream.value(value), + value, ) } - fn value_computed(self, value: &V) -> Result { + fn value_computed(self, value: V) -> Result { self.value_or_recurse( - |stream, _| default_stream::value_computed(stream, value), - |stream, _| stream.value_computed(value), - (), + |stream, value| default_stream::value_computed(stream, value), + |stream, value| stream.value_computed(value), + value, ) } @@ -139,31 +139,35 @@ impl<'sval, S: StreamEnum<'sval>> Stream<'sval> for FlatStreamEnum { ) } - fn tagged( + fn tagged>( self, tag: Option, label: Option, index: Option, - value: &'sval V, + value: V, ) -> Result { self.value_or_recurse( - |stream, (tag, label, index)| stream.stream.tagged(tag, label, index, value), - |stream, (tag, label, index)| Stream::tagged(stream, tag, label, index, value), - (tag, label, index), + |stream, (value, tag, label, index)| stream.stream.tagged(tag, label, index, value), + |stream, (value, tag, label, index)| Stream::tagged(stream, tag, label, index, value), + (value, tag, label, index), ) } - fn tagged_computed( + fn tagged_computed( self, tag: Option, label: Option, index: Option, - value: &V, + value: V, ) -> Result { self.value_or_recurse( - |stream, (tag, label, index)| stream.stream.tagged_computed(tag, label, index, value), - |stream, (tag, label, index)| Stream::tagged_computed(stream, tag, label, index, value), - (tag, label, index), + |stream, (value, tag, label, index)| { + stream.stream.tagged_computed(tag, label, index, value) + }, + |stream, (value, tag, label, index)| { + Stream::tagged_computed(stream, tag, label, index, value) + }, + (value, tag, label, index), ) } diff --git a/ref/src/lib.rs b/ref/src/lib.rs index 3f618c02..02e6269d 100644 --- a/ref/src/lib.rs +++ b/ref/src/lib.rs @@ -36,8 +36,67 @@ pub fn stream_ref<'sval>( value.stream_ref(stream) } +/** +Wrap an [`sval::Value`] in a [`ValueRef`] +*/ +pub fn to_ref<'sval, V: sval::Value + ?Sized>(value: &'sval V) -> Ref<&'sval V> { + Ref::new(value) +} + use sval::{Result, Stream, Value}; +/** +Adapt an [`sval::Value`] into a [`ValueRef`]. +*/ +#[repr(transparent)] +#[derive(Debug, Clone, Copy)] +pub struct Ref(V); + +impl Ref { + /** + Wrap a value. + */ + pub fn new(value: V) -> Self { + Ref(value) + } + + /** + Get a reference to the underlying value. + */ + pub fn inner(&self) -> &V { + &self.0 + } + + /** + Take ownership of the underlying value. + */ + pub fn into_inner(self) -> V { + self.0 + } +} + +impl Ref { + /** + Get a borrowed wrapper over a borrowed value. + */ + pub fn new_borrowed<'a>(value: &'a V) -> &'a Ref { + // SAFETY: `&'a V` and `&'a Ref` have the same ABI + unsafe { &*(value as *const _ as *const Ref) } + } +} + +impl sval::Value for Ref { + fn stream<'sval, S: Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> Result { + self.0.stream(stream) + } +} + +impl<'sval, V: sval::Value + ?Sized> ValueRef<'sval> for Ref<&'sval V> { + fn stream_ref + ?Sized>(&self, stream: &mut S) -> Result { + self.0.stream(stream) + } +} + /** A producer of structured data that stores a reference internally. diff --git a/serde/src/to_serialize.rs b/serde/src/to_serialize.rs index 2aa9be77..6a808b90 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(&self.0) + .value_computed(&self.0) .unwrap_or_else(|e| Err(S::Error::custom(e))) } } @@ -187,12 +187,12 @@ impl<'sval, S: serde::Serializer> Stream<'sval> for Serializer { } } - fn tagged_computed( + fn tagged_computed( self, tag: Option, label: Option, _: Option, - value: &V, + value: V, ) -> sval_buffer::Result { match tag { Some(sval::tags::RUST_OPTION_SOME) => { @@ -306,7 +306,7 @@ impl<'sval, S: serde::Serializer> Stream<'sval> for Serializer { impl<'sval, S: serde::ser::SerializeSeq> StreamSeq<'sval> for SerializeSeq { type Ok = Result; - fn value_computed(&mut self, value: &V) -> sval_buffer::Result { + fn value_computed(&mut self, value: V) -> sval_buffer::Result { if let Ok(ref mut serializer) = self.serializer { match serializer.serialize_element(&ToSerialize::new(value)) { Ok(()) => return Ok(()), @@ -332,7 +332,7 @@ impl<'sval, S: serde::ser::SerializeSeq> StreamSeq<'sval> for SerializeSeq StreamMap<'sval> for SerializeMap { type Ok = Result; - fn key_computed(&mut self, key: &V) -> sval_buffer::Result { + fn key_computed(&mut self, key: V) -> sval_buffer::Result { if let Ok(ref mut serializer) = self.serializer { match serializer.serialize_key(&ToSerialize::new(key)) { Ok(()) => return Ok(()), @@ -347,7 +347,7 @@ impl<'sval, S: serde::ser::SerializeMap> StreamMap<'sval> for SerializeMap(&mut self, value: &V) -> sval_buffer::Result { + fn value_computed(&mut self, value: V) -> sval_buffer::Result { if let Ok(ref mut serializer) = self.serializer { match serializer.serialize_value(&ToSerialize::new(value)) { Ok(()) => return Ok(()), @@ -380,11 +380,11 @@ impl< { type Ok = Result; - fn value_computed( + fn value_computed( &mut self, _: Option, label: sval::Label, - value: &V, + value: V, ) -> sval_buffer::Result { match self.serializer { Ok(MaybeNamed::Named { ref mut serializer }) => { @@ -434,11 +434,11 @@ impl< { type Ok = Result; - fn value_computed( + fn value_computed( &mut self, _: Option, _: sval::Index, - value: &V, + value: V, ) -> sval_buffer::Result { match self.serializer { Ok(MaybeNamed::Named { ref mut serializer }) => { @@ -502,12 +502,12 @@ impl<'sval, S: serde::Serializer> StreamEnum<'sval> for SerializeEnum { .serialize_unit_variant(self.name, variant_index, variant)) } - fn tagged_computed( + fn tagged_computed( self, _: Option, label: Option, index: Option, - value: &V, + value: V, ) -> sval_buffer::Result { let variant = label .and_then(|label| label.as_static_str()) @@ -605,11 +605,11 @@ impl<'sval, S: serde::ser::SerializeStructVariant> StreamRecord<'sval> { type Ok = Result; - fn value_computed( + fn value_computed( &mut self, _: Option, label: sval::Label, - value: &V, + value: V, ) -> sval_buffer::Result { let field = label .as_static_str() @@ -642,11 +642,11 @@ impl<'sval, S: serde::ser::SerializeTupleVariant> StreamTuple<'sval> { type Ok = Result; - fn value_computed( + fn value_computed( &mut self, _: Option, _: sval::Index, - value: &V, + value: V, ) -> sval_buffer::Result { if let Ok(ref mut serializer) = self.serializer { match serializer.serialize_field(&ToSerialize::new(value)) {