Skip to main content

init_static/
error.rs

1use crate::Symbol;
2
3/// Error type returned by [`init_static()`](crate::init_static()) when initialization fails.
4///
5/// This enum represents the various failure modes that can occur during the static initialization
6/// process.
7///
8/// ## Note on Execution Errors
9///
10/// Errors returned by initialization expressions (e.g., `"42".parse()?`) are **NOT**
11/// wrapped in this enum. Instead, [`init_static()`](crate::init_static()) returns
12/// [`anyhow::Result<()>`] directly, which preserves the original error's backtrace for better
13/// debugging.
14///
15/// To distinguish between error types, use [`anyhow::Error::downcast`] or
16/// [`anyhow::Error::downcast_ref`].
17#[derive(Debug)]
18pub enum InitError {
19    /// A static symbol was defined multiple times.
20    ///
21    /// This typically occurs when the same [`init_static!`](crate::init_static!) block is included
22    /// multiple times, or when two statics in different modules have the exact same source
23    /// location metadata (which should not happen in normal usage).
24    Ambiguous { symbol: &'static Symbol },
25
26    /// A circular dependency was detected among statics.
27    ///
28    /// This occurs when static A depends on static B, and static B (directly or indirectly) depends
29    /// on static A. The initialization system cannot determine a valid order to initialize such
30    /// statics.
31    ///
32    /// # Example
33    ///
34    /// ```ignore
35    /// use init_static::init_static;
36    ///
37    /// init_static! {
38    ///     // This creates a circular dependency and will fail at runtime
39    ///     static A: u32 = *B + 1;
40    ///     static B: u32 = *A + 1;
41    /// }
42    /// ```
43    Circular { symbols: Vec<&'static Symbol> },
44}
45
46impl std::fmt::Display for InitError {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        match self {
49            Self::Ambiguous { symbol } => {
50                write!(f, "Symbol {symbol} is defined multiple times.")
51            }
52            Self::Circular { symbols } => {
53                writeln!(f, "Circular dependency detected among:")?;
54                for symbol in symbols {
55                    writeln!(f, "    {symbol}")?;
56                }
57                Ok(())
58            }
59        }
60    }
61}
62
63impl std::error::Error for InitError {}