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 {}