harmos_domain/model/storage/files/
read.rs1use std::path::PathBuf;
20use super::FileReference;
23use crate::model::storage::codec::{Nested, Unsigned, coded, variants};
24use crate::{Error, MemorySize, Result};
25
26crate::model::storage::codec::product!(ByteRange {
31 offset: crate::model::storage::codec::Unsigned => 1,
32 limit: crate::model::storage::codec::Optional<crate::model::storage::codec::Unsigned> => 2,
33});
34crate::model::storage::codec::product!(FileBatch {
35 offset: crate::model::storage::codec::Unsigned => 1,
36 bytes: crate::model::storage::codec::Bytes => 2,
37});
38crate::model::storage::codec::product!(FileCompletion {
39 bytes: crate::model::storage::codec::Unsigned => 1,
40});
41variants!(FileSource {
42 0, 1, "stored": Self::Stored(file) => { file: Nested<FileReference> => 1 } => Self::Stored(file);
43 1, 2, "local": Self::Local(path) => { path: super::codec::LocalPath => 1 } => Self::Local(path);
44});
45variants!(FollowStart {
46 0, 1, "beginning": Self::Beginning => {} => Self::Beginning;
47 1, 2, "end": Self::End => {} => Self::End;
48 2, 3, "at": Self::At(offset) => { offset: Unsigned => 1 } => Self::At(offset);
49});
50variants!(FileEvent {
51 0, 1, "data": Self::Data(batch) => { batch: Nested<FileBatch> => 1 } => Self::Data(batch);
52 1, 2, "truncated": Self::Truncated { length } => { length: Unsigned => 1 } => Self::Truncated { length };
53 2, 3, "replaced": Self::Replaced => {} => Self::Replaced;
54});
55coded!(CaptureConsistency { Bounded, Stable });
56crate::model::storage::codec::product!(FileHash {
57 bytes_read: Unsigned => 1,
58 sha256: super::codec::Digest => 2,
59});
60
61#[derive(Clone, Copy, Debug, PartialEq, Eq)]
66pub struct ByteRange {
67 pub offset: u64,
68 pub limit: Option<u64>,
69}
70#[derive(Clone, Debug, PartialEq, Eq)]
71pub struct FileBatch {
72 pub offset: u64,
73 pub bytes: Vec<u8>,
74}
75#[derive(Clone, Copy, Debug, PartialEq, Eq)]
76pub struct FileCompletion {
77 pub bytes: u64,
78}
79
80#[derive(Clone, Copy, Debug, PartialEq, Eq)]
81pub struct FileHash {
82 pub bytes_read: u64,
83 pub sha256: [u8; 32],
84}
85
86#[derive(Clone, Debug, PartialEq, Eq)]
89pub enum FileSource {
90 Stored(FileReference),
91 Local(PathBuf),
92}
93
94#[derive(Clone, Copy, Debug, PartialEq, Eq)]
95pub enum FollowStart {
96 Beginning,
97 End,
98 At(u64),
99}
100
101#[derive(Clone, Debug, PartialEq, Eq)]
102pub enum FileEvent {
103 Data(FileBatch),
104 Truncated { length: u64 },
105 Replaced,
106}
107
108#[derive(Clone, Copy, Debug, PartialEq, Eq)]
109pub enum CaptureConsistency {
110 Bounded,
111 Stable,
112}
113
114impl FileSource {
119 pub fn grant_scope(&self) -> Option<String> {
120 match self {
121 Self::Stored(file) => Some(file.metadata.id.as_str().to_owned()),
122 Self::Local(_) => None,
123 }
124 }
125}
126
127impl MemorySize for FileSource {
128 fn memory_size(&self) -> usize {
129 std::mem::size_of::<Self>()
130 + match self {
131 Self::Stored(file) => file.memory_size().saturating_sub(std::mem::size_of_val(file)),
132 Self::Local(path) => path.capacity(),
133 }
134 }
135}
136
137impl MemorySize for FollowStart {
138 fn memory_size(&self) -> usize {
139 std::mem::size_of::<Self>()
140 }
141}
142
143impl MemorySize for FileEvent {
144 fn memory_size(&self) -> usize {
145 std::mem::size_of::<Self>()
146 + match self {
147 Self::Data(batch) => batch.memory_size().saturating_sub(std::mem::size_of_val(batch)),
148 Self::Truncated { .. } | Self::Replaced => 0,
149 }
150 }
151}
152
153impl MemorySize for CaptureConsistency {
154 fn memory_size(&self) -> usize {
155 std::mem::size_of::<Self>()
156 }
157}
158
159impl MemorySize for FileHash {
160 fn memory_size(&self) -> usize {
161 std::mem::size_of::<Self>()
162 }
163}
164
165impl ByteRange {
166 pub fn end(self, length: u64) -> Result<u64> {
167 let remaining = length
168 .checked_sub(self.offset)
169 .ok_or(Error::InvalidInput { field: "file byte range", reason: "offset exceeds the immutable file length" })?;
170 self.offset
171 .checked_add(self.limit.unwrap_or(remaining).min(remaining))
172 .ok_or(Error::InvalidInput { field: "file byte range", reason: "byte range overflow" })
173 }
174}
175impl MemorySize for ByteRange {
176 fn memory_size(&self) -> usize {
177 std::mem::size_of::<Self>()
178 }
179}
180impl MemorySize for FileBatch {
181 fn memory_size(&self) -> usize {
182 std::mem::size_of::<Self>().saturating_add(self.bytes.capacity())
183 }
184}
185impl MemorySize for FileCompletion {
186 fn memory_size(&self) -> usize {
187 std::mem::size_of::<Self>()
188 }
189}
190
191