nu_protocol/errors/shell_error/
bridge.rs

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