use thiserror::Error;
#[derive(Debug, Error)]
pub enum PsrpError {
#[error(transparent)]
Winrm(#[from] winrm_rs::WinrmError),
#[error("PSRP protocol: {0}")]
Protocol(String),
#[error("CLIXML: {0}")]
Clixml(String),
#[error("fragment reassembly: {0}")]
Fragment(String),
#[error("runspace pool not in state {expected}, got {actual}")]
BadState {
expected: String,
actual: String,
},
#[error("pipeline stopped")]
Stopped,
#[error("pipeline failed: {0}")]
PipelineFailed(String),
#[error("operation cancelled")]
Cancelled,
}
impl PsrpError {
pub(crate) fn protocol(msg: impl Into<String>) -> Self {
Self::Protocol(msg.into())
}
pub(crate) fn clixml(msg: impl Into<String>) -> Self {
Self::Clixml(msg.into())
}
pub(crate) fn fragment(msg: impl Into<String>) -> Self {
Self::Fragment(msg.into())
}
}
pub type Result<T> = std::result::Result<T, PsrpError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn display_variants() {
assert!(
PsrpError::protocol("x")
.to_string()
.contains("PSRP protocol")
);
assert!(PsrpError::clixml("x").to_string().contains("CLIXML"));
assert!(
PsrpError::fragment("x")
.to_string()
.contains("fragment reassembly")
);
assert!(
PsrpError::BadState {
expected: "Opened".into(),
actual: "Opening".into(),
}
.to_string()
.contains("Opened")
);
assert_eq!(PsrpError::Stopped.to_string(), "pipeline stopped");
assert!(
PsrpError::PipelineFailed("boom".into())
.to_string()
.contains("boom")
);
assert_eq!(PsrpError::Cancelled.to_string(), "operation cancelled");
}
#[test]
fn from_winrm_error() {
let we = winrm_rs::WinrmError::Timeout(5);
let pe: PsrpError = we.into();
assert!(matches!(pe, PsrpError::Winrm(_)));
}
}