Skip to main content

mount_fstab/
error.rs

1//! Error types for all fstab parsing and validation operations.
2//!
3//! This module defines the error hierarchy used throughout the library.
4//! Each error type implements `std::error::Error` via `thiserror`.
5
6/// Error parsing a spec (fstab field 1).
7#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[non_exhaustive]
10pub enum SpecError {
11    /// Spec field was empty.
12    #[error("empty spec field")]
13    Empty,
14}
15
16/// Error parsing a filesystem type (fstab field 3).
17#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19#[non_exhaustive]
20pub enum FsTypeError {
21    /// Filesystem type field was empty.
22    #[error("empty filesystem type (field 3)")]
23    Empty,
24}
25
26/// Error parsing mount options (fstab field 4).
27#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
29#[non_exhaustive]
30pub enum OptionsError {
31    /// An option had an empty name (e.g., leading comma or `=value` without a name).
32    #[error("empty option name in mount options")]
33    EmptyOptionName,
34}
35
36/// Error constructing an [`OptItem`](crate::options::OptItem).
37#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
38#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39#[non_exhaustive]
40pub enum OptItemError {
41    /// The option name was empty.
42    #[error("option name must not be empty")]
43    EmptyName,
44}
45
46/// Error constructing a [`MountPoint`](crate::types::MountPoint).
47#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
48#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
49#[non_exhaustive]
50pub enum MountPointError {
51    /// Mount point is not an absolute path and not `none` or `swap`.
52    #[error("mount point must be an absolute path (start with '/') or 'none'")]
53    NotAbsolute,
54    /// Mount point was empty.
55    #[error("mount point must not be empty")]
56    Empty,
57}
58
59/// Error building an [`Entry`](crate::types::Entry) via the builder pattern.
60///
61/// Returned by [`EntryBuilder::build`](crate::types::EntryBuilder::build)
62/// when a required field is missing.
63#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
64#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
65#[non_exhaustive]
66pub enum EntryBuilderError {
67    /// The `spec` field was not set before calling `build()`.
68    #[error("missing required field 'spec' in Entry builder")]
69    MissingSpec,
70    /// The `file` (mount point) field was not set before calling `build()`.
71    #[error("missing required field 'file' (mount point) in Entry builder")]
72    MissingFile,
73    /// The `vfstype` field was not set before calling `build()`.
74    #[error("missing required field 'vfstype' in Entry builder")]
75    MissingFsType,
76}
77
78/// Fstab parsing and editing error.
79#[derive(Debug, thiserror::Error)]
80#[non_exhaustive]
81pub enum FstabError {
82    /// A parse error on a specific line.
83    #[error("line {line}: {kind}")]
84    Parse {
85        /// The 1-indexed line number where the error occurred.
86        line: usize,
87        /// The specific kind of parse error.
88        #[source]
89        kind: ParseErrorKind,
90    },
91    /// An I/O error (file not found, permission denied, etc.).
92    #[error("I/O error: {0}")]
93    Io(#[from] std::io::Error),
94    /// An index was out of bounds when accessing an entry.
95    #[error("index {0} out of bounds (len={1})")]
96    IndexOutOfBounds(usize, usize),
97}
98
99/// Specific kind of parse error on a single fstab line.
100#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
101#[non_exhaustive]
102pub enum ParseErrorKind {
103    /// A required field was missing.
104    #[error("missing field: {0}")]
105    MissingField(&'static str),
106    /// The spec field (field 1) was invalid.
107    #[error("invalid spec: {0}")]
108    InvalidSpec(#[from] SpecError),
109    /// The mount point (field 2) was invalid.
110    #[error("invalid mount point: {0}")]
111    InvalidMountPoint(#[from] MountPointError),
112    /// The filesystem type (field 3) was invalid.
113    #[error("invalid filesystem type: {0}")]
114    InvalidFsType(#[from] FsTypeError),
115    /// The mount options (field 4) were invalid.
116    #[error("invalid mount options: {0}")]
117    InvalidOptions(#[from] OptionsError),
118    /// The freq value (field 5) was not a valid integer.
119    #[error("invalid freq value: {0}")]
120    InvalidFreq(String),
121    /// The passno value (field 6) was not a valid integer.
122    #[error("invalid passno value: {0}")]
123    InvalidPassNo(String),
124}