1use thiserror::Error;
4
5#[derive(Debug, Error)]
9pub enum PsrpError {
10 #[error(transparent)]
12 Winrm(#[from] winrm_rs::WinrmError),
13
14 #[error("PSRP protocol: {0}")]
16 Protocol(String),
17
18 #[error("CLIXML: {0}")]
20 Clixml(String),
21
22 #[error("fragment reassembly: {0}")]
24 Fragment(String),
25
26 #[error("runspace pool not in state {expected}, got {actual}")]
28 BadState {
29 expected: String,
31 actual: String,
33 },
34
35 #[error("pipeline stopped")]
37 Stopped,
38
39 #[error("pipeline failed: {0}")]
41 PipelineFailed(String),
42
43 #[error("operation cancelled")]
45 Cancelled,
46}
47
48impl PsrpError {
49 pub(crate) fn protocol(msg: impl Into<String>) -> Self {
50 Self::Protocol(msg.into())
51 }
52
53 pub(crate) fn clixml(msg: impl Into<String>) -> Self {
54 Self::Clixml(msg.into())
55 }
56
57 pub(crate) fn fragment(msg: impl Into<String>) -> Self {
58 Self::Fragment(msg.into())
59 }
60}
61
62pub type Result<T> = std::result::Result<T, PsrpError>;
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn display_variants() {
71 assert!(
72 PsrpError::protocol("x")
73 .to_string()
74 .contains("PSRP protocol")
75 );
76 assert!(PsrpError::clixml("x").to_string().contains("CLIXML"));
77 assert!(
78 PsrpError::fragment("x")
79 .to_string()
80 .contains("fragment reassembly")
81 );
82 assert!(
83 PsrpError::BadState {
84 expected: "Opened".into(),
85 actual: "Opening".into(),
86 }
87 .to_string()
88 .contains("Opened")
89 );
90 assert_eq!(PsrpError::Stopped.to_string(), "pipeline stopped");
91 assert!(
92 PsrpError::PipelineFailed("boom".into())
93 .to_string()
94 .contains("boom")
95 );
96 assert_eq!(PsrpError::Cancelled.to_string(), "operation cancelled");
97 }
98
99 #[test]
100 fn from_winrm_error() {
101 let we = winrm_rs::WinrmError::Timeout(5);
102 let pe: PsrpError = we.into();
103 assert!(matches!(pe, PsrpError::Winrm(_)));
104 }
105}