rainier_filesystem/driver.rs
1//! Which disk to build — [`FilesystemDriver`].
2
3use rainier_support::setting_enum;
4
5setting_enum! {
6 /// Which [`Filesystem`](crate::Filesystem) a named disk uses.
7 ///
8 /// ```
9 /// use rainier_filesystem::FilesystemDriver;
10 /// use rainier_support::Setting;
11 ///
12 /// // R2, MinIO, B2 and Wasabi are all `s3` pointed at a different endpoint.
13 /// assert_eq!(FilesystemDriver::parse("s3").unwrap(), FilesystemDriver::S3);
14 /// ```
15 pub enum FilesystemDriver: "filesystem driver" {
16 /// One directory on this machine.
17 ///
18 /// The default. Survives a restart and not a redeploy, which is the
19 /// distinction that catches people out on ephemeral hosting.
20 #[default]
21 Local = "local",
22
23 /// In memory, for tests.
24 Memory = "memory",
25
26 /// S3, and everything that speaks its API: **Cloudflare R2**, MinIO,
27 /// Backblaze B2, Wasabi. The difference is the endpoint, not the
28 /// driver.
29 S3 = "s3",
30 }
31}
32
33impl FilesystemDriver {
34 /// Whether files written by one instance are visible to the others.
35 pub fn is_shared(&self) -> bool {
36 matches!(self, Self::S3)
37 }
38
39 /// Whether files survive the machine going away.
40 ///
41 /// `false` for [`Local`](Self::Local), which is the answer that surprises
42 /// people: a container's disk is not storage.
43 pub fn is_durable(&self) -> bool {
44 matches!(self, Self::S3)
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51 use rainier_support::Setting;
52
53 #[test]
54 fn only_object_storage_is_shared_and_durable() {
55 assert!(FilesystemDriver::S3.is_shared());
56 assert!(FilesystemDriver::S3.is_durable());
57
58 for driver in FilesystemDriver::ALL.iter().filter(|d| **d != FilesystemDriver::S3) {
59 assert!(!driver.is_shared(), "{driver} is per-machine");
60 assert!(!driver.is_durable(), "{driver} does not outlive its machine");
61 }
62 }
63}