1use std::fmt;
4use std::path::PathBuf;
5
6#[derive(Debug)]
8pub enum Error {
9 FirefoxRunning,
11 FirefoxDirNotFound,
13 NoProfileGroups,
15 ProfileNotFound { name: String },
17 AmbiguousProfile { name: String, matches: Vec<String> },
19 ProfilePathInvalid { path: PathBuf },
21 DatabaseNotFound { name: String, path: PathBuf },
23 Sqlite(rusqlite::Error),
25 Io(std::io::Error),
27 TomlSerialize(toml::ser::Error),
29 TomlDeserialize(toml::de::Error),
31 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
118pub type Result<T> = std::result::Result<T, Error>;