diff --git a/rust/fory-core/src/row/mod.rs b/rust/fory-core/src/row/mod.rs index 6c6d66f0aa..82bfe7201d 100644 --- a/rust/fory-core/src/row/mod.rs +++ b/rust/fory-core/src/row/mod.rs @@ -21,6 +21,6 @@ mod reader; mod row; mod writer; -pub use reader::{from_row, ArrayViewer, StructViewer}; +pub use reader::{from_row, from_row_in, ArrayViewer, StructViewer}; pub use row::Row; -pub use writer::{to_row, ArrayWriter, StructWriter}; +pub use writer::{to_row, to_row_in, ArrayWriter, StructWriter}; diff --git a/rust/fory-core/src/row/reader.rs b/rust/fory-core/src/row/reader.rs index 1549a55ea7..42ef474607 100644 --- a/rust/fory-core/src/row/reader.rs +++ b/rust/fory-core/src/row/reader.rs @@ -16,6 +16,7 @@ // under the License. use super::{bit_util::calculate_bitmap_width_in_bytes, row::Row}; +use crate::buffer::Reader; use byteorder::{ByteOrder, LittleEndian}; struct FieldAccessorHelper<'a> { @@ -122,3 +123,7 @@ impl<'r> MapViewer<'r> { pub fn from_row<'a, T: Row<'a>>(row: &'a [u8]) -> T::ReadResult { T::cast(row) } + +pub fn from_row_in<'a, T: Row<'a>>(reader: &Reader<'a>) -> T::ReadResult { + T::cast(&reader.bf[reader.cursor..]) +} diff --git a/rust/fory-core/src/row/writer.rs b/rust/fory-core/src/row/writer.rs index 06bf5dd3c9..e93f8f8aed 100644 --- a/rust/fory-core/src/row/writer.rs +++ b/rust/fory-core/src/row/writer.rs @@ -190,3 +190,10 @@ pub fn to_row<'a, T: Row<'a>>(v: &T) -> Result, Error> { T::write(v, &mut writer)?; Ok(buffer) } + +pub fn to_row_in<'a, T: Row<'a>>(buffer: &mut Vec, v: &T) -> Result { + let start = buffer.len(); + let mut writer = Writer::from_buffer(buffer); + T::write(v, &mut writer)?; + Ok(writer.len() - start) +} diff --git a/rust/tests/tests/test_row.rs b/rust/tests/tests/test_row.rs index 488a57cfb9..c9a5b0a43c 100644 --- a/rust/tests/tests/test_row.rs +++ b/rust/tests/tests/test_row.rs @@ -17,7 +17,8 @@ use std::collections::BTreeMap; -use fory_core::row::{from_row, to_row}; +use fory_core::row::{from_row, from_row_in, to_row, to_row_in}; +use fory_core::Reader; use fory_derive::ForyRow; #[test] @@ -139,3 +140,49 @@ fn row() { assert_eq!(f5.get("k1").expect("should exists"), &"v1"); assert_eq!(f5.get("k2").expect("should exists"), &"v2"); } + +#[test] +fn test_to_row_in() { + #[derive(ForyRow)] + struct Data { + id: i32, + val: String, + } + + let data = Data { + id: 123, + val: "test".to_string(), + }; + + let mut buffer = vec![1, 2, 3]; + to_row_in(&mut buffer, &data).unwrap(); + + assert!(buffer.len() > 3); + let row = from_row::(&buffer[3..]); + assert_eq!(row.id(), 123); + assert_eq!(row.val(), "test"); +} + +#[test] +fn test_from_row_in() { + #[derive(ForyRow)] + struct Data { + id: i32, + val: String, + } + + let data = Data { + id: 456, + val: "reader_test".to_string(), + }; + + let mut buffer = vec![0u8; 5]; // padding + to_row_in(&mut buffer, &data).unwrap(); + + let mut reader = Reader::new(&buffer); + reader.skip(5).unwrap(); // skip padding + + let row = from_row_in::(&reader); + assert_eq!(row.id(), 456); + assert_eq!(row.val(), "reader_test"); +}