Skip to main content

union_error/
lib.rs

1#![forbid(unsafe_code)]
2
3use std::error::Error;
4use std::fmt::{self, Display, Formatter};
5use std::panic::Location;
6
7pub use union_error_derive::{error_union, located_error, ErrorUnion};
8
9#[doc(hidden)]
10pub mod __private {
11    #[derive(Debug, Clone, Copy)]
12    pub struct LeafSpec {
13        pub variant_name: &'static str,
14        pub leaf_type_name: &'static str,
15    }
16
17    pub trait LocatedErrorMetadata {
18        const LEAVES: &'static [LeafSpec];
19    }
20}
21
22#[derive(Debug)]
23pub struct Located<E> {
24    source: E,
25    location: &'static Location<'static>,
26}
27
28impl<E> Located<E> {
29    #[track_caller]
30    pub fn new(source: E) -> Self {
31        Self {
32            source,
33            location: Location::caller(),
34        }
35    }
36
37    pub fn source_ref(&self) -> &E {
38        &self.source
39    }
40
41    pub fn into_source(self) -> E {
42        self.source
43    }
44
45    pub fn location(&self) -> &'static Location<'static> {
46        self.location
47    }
48}
49
50impl<E> Display for Located<E>
51where
52    E: Display,
53{
54    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
55        write!(
56            f,
57            "{} (at {}:{}:{})",
58            self.source,
59            self.location.file(),
60            self.location.line(),
61            self.location.column()
62        )
63    }
64}
65
66impl<E> Error for Located<E>
67where
68    E: Error + 'static,
69{
70    fn source(&self) -> Option<&(dyn Error + 'static)> {
71        Some(&self.source)
72    }
73}