hdf5_pure/file_create_properties.rs
1//! File-creation properties as one reusable value — the `fcpl` analogue.
2
3use crate::file_space_info::FileSpaceStrategy;
4use crate::libver::LibVer;
5
6/// File-creation properties applied when writing a new HDF5 file.
7///
8/// This is the `hdf5-pure` analogue of an HDF5 **file creation property list**
9/// (`fcpl`): one value carrying every creation-time setting, so application code
10/// can define a file layout once and reuse it everywhere it writes, instead of
11/// repeating a builder call chain and keeping the copies in sync.
12///
13/// The `Properties` suffix means the type stands in for one whole HDF5 property
14/// list, so every setting on it has a C counterpart to look up. It is a stand-in
15/// and not a port: a plain `Copy` value, with no handle to create or close, no
16/// runtime property registry, and no setter that can fail. `fcpl` and each
17/// `H5Pset_*` it models are doc aliases, so a search for either lands here.
18///
19/// One setting crosses the class line. `H5Pset_libver_bounds` is officially a
20/// *file access* property, but this crate checks the bound as the file is
21/// written, so [`with_libver_bounds`](Self::with_libver_bounds) lives here with
22/// the other write-time settings rather than on
23/// [`FileAccessProperties`](crate::FileAccessProperties).
24///
25/// Pass it to [`FileBuilder::with_create_properties`](crate::FileBuilder::with_create_properties)
26/// or [`File::create_with_options`](crate::File::create_with_options). The
27/// equivalent [`FileBuilder`](crate::FileBuilder) methods set the same fields one
28/// at a time and interoperate freely with this.
29///
30/// Values are recorded as given and checked when the file is written, not when
31/// the properties are built — the value is inert data, so an illegal page size
32/// is reported by `finish`/`write` rather than here. Note that a non-paged
33/// userblock size is currently **not** validated against HDF5's power-of-two
34/// rule; see the property-support reference for the exact coverage.
35///
36/// See the [property-support reference] for the full property-by-property map.
37///
38/// [property-support reference]: https://github.com/CramBL/hdf5-pure/blob/main/docs/reference/property-support.md
39///
40/// # Examples
41///
42/// ```no_run
43/// use hdf5_pure::{FileCreateProperties, FileSpaceStrategy};
44///
45/// // Define the layout once...
46/// fn paged_layout() -> FileCreateProperties {
47/// FileCreateProperties::new()
48/// .with_file_space_strategy(FileSpaceStrategy::Page, true, 1)
49/// .with_file_space_page_size(8192)
50/// }
51///
52/// // ...and reuse it across every write path.
53/// let mut builder = hdf5_pure::FileBuilder::new();
54/// builder.with_create_properties(paged_layout());
55/// builder.create_dataset("data").with_f64_data(&[1.0, 2.0]);
56/// builder.write("out.h5").unwrap();
57/// ```
58#[derive(Debug, Clone, Copy, PartialEq, Eq)]
59#[doc(alias = "fcpl")]
60pub struct FileCreateProperties {
61 userblock: u64,
62 libver_bounds: Option<(LibVer, LibVer)>,
63 file_space_strategy: Option<(FileSpaceStrategy, bool, u64)>,
64 file_space_page_size: Option<u64>,
65}
66
67impl FileCreateProperties {
68 /// A value carrying the crate's default creation behavior: no userblock,
69 /// no library-version bounds, and the writer's default file-space handling.
70 pub const fn new() -> Self {
71 Self {
72 userblock: 0,
73 libver_bounds: None,
74 file_space_strategy: None,
75 file_space_page_size: None,
76 }
77 }
78
79 /// Reserve a zero-filled userblock of `size` bytes before the superblock.
80 ///
81 /// HDF5 requires a power of two `>= 512`, or 0 for no userblock; the check
82 /// runs when the file is written. See
83 /// [`FileBuilder::with_userblock`](crate::FileBuilder::with_userblock) for how
84 /// to fill the region afterward.
85 #[doc(alias = "H5Pset_userblock")]
86 pub const fn with_userblock(mut self, size: u64) -> Self {
87 self.userblock = size;
88 self
89 }
90
91 /// Constrain the on-disk format version to `[low, high]`.
92 ///
93 /// `high` **selects** the format: `Earliest..=V18` writes the HDF5 1.8 one
94 /// and anything reaching 1.10 writes the 1.10 one, so this changes the bytes
95 /// of every file the properties are applied to. Content the chosen format
96 /// cannot express is refused with
97 /// [`FormatError::LibverTooOldForContent`](crate::FormatError::LibverTooOldForContent)
98 /// rather than silently upgraded — see
99 /// [`FileBuilder::with_libver_bounds`](crate::FileBuilder::with_libver_bounds)
100 /// for which content that is.
101 ///
102 /// `low` only rules formats out, licensing newer encodings without requiring
103 /// them, so a lower bound of `V112`, `V114` or `LATEST` writes the 1.10
104 /// format rather than being refused — provided `high` reaches it. An
105 /// inverted range such as `V114..=V110` is refused with
106 /// [`FormatError::LibverBoundsUnsatisfiable`](crate::FormatError::LibverBoundsUnsatisfiable).
107 ///
108 /// HDF5 classes `H5Pset_libver_bounds` as a *file access* property; it sits
109 /// here because this crate resolves the bound at write time.
110 #[doc(alias = "H5Pset_libver_bounds")]
111 pub const fn with_libver_bounds(mut self, low: LibVer, high: LibVer) -> Self {
112 self.libver_bounds = Some((low, high));
113 self
114 }
115
116 /// Set the file-space management strategy, whether free space persists across
117 /// close, and the smallest free-space section tracked.
118 #[doc(alias = "H5Pset_file_space_strategy")]
119 pub const fn with_file_space_strategy(
120 mut self,
121 strategy: FileSpaceStrategy,
122 persist: bool,
123 threshold: u64,
124 ) -> Self {
125 self.file_space_strategy = Some((strategy, persist, threshold));
126 self
127 }
128
129 /// Set the file-space page size, the allocation quantum under
130 /// [`FileSpaceStrategy::Page`].
131 #[doc(alias = "H5Pset_file_space_page_size")]
132 pub const fn with_file_space_page_size(mut self, page_size: u64) -> Self {
133 self.file_space_page_size = Some(page_size);
134 self
135 }
136
137 /// Return the configured userblock size in bytes (0 for none).
138 pub const fn userblock(&self) -> u64 {
139 self.userblock
140 }
141
142 /// Return the configured library-version bounds, if any.
143 pub const fn libver_bounds(&self) -> Option<(LibVer, LibVer)> {
144 self.libver_bounds
145 }
146
147 /// Return the configured file-space strategy, persist flag, and threshold, if
148 /// any.
149 pub const fn file_space_strategy(&self) -> Option<(FileSpaceStrategy, bool, u64)> {
150 self.file_space_strategy
151 }
152
153 /// Return the configured file-space page size, if any.
154 pub const fn file_space_page_size(&self) -> Option<u64> {
155 self.file_space_page_size
156 }
157}
158
159impl Default for FileCreateProperties {
160 fn default() -> Self {
161 Self::new()
162 }
163}