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}