feat: fixed delimiter differences between overlay and fuse-overlay
This commit is contained in:
parent
7b8f351b21
commit
489cbcc824
4 changed files with 33 additions and 136 deletions
147
src/fs/mount.rs
147
src/fs/mount.rs
|
@ -379,6 +379,26 @@ impl From<UntypedIdRange> for GidRange {
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct DelimitedList<const D: char, T>(Vec<T>);
|
pub struct DelimitedList<const D: char, T>(Vec<T>);
|
||||||
|
|
||||||
|
impl<const D: char, T> Deref for DelimitedList<D, T> {
|
||||||
|
type Target = Vec<T>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const D: char, T> Default for DelimitedList<D, T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(Default::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const D: char, T> DerefMut for DelimitedList<D, T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<const D: char, T: FromStr> FromStr for DelimitedList<D, T> {
|
impl<const D: char, T: FromStr> FromStr for DelimitedList<D, T> {
|
||||||
type Err = T::Err;
|
type Err = T::Err;
|
||||||
|
|
||||||
|
@ -431,129 +451,6 @@ impl<const D: char, T: Display> Display for DelimitedList<D, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Options<T> {
|
|
||||||
options: Vec<T>,
|
|
||||||
delimiter: char,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Options<T> {
|
|
||||||
pub fn new(options: Vec<T>, delimiter: char) -> Self {
|
|
||||||
Self { options, delimiter }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Deref for Options<T> {
|
|
||||||
type Target = Vec<T>;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.options
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> DerefMut for Options<T> {
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
&mut self.options
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Default for Options<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
options: Default::default(),
|
|
||||||
delimiter: ' ',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> AsRef<Vec<T>> for Options<T> {
|
|
||||||
fn as_ref(&self) -> &Vec<T> {
|
|
||||||
&self.options
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone> Clone for Options<T> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self {
|
|
||||||
options: self.options.clone(),
|
|
||||||
delimiter: self.delimiter,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: PartialEq> PartialEq for Options<T> {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.options.eq(&other.options) && self.delimiter.eq(&other.delimiter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Eq> Eq for Options<T> {}
|
|
||||||
|
|
||||||
impl<T: FromStr> FromStr for Options<T> {
|
|
||||||
type Err = T::Err;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
s.split(',')
|
|
||||||
.map(T::from_str)
|
|
||||||
.process_results(|iter| Options::from(iter.collect::<Vec<_>>()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Display> Display for Options<T> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
let mut iter = self.options.iter();
|
|
||||||
if let Some(head) = iter.next() {
|
|
||||||
write!(f, "{head}")?;
|
|
||||||
|
|
||||||
for item in iter {
|
|
||||||
write!(f, "{}{item}", self.delimiter)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> FromIterator<T> for Options<T> {
|
|
||||||
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
|
|
||||||
Self {
|
|
||||||
options: iter.into_iter().collect(),
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> IntoIterator for Options<T> {
|
|
||||||
type Item = T;
|
|
||||||
|
|
||||||
type IntoIter = IntoIter<T>;
|
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
|
||||||
self.options.into_iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a, T> IntoIterator for &'a Options<T> {
|
|
||||||
type Item = &'a T;
|
|
||||||
|
|
||||||
type IntoIter = Iter<'a, T>;
|
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
|
||||||
self.options.as_slice().iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> From<Vec<T>> for Options<T> {
|
|
||||||
fn from(value: Vec<T>) -> Self {
|
|
||||||
Self::from_iter(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> From<T> for Options<T> {
|
|
||||||
fn from(value: T) -> Self {
|
|
||||||
Self::from_iter([value])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct Sources(DelimitedList<',', OptionsSource>);
|
pub struct Sources(DelimitedList<',', OptionsSource>);
|
||||||
|
|
||||||
|
@ -1015,8 +912,8 @@ mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Access, DeviceId, KeyValuePair, MapUsers, MountOperation, MountOption, Options,
|
Access, DeviceId, KeyValuePair, MapUsers, MountOperation, MountOption, OptionsMode,
|
||||||
OptionsMode, OptionsSource, ParseMountOptionError, Subtree, UncheckedOptions,
|
OptionsSource, ParseMountOptionError, Subtree, UncheckedOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -272,10 +272,10 @@ impl Display for FuseOverlayOption {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FuseOverlay(StackFs<FuseOverlayOption>);
|
pub struct FuseOverlay(StackFs<' ', FuseOverlayOption>);
|
||||||
|
|
||||||
impl_deref!(FuseOverlay(StackFs<FuseOverlayOption>));
|
impl_deref!(FuseOverlay(StackFs<' ', FuseOverlayOption>));
|
||||||
impl_deref_mut!(FuseOverlay(StackFs<FuseOverlayOption>));
|
impl_deref_mut!(FuseOverlay(StackFs<' ', FuseOverlayOption>));
|
||||||
|
|
||||||
impl FuseOverlay {
|
impl FuseOverlay {
|
||||||
pub fn new(target: impl Into<PathBuf>) -> Self {
|
pub fn new(target: impl Into<PathBuf>) -> Self {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use crate::macros::impl_deref;
|
use crate::macros::impl_deref;
|
||||||
|
|
||||||
use super::mount::Options;
|
use super::mount::DelimitedList;
|
||||||
use super::Mountpoint;
|
use super::Mountpoint;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
|
@ -76,12 +76,12 @@ impl FromStr for LowerDirs {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StackFs<T> {
|
pub struct StackFs<const D: char, T> {
|
||||||
mountpoint: PathBuf,
|
mountpoint: PathBuf,
|
||||||
options: Options<T>,
|
options: DelimitedList<D, T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> StackFs<T> {
|
impl<const D: char, T> StackFs<D, T> {
|
||||||
pub fn new(target: impl Into<PathBuf>) -> Self {
|
pub fn new(target: impl Into<PathBuf>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
mountpoint: target.into(),
|
mountpoint: target.into(),
|
||||||
|
@ -105,7 +105,7 @@ impl<T> StackFs<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Display> Mountpoint for StackFs<T> {
|
impl<const D: char, T: Display> Mountpoint for StackFs<D, T> {
|
||||||
fn options(&self) -> impl Iterator<Item = impl Display> {
|
fn options(&self) -> impl Iterator<Item = impl Display> {
|
||||||
self.options.iter()
|
self.options.iter()
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,10 +247,10 @@ impl Display for OverlayOption {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Overlay(StackFs<OverlayOption>);
|
pub struct Overlay(StackFs<',', OverlayOption>);
|
||||||
|
|
||||||
impl_deref!(Overlay(StackFs<OverlayOption>));
|
impl_deref!(Overlay(StackFs<',', OverlayOption>));
|
||||||
impl_deref_mut!(Overlay(StackFs<OverlayOption>));
|
impl_deref_mut!(Overlay(StackFs<',', OverlayOption>));
|
||||||
|
|
||||||
impl Stack for Overlay {
|
impl Stack for Overlay {
|
||||||
fn lower_dirs(&self) -> impl Iterator<Item = &std::path::Path> {
|
fn lower_dirs(&self) -> impl Iterator<Item = &std::path::Path> {
|
||||||
|
|
Loading…
Add table
Reference in a new issue