netrc_parser/error.rs
1use std::io;
2
3/// Error types for the `netrc_parser` library.
4///
5/// Represents all possible errors that can occur when parsing, reading, or
6/// manipulating `.netrc` files. Each variant provides specific details about
7/// the failure, such as I/O issues, parsing errors, or invalid file
8/// permissions. Use this enum to handle errors from methods like
9/// [`crate::Netrc::parse_from_path`] or [`crate::Netrc::parse_from_str`].
10///
11/// # Examples
12///
13/// Handling a file not found error:
14///
15/// ```
16/// use netrc_parser::{Netrc, NetrcError};
17///
18/// match Netrc::parse_from_path("/nonexistent/.netrc") {
19/// Ok(netrc) => println!("Parsed netrc: {:?}", netrc),
20/// Err(NetrcError::FileNotFound(path)) => println!("File not found: {}", path),
21/// Err(e) => println!("Other error: {}", e),
22/// }
23/// ```
24///
25/// Handling a parse error:
26///
27/// ```
28/// use netrc_parser::{Netrc, NetrcError};
29///
30/// match Netrc::parse_from_str("machine login user") {
31/// Ok(netrc) => println!("Parsed netrc: {:?}", netrc),
32/// Err(NetrcError::Parse { message, input }) => {
33/// println!("Parse error: {} in input: {}", message, input);
34/// },
35/// Err(e) => println!("Other error: {}", e),
36/// }
37/// ```
38#[derive(Debug, thiserror::Error)]
39pub enum NetrcError {
40 /// An I/O error occurred while reading or writing a `.netrc` file.
41 ///
42 /// This variant wraps standard I/O errors, such as permission denied or
43 /// disk full, but excludes file not found errors (see
44 /// [`NetrcError::FileNotFound`]). It originates from operations like
45 /// [`std::fs::metadata`] or [`std::fs::read_to_string`].
46 ///
47 /// # Fields
48 ///
49 /// * `0`: The underlying [`std::io::Error`].
50 ///
51 /// # Example
52 ///
53 /// ```no_run
54 /// use netrc_parser::{Netrc, NetrcError};
55 ///
56 /// if let Err(NetrcError::Io(e)) = Netrc::parse_from_path("/protected/.netrc") {
57 /// println!("I/O error: {}", e);
58 /// }
59 /// ```
60 #[error("I/O error: {0}")]
61 Io(#[from] io::Error),
62
63 /// The specified `.netrc` file was not found.
64 ///
65 /// This error occurs when the file path provided to
66 /// [`crate::Netrc::parse_from_path`] does not exist. It is distinct
67 /// from other I/O errors to allow specific handling of missing files.
68 ///
69 /// # Fields
70 ///
71 /// * `0`: The path to the non-existent file as a `String`.
72 ///
73 /// # Example
74 ///
75 /// ```
76 /// use netrc_parser::{Netrc, NetrcError};
77 ///
78 /// match Netrc::parse_from_path("/nonexistent/.netrc") {
79 /// Ok(_) => println!("File parsed"),
80 /// Err(NetrcError::FileNotFound(path)) => println!("File not found: {}", path),
81 /// Err(e) => println!("Other error: {}", e),
82 /// }
83 /// ```
84 #[error("File not found: {0}")]
85 FileNotFound(String),
86
87 /// A parsing error occurred while processing `.netrc` content.
88 ///
89 /// This error is returned by [`crate::Netrc::parse_from_str`] or
90 /// [`crate::Netrc::parse_from_path`] when the input cannot be parsed, such
91 /// as invalid syntax or missing required fields (e.g., a `machine`
92 /// keyword without a name).
93 ///
94 /// # Fields
95 ///
96 /// * `message`: A description of the parsing error.
97 /// * `input`: The input string that caused the error.
98 ///
99 /// # Example
100 ///
101 /// ```
102 /// use netrc_parser::{Netrc, NetrcError};
103 ///
104 /// if let Err(NetrcError::Parse { message, input }) = Netrc::parse_from_str("machine ") {
105 /// println!("Parse error: {} in input: {}", message, input);
106 /// }
107 /// ```
108 #[error("Parse error: {message} at input: {input}")]
109 Parse { message: String, input: String },
110
111 /// A duplicate machine entry was found in the `.netrc` content.
112 ///
113 /// This error occurs when the same machine name (or `default`) appears
114 /// multiple times in the input, which is invalid for `.netrc` files.
115 ///
116 /// # Fields
117 ///
118 /// * `0`: The name of the duplicated machine.
119 ///
120 /// # Example
121 ///
122 /// ```
123 /// use netrc_parser::{Netrc, NetrcError};
124 ///
125 /// let input = "machine example.com login user password pass\nmachine example.com login other password pass";
126 /// if let Err(NetrcError::DuplicateEntry(name)) = Netrc::parse_from_str(input) {
127 /// println!("Duplicate machine: {}", name);
128 /// }
129 /// ```
130 #[error("Duplicate entry: {0}")]
131 DuplicateEntry(String),
132
133 /// The requested machine was not found in the `.netrc` data.
134 ///
135 /// This error is returned by [`crate::Netrc::get`] or
136 /// [`crate::Netrc::update_machine`] when the specified machine name
137 /// does not exist.
138 ///
139 /// # Fields
140 ///
141 /// * `0`: The name of the missing machine.
142 ///
143 /// # Example
144 ///
145 /// ```
146 /// use netrc_parser::{Netrc, NetrcError};
147 ///
148 /// let mut netrc = Netrc::default();
149 /// if let Err(NetrcError::NotFound(name)) = netrc.update_machine("example.com", |m| {}) {
150 /// println!("Machine not found: {}", name);
151 /// }
152 /// ```
153 #[error("Machine not found: {0}")]
154 NotFound(String),
155
156 /// The `.netrc` file has insecure permissions.
157 ///
158 /// On Unix systems, `.netrc` files must have permissions set to `0600`
159 /// (owner read/write only). This error is returned by
160 /// [`crate::Netrc::parse_from_path`] if the file is readable or writable by
161 /// group or others.
162 ///
163 /// # Example
164 ///
165 /// ```no_run
166 /// use netrc_parser::{Netrc, NetrcError};
167 /// use std::fs;
168 ///
169 /// let path = "/tmp/test_netrc";
170 /// fs::write(path, "machine example.com login user password pass").unwrap();
171 /// #[cfg(unix)]
172 /// std::os::unix::fs::PermissionsExt::set_mode(
173 /// &mut fs::metadata(path).unwrap().permissions(),
174 /// 0o666,
175 /// );
176 /// if let Err(NetrcError::InsecurePermissions) = Netrc::parse_from_path(path) {
177 /// println!("Insecure permissions detected");
178 /// }
179 /// ```
180 #[error("Insecure file permissions")]
181 InsecurePermissions,
182
183 /// A serialization error occurred while converting to JSON or TOML.
184 ///
185 /// This error is returned by [`crate::Netrc::to_json`] or
186 /// [`crate::Netrc::to_toml`] if serialization fails, typically due to
187 /// invalid data or internal serializer issues.
188 ///
189 /// # Fields
190 ///
191 /// * `0`: A description of the serialization error.
192 ///
193 /// # Example
194 ///
195 /// ```no_run
196 /// use netrc_parser::{Netrc, NetrcError};
197 ///
198 /// let netrc = Netrc::default();
199 /// if let Err(NetrcError::Serialize(msg)) = netrc.to_json() {
200 /// println!("Serialization error: {}", msg);
201 /// }
202 /// ```
203 #[error("Serialization error: {0}")]
204 Serialize(String),
205}