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}