nectar_primitives/chunk/traits.rs
1//! Traits for chunk types and operations
2//!
3//! This module defines the core traits that all chunk types must implement,
4//! along with serialization and deserialization functionality.
5
6use crate::SwarmAddress;
7use crate::chunk::error;
8use crate::error::Result;
9use bytes::{BufMut, Bytes, BytesMut};
10
11/// Type alias for chunk addresses
12pub type ChunkAddress = SwarmAddress;
13
14/// Core trait for chunk metadata
15pub trait ChunkMetadata {
16 /// Get the metadata bytes for this chunk
17 fn bytes(&self) -> Bytes;
18}
19
20/// Core trait for chunk header
21pub trait ChunkHeader {
22 /// The metadata type for this chunk
23 type Metadata: ChunkMetadata;
24
25 /// Get the identifier byte for this chunk type
26 fn id(&self) -> u8;
27
28 /// Get the version byte for this chunk type
29 fn version(&self) -> u8;
30
31 /// Get the metadata bytes for this chunk
32 fn metadata(&self) -> &Self::Metadata;
33
34 /// Get the header bytes for this chunk
35 fn bytes(&self) -> Bytes {
36 let mut buf = BytesMut::with_capacity(2);
37 buf.put_u8(self.id());
38 buf.put_u8(self.version());
39 buf.put_slice(self.metadata().bytes().as_ref());
40 buf.freeze()
41 }
42}
43
44/// Core trait for all chunk types in the system.
45///
46/// This trait defines the common interface that all chunk implementations must provide.
47/// Each implementation must specify its type ID and version as associated constants.
48pub trait Chunk: Send + Sync + 'static {
49 /// The header type for this chunk
50 type Header: ChunkHeader;
51
52 /// Get the address of this chunk
53 fn address(&self) -> &ChunkAddress;
54
55 /// Get the header for this chunk
56 fn header(&self) -> &Self::Header;
57
58 /// Get the raw data contained in this chunk
59 fn data(&self) -> &Bytes;
60
61 /// Get the total size of this chunk in bytes
62 fn size(&self) -> usize {
63 self.header().bytes().len() + self.data().len()
64 }
65
66 /// Verify that this chunk matches an expected address
67 fn verify(&self, expected: &ChunkAddress) -> Result<()> {
68 let actual = self.address();
69 if actual != expected {
70 return Err(error::ChunkError::verification_failed(*expected, *actual).into());
71 }
72 Ok(())
73 }
74}
75
76/// Trait for serializing chunks with type prefix.
77///
78/// This trait provides methods for serializing a chunk with its type
79/// ID and version prefix.
80pub trait ChunkSerialization {
81 /// Serialize this chunk with its type ID and version prefix
82 fn serialize_with_prefix(&self) -> Bytes;
83}
84
85impl<T: Chunk> ChunkSerialization for T {
86 fn serialize_with_prefix(&self) -> Bytes {
87 let mut bytes = BytesMut::with_capacity(2 + self.size());
88 bytes.extend(self.header().bytes());
89 bytes.extend(self.data());
90 bytes.freeze()
91 }
92}
93
94/// Trait for chunks that contain a BMT body
95pub trait BmtChunk: Chunk {
96 /// Get the span of the chunk data
97 fn span(&self) -> u64;
98}