Skip to main content

qubit_progress/error/
reporter_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 directly by reporter sinks.
9// qubit-style: allow source-test-pair
10
11use std::{
12    error::Error,
13    fmt,
14    sync::Arc,
15};
16
17/// Reporter failure that preserves its original error chain.
18#[derive(Clone, Debug)]
19pub struct ReporterError {
20    source: Arc<dyn Error + Send + Sync + 'static>,
21}
22
23impl ReporterError {
24    /// Wraps a concrete reporter failure without discarding its source.
25    pub fn new<E>(source: E) -> Self
26    where
27        E: Error + Send + Sync + 'static,
28    {
29        Self {
30            source: Arc::new(source),
31        }
32    }
33
34    /// Creates a reporter error from a stable message.
35    pub fn message(message: &str) -> Self {
36        Self::new(MessageError(message.into()))
37    }
38
39    /// Returns the original reporter error.
40    #[must_use]
41    pub fn source_error(&self) -> &(dyn Error + Send + Sync + 'static) {
42        self.source.as_ref()
43    }
44}
45
46impl fmt::Display for ReporterError {
47    /// Formats the original reporter error.
48    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
49        self.source.fmt(formatter)
50    }
51}
52
53impl Error for ReporterError {
54    /// Returns the original reporter error as the source.
55    fn source(&self) -> Option<&(dyn Error + 'static)> {
56        Some(self.source.as_ref())
57    }
58}
59
60/// Message-backed error used by [`ReporterError::message`].
61#[derive(Debug)]
62struct MessageError(String);
63
64impl fmt::Display for MessageError {
65    /// Formats the stored message.
66    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
67        formatter.write_str(&self.0)
68    }
69}
70
71impl Error for MessageError {}