memlink_protocol/
chunk.rs1use alloc::vec::Vec;
7
8#[derive(Debug, Clone)]
9pub struct Chunk {
10 pub offset: u64,
11 pub data: Vec<u8>,
12}
13
14impl Chunk {
15 #[allow(dead_code)]
16 pub fn new(offset: u64, data: Vec<u8>) -> Self {
17 Self { offset, data }
18 }
19
20 #[allow(dead_code)]
21 pub fn size(&self) -> usize {
22 self.data.len()
23 }
24
25 #[allow(dead_code)]
26 pub fn is_last(&self, total_size: u64) -> bool {
27 self.offset + self.data.len() as u64 >= total_size
28 }
29
30 #[allow(dead_code)]
31 pub fn serialize(&self) -> Vec<u8> {
32 unimplemented!("Chunk serialization will be implemented in Phase 2")
33 }
34
35 #[allow(dead_code)]
36 pub fn deserialize(_bytes: &[u8]) -> Option<Self> {
37 unimplemented!("Chunk deserialization will be implemented in Phase 2")
38 }
39}
40
41#[repr(u8)]
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
43#[allow(dead_code)]
44pub enum ChunkFlags {
45 None = 0,
46 Last = 1,
47 Compressed = 2,
48 RequiresAck = 4,
49 Retransmit = 8,
50}
51
52impl ChunkFlags {
53 #[allow(dead_code)]
54 pub fn from_u8(value: u8) -> Self {
55 match value {
56 1 => ChunkFlags::Last,
57 2 => ChunkFlags::Compressed,
58 4 => ChunkFlags::RequiresAck,
59 8 => ChunkFlags::Retransmit,
60 _ => ChunkFlags::None,
61 }
62 }
63
64 #[allow(dead_code)]
65 pub fn as_u8(self) -> u8 {
66 self as u8
67 }
68
69 #[allow(dead_code)]
70 pub fn has_flag(flags: u8, flag: ChunkFlags) -> bool {
71 flags & flag.as_u8() != 0
72 }
73
74 #[allow(dead_code)]
75 pub fn set_flag(flags: &mut u8, flag: ChunkFlags) {
76 *flags |= flag.as_u8();
77 }
78
79 #[allow(dead_code)]
80 pub fn clear_flag(flags: &mut u8, flag: ChunkFlags) {
81 *flags &= !flag.as_u8();
82 }
83}
84
85#[derive(Debug, Clone)]
86#[allow(dead_code)]
87pub struct ChunkedStream {
88 pub total_size: u64,
89 pub transferred: u64,
90 pub current_offset: u64,
91 pub chunk_size: usize,
92}
93
94#[allow(dead_code)]
95impl ChunkedStream {
96 pub fn new(total_size: u64, chunk_size: usize) -> Self {
97 Self {
98 total_size,
99 transferred: 0,
100 current_offset: 0,
101 chunk_size,
102 }
103 }
104
105 pub fn progress(&self) -> f64 {
106 if self.total_size == 0 {
107 return 1.0;
108 }
109 self.transferred as f64 / self.total_size as f64
110 }
111
112 pub fn remaining(&self) -> u64 {
113 self.total_size.saturating_sub(self.transferred)
114 }
115
116 pub fn is_complete(&self) -> bool {
117 self.transferred >= self.total_size
118 }
119}