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}