Skip to main content

vfsi_core/api/
builders.rs

1//! Builders shared by all application clients.
2use super::{OpenFlags, OpenOp, Result, Vfsi, VfsiExt};
3use std::{fmt, path::Path};
4
5/// `std::fs::OpenOptions`-style builder for any [`Vfsi`] client.
6#[must_use = "configuration and requests have no effect until used"]
7pub struct OpenOptions<'a, C: Vfsi + ?Sized> {
8    client: &'a C,
9    flags: OpenFlags,
10    mode: u32,
11}
12
13impl<C: Vfsi + ?Sized> Clone for OpenOptions<'_, C> {
14    fn clone(&self) -> Self {
15        Self {
16            client: self.client,
17            flags: self.flags,
18            mode: self.mode,
19        }
20    }
21}
22
23impl<C: Vfsi + ?Sized> fmt::Debug for OpenOptions<'_, C> {
24    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
25        formatter
26            .debug_struct("OpenOptions")
27            .field("flags", &self.flags)
28            .field("mode", &format_args!("{:#o}", self.mode))
29            .finish()
30    }
31}
32
33impl<'a, C: Vfsi + ?Sized> OpenOptions<'a, C> {
34    pub(super) fn new(client: &'a C) -> Self {
35        Self {
36            client,
37            flags: OpenFlags::empty(),
38            mode: 0o666,
39        }
40    }
41
42    pub fn read(&mut self, enabled: bool) -> &mut Self {
43        self.flags.set(OpenFlags::READ, enabled);
44        self
45    }
46
47    pub fn write(&mut self, enabled: bool) -> &mut Self {
48        self.flags.set(OpenFlags::WRITE, enabled);
49        self
50    }
51
52    pub fn append(&mut self, enabled: bool) -> &mut Self {
53        self.flags.set(OpenFlags::APPEND, enabled);
54        self
55    }
56
57    pub fn truncate(&mut self, enabled: bool) -> &mut Self {
58        self.flags.set(OpenFlags::TRUNCATE, enabled);
59        self
60    }
61
62    pub fn create(&mut self, enabled: bool) -> &mut Self {
63        self.flags.set(OpenFlags::CREATE, enabled);
64        self
65    }
66
67    pub fn create_new(&mut self, enabled: bool) -> &mut Self {
68        self.flags.set(OpenFlags::CREATE_NEW, enabled);
69        self
70    }
71
72    pub fn mode(&mut self, mode: u32) -> &mut Self {
73        self.mode = mode;
74        self
75    }
76
77    pub fn open(&self, path: impl AsRef<Path>) -> Result<C::File> {
78        self.client
79            .open_with(OpenOp::new(path.as_ref(), self.flags).mode(self.mode))
80    }
81}
82
83impl<C: Vfsi + ?Sized> OpenOptions<'_, C> {
84    pub fn vopen<P: AsRef<Path>>(&self, paths: &[P]) -> Result<Vec<C::File>> {
85        let requests: Vec<OpenOp> = paths
86            .iter()
87            .map(|path| OpenOp::new(path.as_ref(), self.flags).mode(self.mode))
88            .collect();
89        self.client.vopen(&requests)
90    }
91}