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