ffbm/
error.rs

1//! Error types for ffbm.
2
3use std::fmt;
4use std::path::PathBuf;
5
6/// Errors that can occur during bookmark management.
7#[derive(Debug)]
8pub enum Error {
9    /// Firefox is currently running; close it first.
10    FirefoxRunning,
11    /// Firefox application directory not found.
12    FirefoxDirNotFound,
13    /// No Profile Groups databases found.
14    NoProfileGroups,
15    /// Profile name not found.
16    ProfileNotFound { name: String },
17    /// Multiple profiles match the given name.
18    AmbiguousProfile { name: String, matches: Vec<String> },
19    /// Profile path specified does not exist.
20    ProfilePathInvalid { path: PathBuf },
21    /// Database file not found in profile.
22    DatabaseNotFound { name: String, path: PathBuf },
23    /// Database error.
24    Sqlite(rusqlite::Error),
25    /// I/O error.
26    Io(std::io::Error),
27    /// TOML serialization error.
28    TomlSerialize(toml::ser::Error),
29    /// TOML deserialization error.
30    TomlDeserialize(toml::de::Error),
31    /// Invalid bookmark data.
32    InvalidBookmark { reason: String },
33}
34
35impl fmt::Display for Error {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        match self {
38            Self::FirefoxRunning => write!(
39                f,
40                "Firefox is running; close it before modifying bookmarks"
41            ),
42            Self::FirefoxDirNotFound => write!(
43                f,
44                "Firefox directory not found (expected ~/Library/Application Support/Firefox)"
45            ),
46            Self::NoProfileGroups => write!(
47                f,
48                "no Profile Groups databases found in Firefox directory"
49            ),
50            Self::ProfileNotFound { name } => {
51                write!(f, "profile not found: {name}")
52            }
53            Self::AmbiguousProfile { name, matches } => {
54                write!(
55                    f,
56                    "multiple profiles match \"{name}\": {}",
57                    matches.join(", ")
58                )
59            }
60            Self::ProfilePathInvalid { path } => {
61                write!(f, "profile path does not exist: {}", path.display())
62            }
63            Self::DatabaseNotFound { name, path } => {
64                write!(f, "database {} not found in {}", name, path.display())
65            }
66            Self::Sqlite(e) => write!(f, "SQLite error: {e}"),
67            Self::Io(e) => write!(f, "I/O error: {e}"),
68            Self::TomlSerialize(e) => write!(f, "TOML serialization error: {e}"),
69            Self::TomlDeserialize(e) => write!(f, "TOML deserialization error: {e}"),
70            Self::InvalidBookmark { reason } => write!(f, "invalid bookmark: {reason}"),
71        }
72    }
73}
74
75impl std::error::Error for Error {
76    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
77        match self {
78            Self::Sqlite(e) => Some(e),
79            Self::Io(e) => Some(e),
80            Self::TomlSerialize(e) => Some(e),
81            Self::TomlDeserialize(e) => Some(e),
82            Self::FirefoxRunning
83            | Self::FirefoxDirNotFound
84            | Self::NoProfileGroups
85            | Self::ProfileNotFound { .. }
86            | Self::AmbiguousProfile { .. }
87            | Self::ProfilePathInvalid { .. }
88            | Self::DatabaseNotFound { .. }
89            | Self::InvalidBookmark { .. } => None,
90        }
91    }
92}
93
94impl From<rusqlite::Error> for Error {
95    fn from(e: rusqlite::Error) -> Self {
96        Self::Sqlite(e)
97    }
98}
99
100impl From<std::io::Error> for Error {
101    fn from(e: std::io::Error) -> Self {
102        Self::Io(e)
103    }
104}
105
106impl From<toml::ser::Error> for Error {
107    fn from(e: toml::ser::Error) -> Self {
108        Self::TomlSerialize(e)
109    }
110}
111
112impl From<toml::de::Error> for Error {
113    fn from(e: toml::de::Error) -> Self {
114        Self::TomlDeserialize(e)
115    }
116}
117
118/// A specialized Result type for ffbm operations.
119pub type Result<T> = std::result::Result<T, Error>;