qubit_fs/spi/spi_copy_failure.rs
1// =============================================================================
2// Copyright (c) 2026 Haixing Hu.
3//
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0.
7// =============================================================================
8// facade.
9//! Provider copy failure facts.
10
11use crate::copy::CopyFailureState;
12use crate::copy::CopyStats;
13use crate::error::FsError;
14
15/// Typed provider copy failure reserved for copy orchestration.
16///
17/// # Examples
18///
19/// ```rust
20/// use qubit_fs::copy::CopyFailureState;
21/// use qubit_fs::copy::CopyStats;
22/// use qubit_fs::error::{FsError, FsErrorKind, FsOperation};
23/// use qubit_fs::spi::SpiCopyFailure;
24///
25/// let failure = SpiCopyFailure::new(
26/// FsError::new(FsErrorKind::Io, FsOperation::Copy, "failed"),
27/// CopyFailureState::Unchanged,
28/// CopyStats::default(),
29/// );
30/// assert_eq!(CopyFailureState::Unchanged, failure.state());
31/// ```
32pub struct SpiCopyFailure {
33 /// Provider failure with filesystem context.
34 error: Box<FsError>,
35 /// Provider-confirmed destination publication state.
36 state: CopyFailureState,
37 /// Transfer progress confirmed before failure.
38 partial_stats: CopyStats,
39}
40
41impl SpiCopyFailure {
42 /// Creates a typed provider copy failure.
43 ///
44 /// # Parameters
45 /// - `error`: Provider failure with filesystem context.
46 /// - `state`: Provider-confirmed publication state.
47 /// - `partial_stats`: Transfer progress confirmed before failure.
48 ///
49 /// # Returns
50 /// A failure containing all provider-confirmed facts.
51 #[inline]
52 #[must_use]
53 pub fn new(error: FsError, state: CopyFailureState, partial_stats: CopyStats) -> Self {
54 Self {
55 error: Box::new(error),
56 state,
57 partial_stats,
58 }
59 }
60
61 /// Returns the provider error without exposing a recovery writer.
62 ///
63 /// # Returns
64 /// The provider failure with filesystem context.
65 #[inline]
66 #[must_use]
67 pub fn error(&self) -> &FsError {
68 &self.error
69 }
70
71 /// Returns the typed publication state.
72 ///
73 /// # Returns
74 /// The provider-confirmed publication state.
75 #[inline]
76 #[must_use]
77 pub const fn state(&self) -> CopyFailureState {
78 self.state
79 }
80
81 /// Splits this failure into its typed facts.
82 ///
83 /// # Returns
84 /// The provider error, publication state, and partial transfer statistics.
85 #[inline]
86 #[must_use]
87 pub fn into_parts(self) -> (FsError, CopyFailureState, CopyStats) {
88 (*self.error, self.state, self.partial_stats)
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::SpiCopyFailure;
95 use crate::copy::CopyFailureState;
96 use crate::copy::CopyStats;
97 use crate::error::FsError;
98 use crate::error::FsErrorKind;
99 use crate::error::FsOperation;
100
101 #[test]
102 fn failure_facts_are_executed_at_runtime() {
103 let failure = SpiCopyFailure::new(
104 FsError::new(FsErrorKind::NotFound, FsOperation::Copy, "missing source"),
105 CopyFailureState::PartiallyPublished,
106 CopyStats {
107 bytes: 4,
108 ..CopyStats::default()
109 },
110 );
111 assert_eq!(failure.error().kind(), FsErrorKind::NotFound);
112 assert_eq!(failure.state(), CopyFailureState::PartiallyPublished);
113
114 let (error, state, stats) = failure.into_parts();
115 assert_eq!(error.kind(), FsErrorKind::NotFound);
116 assert_eq!(state, CopyFailureState::PartiallyPublished);
117 assert_eq!(stats.bytes, 4);
118 }
119}