From 188fa9e75a77bb980b9fc8f1ea7efc9bcb6198a8 Mon Sep 17 00:00:00 2001 From: Tedmund Ho Date: Tue, 24 Oct 2023 10:39:54 +0800 Subject: [PATCH] quicklog(serialize): modify `encode` signature --- quicklog/benches/logger_benchmark.rs | 6 +-- quicklog/examples/macros.rs | 2 +- quicklog/src/lib.rs | 2 +- quicklog/src/macros.rs | 6 ++- quicklog/src/serialize/mod.rs | 41 ++++++++----------- quicklog/tests/common/mod.rs | 8 ++-- .../failures/struct_missing_display.stderr | 4 +- 7 files changed, 33 insertions(+), 36 deletions(-) diff --git a/quicklog/benches/logger_benchmark.rs b/quicklog/benches/logger_benchmark.rs index 9537680..f3c483f 100644 --- a/quicklog/benches/logger_benchmark.rs +++ b/quicklog/benches/logger_benchmark.rs @@ -25,8 +25,8 @@ struct Nested { } impl Serialize for BigStruct { - fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> Store<'buf> { - let (chunk, _) = write_buf.split_at_mut(self.buffer_size_required()); + fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> (Store<'buf>, &'buf mut [u8]) { + let (chunk, rest) = write_buf.split_at_mut(self.buffer_size_required()); let elm_size = std::mem::size_of::(); let (vec_chunk, str_chunk) = chunk.split_at_mut(self.vec.len() * elm_size); @@ -38,7 +38,7 @@ impl Serialize for BigStruct { _ = self.some.encode(str_chunk); - Store::new(Self::decode, chunk) + (Store::new(Self::decode, chunk), rest) } fn decode(buf: &[u8]) -> (String, &[u8]) { diff --git a/quicklog/examples/macros.rs b/quicklog/examples/macros.rs index 344bbe2..6ba6d75 100644 --- a/quicklog/examples/macros.rs +++ b/quicklog/examples/macros.rs @@ -17,7 +17,7 @@ impl std::fmt::Display for S { } impl Serialize for S { - fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> Store<'buf> { + fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> (Store<'buf>, &'buf mut [u8]) { self.i.encode(write_buf) } diff --git a/quicklog/src/lib.rs b/quicklog/src/lib.rs index 9a4aa2a..71022ed 100644 --- a/quicklog/src/lib.rs +++ b/quicklog/src/lib.rs @@ -88,7 +88,7 @@ //! } //! //! impl Serialize for SomeStruct { -//! fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> Store<'buf> { /* some impl */ } +//! fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> (Store<'buf>, &'buf mut[u8]) { /* some impl */ } //! fn decode(read_buf: &[u8]) -> (String, &[u8]) { /* some impl */ } //! fn buffer_size_required(&self) -> usize { /* some impl */ } //! } diff --git a/quicklog/src/macros.rs b/quicklog/src/macros.rs index e3d4903..c3f8d77 100644 --- a/quicklog/src/macros.rs +++ b/quicklog/src/macros.rs @@ -76,8 +76,10 @@ macro_rules! is_level_enabled { macro_rules! make_store { ($serializable:expr) => {{ use $crate::serialize::Serialize; - $serializable - .encode($crate::logger().get_chunk_as_mut($serializable.buffer_size_required())) + let (store, _) = $serializable + .encode($crate::logger().get_chunk_as_mut($serializable.buffer_size_required())); + + store }}; } diff --git a/quicklog/src/serialize/mod.rs b/quicklog/src/serialize/mod.rs index 9ecdd6b..950cd1f 100644 --- a/quicklog/src/serialize/mod.rs +++ b/quicklog/src/serialize/mod.rs @@ -6,7 +6,7 @@ pub mod buffer; /// Additionally, this stores the contents serialized into a buffer, which does /// not require allocation and could speed things up. pub trait Serialize { - fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> Store<'buf>; + fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> (Store<'buf>, &'buf mut [u8]); fn decode(read_buf: &[u8]) -> (String, &[u8]); fn buffer_size_required(&self) -> usize; } @@ -45,13 +45,12 @@ impl Display for Store<'_> { macro_rules! gen_serialize { ($primitive:ty) => { impl Serialize for $primitive { - fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> Store<'buf> { - assert!(std::mem::size_of::<$primitive>() == write_buf.len()); - - let size = std::mem::size_of::<$primitive>(); - let (x, _) = write_buf.split_at_mut(size); + fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> (Store<'buf>, &'buf mut [u8]) { + let size = self.buffer_size_required(); + let (x, rest) = write_buf.split_at_mut(size); x.copy_from_slice(&self.to_le_bytes()); - Store::new(Self::decode, x) + + (Store::new(Self::decode, x), rest) } fn decode(read_buf: &[u8]) -> (String, &[u8]) { @@ -78,15 +77,15 @@ gen_serialize!(u64); gen_serialize!(usize); impl Serialize for &str { - fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> Store<'buf> { + fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> (Store<'buf>, &'buf mut [u8]) { let str_len = self.len(); - let (chunk, _) = write_buf.split_at_mut(str_len + SIZE_LENGTH); + let (chunk, rest) = write_buf.split_at_mut(str_len + SIZE_LENGTH); let (len_chunk, str_chunk) = chunk.split_at_mut(SIZE_LENGTH); len_chunk.copy_from_slice(&str_len.to_le_bytes()); str_chunk.copy_from_slice(self.as_bytes()); - Store::new(Self::decode, chunk) + (Store::new(Self::decode, chunk), rest) } fn decode(read_buf: &[u8]) -> (String, &[u8]) { @@ -105,16 +104,16 @@ impl Serialize for &str { } /// Eager evaluation into a String for debug structs -pub fn encode_debug(val: T, write_buf: &mut [u8]) -> Store { +pub fn encode_debug(val: T, write_buf: &mut [u8]) -> (Store, &mut [u8]) { let val_string = format!("{:?}", val); let str_len = val_string.len(); - let (chunk, _) = write_buf.split_at_mut(str_len + SIZE_LENGTH); + let (chunk, rest) = write_buf.split_at_mut(str_len + SIZE_LENGTH); let (len_chunk, str_chunk) = chunk.split_at_mut(SIZE_LENGTH); len_chunk.copy_from_slice(&str_len.to_le_bytes()); str_chunk.copy_from_slice(val_string.as_bytes()); - Store::new(<&str as Serialize>::decode, chunk) + (Store::new(<&str as Serialize>::decode, chunk), rest) } #[cfg(test)] @@ -129,7 +128,7 @@ mod tests { let mut buf = [0u8; BUF_SIZE]; let x: $primitive = $val; - let x_store = x.encode(&mut buf); + let (x_store, _) = x.encode(&mut buf); assert_eq!(format!("{}", x), format!("{}", x_store)); }}; } @@ -153,13 +152,9 @@ mod tests { let b: u32 = 999; let c: usize = 100000; - let (a_chunk, chunk) = buf.split_at_mut(a.buffer_size_required()); - let (b_chunk, chunk) = chunk.split_at_mut(b.buffer_size_required()); - let (c_chunk, _) = chunk.split_at_mut(c.buffer_size_required()); - - let a_store = a.encode(a_chunk); - let b_store = b.encode(b_chunk); - let c_store = c.encode(c_chunk); + let (a_store, chunk) = a.encode(&mut buf); + let (b_store, chunk) = b.encode(chunk); + let (c_store, _) = c.encode(chunk); assert_eq!( format!("{} {} {}", a, b, c), @@ -171,7 +166,7 @@ mod tests { fn serialize_str() { let mut buf = [0; 128]; let s = "hello world"; - let store = s.encode(&mut buf); + let (store, _) = s.encode(&mut buf); assert_eq!(s, format!("{}", store).as_str()) } @@ -186,7 +181,7 @@ mod tests { let mut buf = [0; 128]; let s = DebugStruct { s: "Hello World" }; - let store = encode_debug(&s, &mut buf); + let (store, _) = encode_debug(&s, &mut buf); assert_eq!(format!("{:?}", s), format!("{}", store)) } diff --git a/quicklog/tests/common/mod.rs b/quicklog/tests/common/mod.rs index 3e710b3..1eab24b 100644 --- a/quicklog/tests/common/mod.rs +++ b/quicklog/tests/common/mod.rs @@ -105,7 +105,7 @@ pub(crate) struct SerializeStruct { } impl Serialize for SerializeStruct { - fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> Store<'buf> { + fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> (Store<'buf>, &'buf mut [u8]) { self.symbol.as_str().encode(write_buf) } @@ -125,8 +125,8 @@ pub(crate) struct BigStruct { } impl Serialize for BigStruct { - fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> Store<'buf> { - let (chunk, _) = write_buf.split_at_mut(self.buffer_size_required()); + fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> (Store<'buf>, &'buf mut [u8]) { + let (chunk, rest) = write_buf.split_at_mut(self.buffer_size_required()); let elm_size = std::mem::size_of::(); let (vec_chunk, str_chunk) = chunk.split_at_mut(self.vec.len() * elm_size); @@ -138,7 +138,7 @@ impl Serialize for BigStruct { _ = self.some.encode(str_chunk); - Store::new(Self::decode, chunk) + (Store::new(Self::decode, chunk), rest) } fn decode(buf: &[u8]) -> (String, &[u8]) { diff --git a/quicklog/tests/failures/struct_missing_display.stderr b/quicklog/tests/failures/struct_missing_display.stderr index 4bc86d3..0e1c54f 100644 --- a/quicklog/tests/failures/struct_missing_display.stderr +++ b/quicklog/tests/failures/struct_missing_display.stderr @@ -41,7 +41,7 @@ error[E0599]: no method named `encode` found for struct `Something` in the curre help: one of the expressions' fields has a method of the same name --> src/macros.rs | - | .some_str.encode($crate::logger().get_chunk_as_mut($serializable.buffer_size_required())) + | .some_str.encode($crate::logger().get_chunk_as_mut($serializable.buffer_size_required())); | +++++++++ error[E0599]: no method named `buffer_size_required` found for struct `Something` in the current scope @@ -62,5 +62,5 @@ error[E0599]: no method named `buffer_size_required` found for struct `Something help: one of the expressions' fields has a method of the same name --> src/macros.rs | - | .encode($crate::logger().get_chunk_as_mut($serializable.some_str.buffer_size_required())) + | .encode($crate::logger().get_chunk_as_mut($serializable.some_str.buffer_size_required())); | +++++++++