Skip to main content

qubit_progress/error/
finish_error.rs

1// =============================================================================
2//    Copyright (c) 2025 - 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Errors returned by checked successful completion.
9// qubit-style: allow source-test-pair
10
11use std::error::Error;
12use std::fmt;
13use std::time::Duration;
14
15use crate::error::CompletionError;
16use crate::error::TerminalError;
17
18/// Failure from checked finish after the operation has been consumed.
19#[derive(Debug)]
20pub enum FinishError {
21    /// Completion validation failed before terminal emission.
22    Incomplete {
23        /// Elapsed operation time sampled before completion validation.
24        elapsed: Duration,
25        /// First completion invariant that failed.
26        source: CompletionError,
27    },
28    /// A terminal emission was attempted and failed permanently.
29    Terminal(TerminalError),
30}
31
32impl FinishError {
33    /// Returns elapsed operation time sampled by the finish attempt.
34    #[must_use]
35    pub const fn elapsed(&self) -> Duration {
36        match self {
37            Self::Incomplete { elapsed, .. } => *elapsed,
38            Self::Terminal(error) => error.elapsed(),
39        }
40    }
41
42    /// Returns the completion error when validation failed.
43    #[must_use]
44    pub const fn completion_error(&self) -> Option<&CompletionError> {
45        match self {
46            Self::Incomplete { source, .. } => Some(source),
47            Self::Terminal(_) => None,
48        }
49    }
50}
51
52impl fmt::Display for FinishError {
53    /// Formats the completion or terminal failure.
54    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
55        match self {
56            Self::Incomplete { source, .. } => source.fmt(formatter),
57            Self::Terminal(error) => error.fmt(formatter),
58        }
59    }
60}
61
62impl Error for FinishError {
63    /// Returns the nested completion or terminal error.
64    fn source(&self) -> Option<&(dyn Error + 'static)> {
65        match self {
66            Self::Incomplete { source, .. } => Some(source),
67            Self::Terminal(error) => Some(error),
68        }
69    }
70}