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}