use std::error::Error;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result as FmtResult;
use crate::error::FsError;
use crate::write::WriteFailureState;
use crate::write::WriterRecovery;
pub struct WriteAllFailure {
error: Box<FsError>,
state: WriteFailureState,
written_bytes: u64,
writer: Option<WriterRecovery>,
}
impl WriteAllFailure {
pub(crate) fn new(
error: FsError,
state: WriteFailureState,
written_bytes: u64,
writer: Option<WriterRecovery>,
) -> Self {
Self {
error: Box::new(error),
state,
written_bytes,
writer,
}
}
#[inline]
#[must_use]
pub const fn error(&self) -> &FsError {
&self.error
}
#[must_use]
pub const fn state(&self) -> WriteFailureState {
self.state
}
#[must_use]
pub const fn written_bytes(&self) -> u64 {
self.written_bytes
}
#[must_use]
pub fn take_recovery(&mut self) -> Option<WriterRecovery> {
self.writer.take()
}
#[inline]
#[must_use]
pub fn recovery(&self) -> Option<&WriterRecovery> {
self.writer.as_ref()
}
#[inline]
#[must_use]
pub fn recovery_mut(&mut self) -> Option<&mut WriterRecovery> {
self.writer.as_mut()
}
#[inline]
#[must_use]
pub fn into_parts(self) -> (FsError, WriteFailureState, u64, Option<WriterRecovery>) {
(*self.error, self.state, self.written_bytes, self.writer)
}
}
impl Display for WriteAllFailure {
#[inline]
fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
self.error.fmt(formatter)
}
}
impl std::fmt::Debug for WriteAllFailure {
#[inline]
fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
formatter
.debug_struct("WriteAllFailure")
.field("error", &self.error)
.field("state", &self.state)
.field("written_bytes", &self.written_bytes)
.field("has_recovery", &self.writer.is_some())
.finish()
}
}
impl Error for WriteAllFailure {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(self.error.as_ref())
}
}
#[cfg(test)]
mod tests {
use std::hint::black_box;
use super::WriteAllFailure;
use crate::error::FsError;
use crate::error::FsErrorKind;
use crate::error::FsOperation;
use crate::write::WriteFailureState;
#[test]
fn failure_accessors_are_executed_at_runtime() {
let error: fn(&WriteAllFailure) -> &FsError = black_box(WriteAllFailure::error);
let recovery: fn(&WriteAllFailure) -> Option<&crate::write::WriterRecovery> =
black_box(WriteAllFailure::recovery);
let failure = WriteAllFailure::new(
FsError::new(FsErrorKind::NotFound, FsOperation::OpenWriter, "missing target"),
WriteFailureState::NotPublished,
4,
None,
);
assert_eq!(FsErrorKind::NotFound, error(&failure).kind());
assert!(recovery(&failure).is_none());
}
}