win_durable_ioring/windows_backend/disposition.rs
1// Copyright (c) 2026 Mike Grier
2//! [`Disposition`]: what an open does about a file that is there and a file that is not, as
3//! `CreateFileW`'s `dwCreationDisposition` states it (DI-13.7.3, DI-D-64).
4//!
5//! `CreateFileW` has five dispositions. Three are offered here. `CREATE_ALWAYS` and
6//! `TRUNCATE_EXISTING` are the two that empty a file that exists, and they are not offered in the
7//! first release (the engineer's ruling of 2026-10-16, recorded with its measurements in DI-D-64);
8//! the enum is `#[non_exhaustive]` so that offering them later is not a breaking change. A caller
9//! that wants an existing file emptied does it through the handle the open lends, with
10//! `File::set_len(0)`.
11
12use windows_sys::Win32::Storage::FileSystem::{CREATE_NEW, OPEN_ALWAYS, OPEN_EXISTING};
13
14#[cfg(test)]
15mod tests;
16
17/// The disposition of an open: what it does when the file exists and when it does not.
18///
19/// None of the three changes the contents of a file that exists, so no data access is gated by the
20/// choice.
21///
22/// | Variant | `dwCreationDisposition` | File exists | File does not exist |
23/// |---|---|---|---|
24/// | [`CreateNew`](Self::CreateNew) | `CREATE_NEW` | fails, `ERROR_FILE_EXISTS` | created |
25/// | [`OpenExisting`](Self::OpenExisting) | `OPEN_EXISTING` | opened | fails, `ERROR_FILE_NOT_FOUND` |
26/// | [`OpenAlways`](Self::OpenAlways) | `OPEN_ALWAYS` | opened | created |
27///
28/// A file that an open creates is created empty.
29///
30/// There is deliberately no `Default`: the options start at [`OpenExisting`](Self::OpenExisting),
31/// which creates nothing, and a disposition is stated where one is wanted.
32#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
33#[non_exhaustive]
34pub enum Disposition {
35 /// `CREATE_NEW`: create the file, and fail if it exists.
36 CreateNew,
37 /// `OPEN_EXISTING`: open the file, and fail if it does not exist.
38 OpenExisting,
39 /// `OPEN_ALWAYS`: open the file if it exists, and create it if it does not.
40 OpenAlways,
41}
42
43impl Disposition {
44 /// The value this is in `dwCreationDisposition`.
45 pub(super) const fn bits(self) -> u32 {
46 match self {
47 Self::CreateNew => CREATE_NEW,
48 Self::OpenExisting => OPEN_EXISTING,
49 Self::OpenAlways => OPEN_ALWAYS,
50 }
51 }
52}