Skip to main content

shannon_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#[test]
36fn test_bridge_io_error_roundtrip() {
37    let shell_error = ShellError::Generic(GenericError::new_internal("some error", "some message"));
38
39    let bridge = ShellErrorBridge(shell_error);
40    let io_error = std::io::Error::from(bridge.clone());
41    let bridge_again = ShellErrorBridge::try_from(io_error).unwrap();
42    assert_eq!(bridge.0, bridge_again.0);
43}