Skip to main content

vfsi_core/api/
write.rs

1//! Portable borrowed positional writes.
2
3#[bitfields::bitfield(u8)]
4#[derive(PartialEq, Eq)]
5struct WriteFlags {
6    write_all: bool,
7    #[bits(7)]
8    _reserved: u8,
9}
10
11/// Policy for positional vector writes. Defaults to reporting short writes.
12/// Completion is not atomicity, durability, or permission to replay failed RPCs.
13#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
14pub struct WriteOptions {
15    flags: WriteFlags,
16}
17impl WriteOptions {
18    /// Report each request's accepted byte count without completing short writes.
19    pub const fn new() -> Self {
20        Self {
21            flags: WriteFlags::new(),
22        }
23    }
24    /// Complete successful short writes at their remaining offsets when true.
25    /// Stop on any error, including ambiguous transport failures; never replay it.
26    /// This does not flush data to stable storage or make the batch atomic.
27    pub const fn write_all(mut self, complete: bool) -> Self {
28        self.flags.set_write_all(complete);
29        self
30    }
31    /// Whether successful short writes should be completed.
32    pub const fn writes_all(self) -> bool {
33        self.flags.write_all()
34    }
35}
36
37/// A positional write borrowing its handle and payload without copying either.
38/// Construction performs no I/O or allocation. Does not change the file cursor.
39/// Uses the same storage definition as the native [`crate::WriteOp`].
40#[repr(transparent)]
41pub struct WriteOp<'a, H>(crate::internal::WriteRequest<&'a H, &'a [u8], u64, ()>);
42
43impl<H> Copy for WriteOp<'_, H> {}
44impl<H> Clone for WriteOp<'_, H> {
45    fn clone(&self) -> Self {
46        *self
47    }
48}
49impl<H> std::fmt::Debug for WriteOp<'_, H> {
50    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51        self.0.fmt(f)
52    }
53}
54impl<'a, H> WriteOp<'a, H> {
55    /// Borrow a handle and payload at an absolute byte offset.
56    pub fn new(file: &'a H, offset: u64, data: &'a [u8]) -> Self {
57        Self(crate::internal::WriteRequest::new(file, offset, data))
58    }
59    /// Borrow a handle and payload at an absolute byte offset.
60    pub fn at(file: &'a H, offset: u64, data: &'a [u8]) -> Self {
61        Self::new(file, offset, data)
62    }
63    pub fn file(&self) -> &'a H {
64        self.0.file()
65    }
66    pub fn offset(&self) -> u64 {
67        self.0.offset()
68    }
69    pub fn data(&self) -> &'a [u8] {
70        self.0.data()
71    }
72}
73
74#[cfg(test)]
75mod option_layout_tests {
76    use super::*;
77    #[test]
78    fn packed_completion_flag_keeps_const_defaults_and_toggles() {
79        const COMPLETE: WriteOptions = WriteOptions::new().write_all(true);
80        assert_eq!(std::mem::size_of::<WriteOptions>(), 1);
81        assert!(!WriteOptions::default().writes_all());
82        assert!(COMPLETE.writes_all());
83        assert!(!COMPLETE.write_all(false).writes_all());
84        assert!(COMPLETE.write_all(false).write_all(true).writes_all());
85    }
86}