A trait for types that can be read from a shard (payload + children). This trait is used internally during parallel reconstruction to deserialize individual items or slices of items from shard payloads. It provides two methods: - [`read_from_shard`](Self::read_from_shard): Reads a single item - [`read_slice_from_shard`](Self::read_slice_from_shard): Reads multiple items (optimized) ## Automatic
| 335 | /// Implementations must be `Send + Sync + 'static` to support parallel reconstruction across |
| 336 | /// threads. This is automatically satisfied for most types. |
| 337 | pub trait ParcodeItem: Sized + Send + Sync + 'static { |
| 338 | /// Reads a single item from the shard payload and children. |
| 339 | /// |
| 340 | /// This method is called during deserialization to reconstruct individual items from |
| 341 | /// a shard's payload. For types with chunkable fields, this method should deserialize |
| 342 | /// local fields from the reader and reconstruct remote fields from the children iterator. |
| 343 | /// |
| 344 | /// ## Parameters |
| 345 | /// |
| 346 | /// * `reader`: Cursor over the shard's decompressed payload |
| 347 | /// * `children`: Iterator over child nodes (for chunkable fields) |
| 348 | /// |
| 349 | /// ## Returns |
| 350 | /// |
| 351 | /// The deserialized item. |
| 352 | /// |
| 353 | /// ## Errors |
| 354 | /// |
| 355 | /// Returns an error if deserialization fails or children are missing. |
| 356 | fn read_from_shard( |
| 357 | reader: &mut std::io::Cursor<&[u8]>, |
| 358 | children: &mut std::vec::IntoIter<ChunkNode<'_>>, |
| 359 | ) -> Result<Self>; |
| 360 | |
| 361 | /// DEPRECATED in favor of `read_into_slice` internally, but kept for API compat. |
| 362 | /// Default impl now delegates to `read_into_slice` to reduce code duplication. |
| 363 | fn read_slice_from_shard( |
| 364 | reader: &mut std::io::Cursor<&[u8]>, |
| 365 | children: &mut std::vec::IntoIter<ChunkNode<'_>>, |
| 366 | ) -> Result<Vec<Self>> { |
| 367 | let start_pos = reader.position(); |
| 368 | |
| 369 | // Read length prefix |
| 370 | let len: u64 = bincode::serde::decode_from_std_read(reader, bincode::config::standard()) |
| 371 | .map_err(|e| ParcodeError::Serialization(e.to_string()))?; |
| 372 | |
| 373 | let count = usize::try_from(len) |
| 374 | .map_err(|_| ParcodeError::Serialization("Vector length exceeds usize".into()))?; |
| 375 | |
| 376 | // Allocate uninit vec |
| 377 | let mut uninit_vec: Vec<MaybeUninit<Self>> = Vec::with_capacity(count); |
| 378 | #[allow(unsafe_code)] |
| 379 | unsafe { |
| 380 | uninit_vec.set_len(count); |
| 381 | } |
| 382 | |
| 383 | reader.set_position(start_pos); |
| 384 | |
| 385 | let read_count = Self::read_into_slice(reader, children, &mut uninit_vec)?; |
| 386 | |
| 387 | if read_count != count { |
| 388 | return Err(ParcodeError::Format("Mismatch in read count".into())); |
| 389 | } |
| 390 | |
| 391 | // Transmute to Vec<T> |
| 392 | #[allow(unsafe_code)] |
| 393 | let final_vec = unsafe { |
| 394 | let mut manual = ManuallyDrop::new(uninit_vec); |
nothing calls this directly
no outgoing calls
no test coverage detected