timber_rust/logger/
loggable.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Dante Doménech Martinez dante19031999@gmail.com
3
4#[cfg(feature = "json")]
5use serde_json::Value;
6use crate::{Message, MessageFactory};
7use std::borrow::Cow;
8use std::error::Error;
9
10/// The [`Loggable`] trait acts as a compile-time dispatcher for the [`Logger`][`crate::Logger`].
11///
12/// It utilizes Rust's monomorphization (static dispatch) to provide a
13/// pseudo-overloaded API. Each implementation handles a specific "Log Shape,"
14/// ensuring high performance and clear type separation without runtime overhead.
15pub trait Loggable {
16    /// Converts the implementing type into a unified [`Message`] object.
17    fn to_message(self) -> Message;
18}
19
20/// Identity implementation: Allows pre-constructed [`Message`]s to be logged directly.
21impl Loggable for Message {
22    fn to_message(self) -> Message {
23        self
24    }
25}
26
27/// Implementation for static string slices.
28/// This is the "Hot Path"—zero allocation is required for the message content.
29impl<S: Into<Cow<'static, str>>> Loggable for (S, &'static str) {
30    fn to_message(self) -> Message {
31        MessageFactory::string_msg(self.0, self.1)
32    }
33}
34
35/// Implementation for owned [`String`]s.
36/// Takes ownership of the string, moving it into the Message without copying.
37impl<S: Into<Cow<'static, str>>> Loggable for (S, String) {
38    fn to_message(self) -> Message {
39        MessageFactory::string_msg(self.0, self.1)
40    }
41}
42
43/// Implementation for Cow (Copy-on-Write) strings.
44/// Handles both borrowed and owned data efficiently.
45impl<S: Into<Cow<'static, str>>> Loggable for (S, Cow<'static, str>) {
46    fn to_message(self) -> Message {
47        MessageFactory::string_msg(self.0, self.1)
48    }
49}
50
51/// Implementation for String references.
52/// Performs a `.clone()` to satisfy the `'static` requirement of the [`Logger`][`crate::Logger`].
53impl<S: Into<Cow<'static, str>>> Loggable for (S, &String) {
54    fn to_message(self) -> Message {
55        MessageFactory::string_msg(self.0, self.1.clone())
56    }
57}
58
59/// Implementation for structured JSON data.
60/// **Requires** feature `json`.
61#[cfg(feature = "json")]
62#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
63impl<S: Into<Cow<'static, str>>> Loggable for (S, Value) {
64    fn to_message(self) -> Message {
65        MessageFactory::json_msg(self.0, self.1)
66    }
67}
68
69/// Implementation for Standard Library Errors.
70/// Wraps the error in a [`Box`] for rich exception logging.
71impl<S: Into<Cow<'static, str>>> Loggable for (S, Box<dyn Error + Send + Sync>) {
72    fn to_message(self) -> Message {
73        MessageFactory::error_msg(self.0, self.1)
74    }
75}