Skip to main content

nu_protocol/errors/shell_error/
bridge.rs

1use super::ShellError;
2#[cfg(test)]
3use super::generic::GenericError;
4use serde::{Deserialize, Serialize};
5use thiserror::Error;
6
7/// A bridge for transferring a [`ShellError`] between Nushell or similar processes.
8///
9/// This newtype encapsulates a [`ShellError`] to facilitate its transfer between Nushell processes
10/// or processes with similar behavior.
11/// By defining this type, we eliminate ambiguity about what is being transferred and avoid the
12/// need to implement [`From<io::Error>`](From) and [`Into<io::Error>`](Into) directly on
13/// `ShellError`.
14#[derive(Debug, Clone, PartialEq, Error, Serialize, Deserialize)]
15#[error("{0}")]
16pub struct ShellErrorBridge(pub ShellError);
17
18impl TryFrom<std::io::Error> for ShellErrorBridge {
19    type Error = std::io::Error;
20
21    fn try_from(value: std::io::Error) -> Result<Self, Self::Error> {
22        let kind = value.kind();
23        value
24            .downcast()
25            .inspect(|_| debug_assert_eq!(kind, std::io::ErrorKind::Other))
26    }
27}
28
29impl From<ShellErrorBridge> for std::io::Error {
30    fn from(value: ShellErrorBridge) -> Self {
31        std::io::Error::other(value)
32    }
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn test_bridge_io_error_roundtrip() {
41        let shell_error =
42            ShellError::Generic(GenericError::new_internal("some error", "some message"));
43
44        let bridge = ShellErrorBridge(shell_error);
45        let io_error = std::io::Error::from(bridge.clone());
46        let bridge_again = ShellErrorBridge::try_from(io_error).unwrap();
47        assert_eq!(bridge.0, bridge_again.0);
48    }
49}