1pub struct ContextValue(ContextValueInner);
23
24enum ContextValueInner {
25 Null,
26 String(String),
27 Bool(bool),
28 Char(char),
29 I64(i64),
30 U64(u64),
31 F64(f64),
32 I128(i128),
33 U128(u128),
34 Debug(Box<dyn std::fmt::Debug + Send + Sync + 'static>),
35 Display(Box<dyn std::fmt::Display + Send + Sync + 'static>),
36 Error(Box<dyn std::error::Error + Send + Sync + 'static>),
37 Serde(Box<dyn erased_serde::Serialize + Send + Sync + 'static>),
38}
39
40impl From<ContextValueInner> for ContextValue {
41 fn from(inner: ContextValueInner) -> Self {
42 Self(inner)
43 }
44}
45
46impl ContextValue {
47 #[allow(clippy::must_use_candidate)]
49 pub fn null() -> Self {
50 ContextValueInner::Null.into()
51 }
52
53 pub fn serde<S>(value: S) -> Self
55 where
56 S: serde::Serialize + Send + Sync + 'static,
57 {
58 let value = Box::new(value);
59 ContextValueInner::Serde(value).into()
60 }
61
62 pub fn display<T>(value: T) -> Self
64 where
65 T: std::fmt::Display + Send + Sync + 'static,
66 {
67 let value = Box::new(value);
68 ContextValueInner::Display(value).into()
69 }
70
71 pub fn debug<T>(value: T) -> Self
73 where
74 T: std::fmt::Debug + Send + Sync + 'static,
75 {
76 let value = Box::new(value);
77 ContextValueInner::Debug(value).into()
78 }
79
80 pub fn error<T>(value: T) -> Self
82 where
83 T: std::error::Error + Send + Sync + 'static,
84 {
85 let value = Box::new(value);
86 ContextValueInner::Error(value).into()
87 }
88
89 #[must_use]
91 pub fn as_log_value(&self) -> log::kv::Value<'_> {
92 match &self.0 {
93 ContextValueInner::Null => log::kv::Value::null(),
94 ContextValueInner::String(s) => log::kv::Value::from(&**s),
95 ContextValueInner::Bool(b) => log::kv::Value::from(*b),
96 ContextValueInner::Char(c) => log::kv::Value::from(*c),
97 ContextValueInner::I64(i) => log::kv::Value::from(*i),
98 ContextValueInner::U64(u) => log::kv::Value::from(*u),
99 ContextValueInner::F64(f) => log::kv::Value::from(*f),
100 ContextValueInner::I128(i) => log::kv::Value::from(*i),
101 ContextValueInner::U128(u) => log::kv::Value::from(*u),
102 ContextValueInner::Display(value) => log::kv::Value::from_dyn_display(value),
103 ContextValueInner::Debug(value) => log::kv::Value::from_dyn_debug(value),
104 ContextValueInner::Error(value) => log::kv::Value::from_dyn_error(&**value),
105 ContextValueInner::Serde(value) => log::kv::Value::from_serde(value),
106 }
107 }
108}
109
110macro_rules! impl_context_value_from_primitive {
111 ($($ty:ty => $arm:ident),*) => {
112 $(
113 impl From<$ty> for ContextValue {
114 fn from(value: $ty) -> Self {
115 ContextValue(ContextValueInner::$arm(value.into()))
116 }
117 }
118 )*
119 };
120}
121
122impl_context_value_from_primitive!(
123 bool => Bool,
124 char => Char,
125 &str => String,
126 std::borrow::Cow<'_, str> => String,
127 String => String,
128 i8 => I64,
129 i16 => I64,
130 i32 => I64,
131 i64 => I64,
132 u8 => U64,
133 u16 => U64,
134 u32 => U64,
135 u64 => U64,
136 f64 => F64,
137 i128 => I128,
138 u128 => U128
139);
140
141impl std::fmt::Display for ContextValue {
142 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
143 self.as_log_value().fmt(f)
144 }
145}
146
147impl std::fmt::Debug for ContextValue {
148 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149 self.as_log_value().fmt(f)
150 }
151}