1use crate::api::FileHandle;
3
4#[bitfields::bitfield(u8)]
5#[derive(PartialEq, Eq)]
6struct WriteFlags {
7 write_all: bool,
8 #[bits(7)]
9 _reserved: u8,
10}
11
12#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
15pub struct WriteOptions {
16 flags: WriteFlags,
17}
18impl WriteOptions {
19 pub const fn new() -> Self {
21 Self {
22 flags: WriteFlags::new(),
23 }
24 }
25 pub const fn write_all(mut self, complete: bool) -> Self {
29 self.flags.set_write_all(complete);
30 self
31 }
32 pub const fn writes_all(self) -> bool {
34 self.flags.write_all()
35 }
36}
37
38pub struct WriteOp<'a, H: FileHandle + 'a> {
41 file: &'a H,
42 offset: u64,
43 data: &'a [u8],
44}
45impl<H: FileHandle> Copy for WriteOp<'_, H> {}
46impl<H: FileHandle> Clone for WriteOp<'_, H> {
47 fn clone(&self) -> Self {
48 *self
49 }
50}
51impl<H: FileHandle> std::fmt::Debug for WriteOp<'_, H> {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 f.debug_struct("WriteOp")
54 .field("offset", &self.offset)
55 .field("length", &self.data.len())
56 .finish_non_exhaustive()
57 }
58}
59impl<'a, H: FileHandle> WriteOp<'a, H> {
60 pub fn at(file: &'a H, offset: u64, data: &'a [u8]) -> Self {
74 Self { file, offset, data }
75 }
76 pub fn file(&self) -> &'a H {
78 self.file
79 }
80 pub fn offset(&self) -> u64 {
82 self.offset
83 }
84 pub fn data(&self) -> &'a [u8] {
86 self.data
87 }
88}
89
90#[cfg(test)]
91mod option_layout_tests {
92 use super::*;
93 #[test]
94 fn packed_completion_flag_keeps_const_defaults_and_toggles() {
95 const COMPLETE: WriteOptions = WriteOptions::new().write_all(true);
96 assert_eq!(std::mem::size_of::<WriteOptions>(), 1);
97 assert!(!WriteOptions::default().writes_all());
98 assert!(COMPLETE.writes_all());
99 assert!(!COMPLETE.write_all(false).writes_all());
100 assert!(COMPLETE.write_all(false).write_all(true).writes_all());
101 }
102}