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::{
12    error::Error,
13    fmt,
14    time::Duration,
15};
16
17use crate::error::{
18    CompletionError,
19    TerminalError,
20};
21
22/// Failure from checked finish after the operation has been consumed.
23#[derive(Debug)]
24pub enum FinishError {
25    /// Completion validation failed before terminal emission.
26    Incomplete {
27        /// Elapsed operation time sampled before completion validation.
28        elapsed: Duration,
29        /// First completion invariant that failed.
30        source: CompletionError,
31    },
32    /// A terminal emission was attempted and failed permanently.
33    Terminal(TerminalError),
34}
35
36impl FinishError {
37    /// Returns elapsed operation time sampled by the finish attempt.
38    #[must_use]
39    pub const fn elapsed(&self) -> Duration {
40        match self {
41            Self::Incomplete { elapsed, .. } => *elapsed,
42            Self::Terminal(error) => error.elapsed(),
43        }
44    }
45
46    /// Returns the completion error when validation failed.
47    #[must_use]
48    pub const fn completion_error(&self) -> Option<&CompletionError> {
49        match self {
50            Self::Incomplete { source, .. } => Some(source),
51            Self::Terminal(_) => None,
52        }
53    }
54}
55
56impl fmt::Display for FinishError {
57    /// Formats the completion or terminal failure.
58    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
59        match self {
60            Self::Incomplete { source, .. } => source.fmt(formatter),
61            Self::Terminal(error) => error.fmt(formatter),
62        }
63    }
64}
65
66impl Error for FinishError {
67    /// Returns the nested completion or terminal error.
68    fn source(&self) -> Option<&(dyn Error + 'static)> {
69        match self {
70            Self::Incomplete { source, .. } => Some(source),
71            Self::Terminal(error) => Some(error),
72        }
73    }
74}