apple_quant_core/log/
ctx.rs1use std::{
2 fmt::{Display, Formatter},
3 panic::Location,
4};
5
6use tracing::Span;
7
8pub(crate) fn new_ctx(
9 message: Option<String>,
10 location: &'static Location<'static>,
11 anyhow_error: anyhow::Error,
12) -> anyhow::Error {
13 anyhow::Error::new(Ctx {
14 message,
15 location,
16 span: Span::current(),
17 anyhow_error,
18 })
19}
20
21#[derive(Debug)]
22pub(crate) struct Ctx {
23 pub(crate) message: Option<String>,
24 pub(crate) location: &'static Location<'static>,
25 pub(crate) span: Span,
26 pub(crate) anyhow_error: anyhow::Error,
27}
28
29impl Display for Ctx {
30 fn fmt(
31 &self,
32 formatter: &mut Formatter<'_>,
33 ) -> std::fmt::Result {
34 match &self.message {
35 Some(
36 message,
37 ) => formatter.write_str(message),
38 None => Display::fmt(&self.anyhow_error, formatter),
39 }
40 }
41}
42
43impl std::error::Error for Ctx {
44 fn source(
45 &self,
46 ) -> Option<
47 &(dyn std::error::Error + 'static),
48 > {
49 Some(self.anyhow_error.as_ref())
50 }
51}
52
53pub trait CtxExt<T> {
54 fn ctx(
55 self,
56 message: impl Into<String>,
57 ) -> anyhow::Result<T>;
58
59 fn ctx_with<F, S>(
60 self,
61 f: F,
62 ) -> anyhow::Result<T>
63 where
64 F: FnOnce() -> S,
65 S: Into<String>;
66
67 fn here(
68 self,
69 ) -> anyhow::Result<T>;
70}
71
72impl<
73 T,
74 E: Into<anyhow::Error>,
75> CtxExt<T> for Result<T, E> {
76 #[track_caller]
77 fn ctx(
78 self,
79 message: impl Into<String>,
80 ) -> anyhow::Result<T> {
81 let location = Location::caller();
82
83 self.map_err(|anyhow_error| {
84 new_ctx(Some(message.into()), location, anyhow_error.into())
85 })
86 }
87
88 #[track_caller]
89 fn ctx_with<F, S>(
90 self,
91 f: F,
92 ) -> anyhow::Result<T>
93 where
94 F: FnOnce() -> S,
95 S: Into<String>,
96 {
97 let location = Location::caller();
98
99 self.map_err(|anyhow_error| {
100 new_ctx(Some(f().into()), location, anyhow_error.into())
101 })
102 }
103
104 #[track_caller]
105 fn here(
106 self,
107 ) -> anyhow::Result<T> {
108 let location = Location::caller();
109 self.map_err(|anyhow_error| new_ctx(None, location, anyhow_error.into()))
110 }
111}