Skip to main content

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}