1use std::sync::Arc;
4
5#[derive(Clone)]
10struct SerdeArc(Arc<dyn erased_serde::Serialize + Send + Sync + 'static>);
11
12impl SerdeArc {
13 fn new<T>(value: T) -> Self
14 where
15 T: serde::Serialize + Send + Sync + 'static,
16 {
17 Self(Arc::new(value))
18 }
19}
20
21impl serde::Serialize for SerdeArc {
22 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
23 erased_serde::serialize(&*self.0, serializer)
24 }
25}
26
27#[derive(Clone)]
48pub struct LogValue(LogValueInner);
49
50#[derive(Clone)]
51enum LogValueInner {
52 Null,
53 String(String),
54 Bool(bool),
55 Char(char),
56 I64(i64),
57 U64(u64),
58 F64(f64),
59 I128(i128),
60 U128(u128),
61 Debug(Arc<dyn std::fmt::Debug + Send + Sync + 'static>),
62 Display(Arc<dyn std::fmt::Display + Send + Sync + 'static>),
63 Error(Arc<dyn std::error::Error + Send + Sync + 'static>),
64 Serde(SerdeArc),
65}
66
67impl From<LogValueInner> for LogValue {
68 fn from(inner: LogValueInner) -> Self {
69 Self(inner)
70 }
71}
72
73impl LogValue {
74 #[must_use]
76 pub fn null() -> Self {
77 LogValueInner::Null.into()
78 }
79
80 pub fn serde<S>(value: S) -> Self
82 where
83 S: serde::Serialize + Send + Sync + 'static,
84 {
85 LogValueInner::Serde(SerdeArc::new(value)).into()
86 }
87
88 pub fn display<T>(value: T) -> Self
90 where
91 T: std::fmt::Display + Send + Sync + 'static,
92 {
93 LogValueInner::Display(Arc::new(value)).into()
94 }
95
96 pub fn debug<T>(value: T) -> Self
98 where
99 T: std::fmt::Debug + Send + Sync + 'static,
100 {
101 LogValueInner::Debug(Arc::new(value)).into()
102 }
103
104 pub fn error<T>(value: T) -> Self
106 where
107 T: std::error::Error + Send + Sync + 'static,
108 {
109 LogValueInner::Error(Arc::new(value)).into()
110 }
111
112 #[must_use]
114 pub fn as_log_value(&self) -> log::kv::Value<'_> {
115 match &self.0 {
116 LogValueInner::Null => log::kv::Value::null(),
117 LogValueInner::String(s) => log::kv::Value::from(&**s),
118 LogValueInner::Bool(b) => log::kv::Value::from(*b),
119 LogValueInner::Char(c) => log::kv::Value::from(*c),
120 LogValueInner::I64(i) => log::kv::Value::from(*i),
121 LogValueInner::U64(u) => log::kv::Value::from(*u),
122 LogValueInner::F64(f) => log::kv::Value::from(*f),
123 LogValueInner::I128(i) => log::kv::Value::from(*i),
124 LogValueInner::U128(u) => log::kv::Value::from(*u),
125 LogValueInner::Display(value) => log::kv::Value::from_dyn_display(&**value),
126 LogValueInner::Debug(value) => log::kv::Value::from_dyn_debug(&**value),
127 LogValueInner::Error(value) => log::kv::Value::from_dyn_error(&**value),
128 LogValueInner::Serde(value) => log::kv::Value::from_serde(value),
129 }
130 }
131}
132
133macro_rules! impl_log_value_from_primitive {
134 ($($ty:ty => $arm:ident),*) => {
135 $(
136 impl From<$ty> for LogValue {
137 fn from(value: $ty) -> Self {
138 LogValue(LogValueInner::$arm(value.into()))
139 }
140 }
141 )*
142 };
143}
144
145impl_log_value_from_primitive!(
146 bool => Bool,
147 char => Char,
148 &str => String,
149 std::borrow::Cow<'_, str> => String,
150 String => String,
151 i8 => I64,
152 i16 => I64,
153 i32 => I64,
154 i64 => I64,
155 u8 => U64,
156 u16 => U64,
157 u32 => U64,
158 u64 => U64,
159 f32 => F64,
160 f64 => F64,
161 i128 => I128,
162 u128 => U128
163);
164
165impl std::fmt::Display for LogValue {
166 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
167 self.as_log_value().fmt(f)
168 }
169}
170
171impl std::fmt::Debug for LogValue {
172 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
173 self.as_log_value().fmt(f)
174 }
175}