use crate::protocol::sense::{Contention, Failure, Fault, Intervention, Outcome};
use crate::transport::{self, Completion};
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
Transport(#[from] transport::Error),
#[error("{0}")]
Busy(Contention),
#[error("{0}")]
Media(Intervention),
#[error("no such scanner")]
NotFound,
#[error("{op} is not supported: {reason}")]
Unsupported { op: &'static str, reason: String },
#[error("scan cancelled")]
Cancelled,
#[error("{0}")]
Device(Box<Fault>),
}
impl From<crate::protocol::caps::Error> for Error {
fn from(e: crate::protocol::caps::Error) -> Self {
Self::Device(Box::new(Fault::Caps(e)))
}
}
impl Error {
pub fn from_outcome(outcome: Outcome, completion: &Completion) -> Self {
let sense = || completion.sense.clone();
match outcome {
Outcome::NeedsOperator(i) => Self::Media(i),
Outcome::Contended(c) => Self::Busy(c),
Outcome::Refused(r) => Self::Device(Box::new(Fault::Rejected(r, sense()))),
Outcome::Failed(f) => Self::Device(Box::new(Fault::Reported(f, sense()))),
_ => Self::Device(Box::new(Fault::Reported(Failure::Unrecognized, sense()))),
}
}
}