#[cfg(feature = "json")]
use serde_json::Value;
use std::any::Any;
use std::borrow::Cow;
use std::error::Error;
use std::fmt::Display;
use std::time::SystemTime;
pub trait MessageImpl: Send + Sync + Any {
fn level(&self) -> &dyn Display;
fn content(&self) -> &dyn Display;
fn instant(&self) -> SystemTime;
fn as_any(&self) -> &dyn Any;
}
pub struct StringMessageImpl {
level: Cow<'static, str>,
content: Cow<'static, str>,
instant: SystemTime,
}
impl MessageImpl for StringMessageImpl {
fn level(&self) -> &dyn Display {
&self.level
}
fn content(&self) -> &dyn Display {
&self.content
}
fn instant(&self) -> SystemTime {
self.instant
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl StringMessageImpl {
pub fn get_string(&self) -> &str {
&self.content
}
}
#[cfg(feature = "json")]
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
pub struct JsonMessageImpl {
pub(crate) level: Cow<'static, str>,
pub(crate) content: Value,
instant: SystemTime,
}
#[cfg(feature = "json")]
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
impl MessageImpl for JsonMessageImpl {
fn level(&self) -> &dyn Display {
&self.level
}
fn content(&self) -> &dyn Display {
&self.content
}
fn instant(&self) -> SystemTime {
self.instant
}
fn as_any(&self) -> &dyn Any {
self
}
}
#[cfg(feature = "json")]
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
impl JsonMessageImpl {
pub fn json(&self) -> &Value {
&self.content
}
}
pub struct ErrorMessageImpl {
level: Cow<'static, str>,
content: Box<dyn Error + Send + Sync>,
instant: SystemTime,
}
impl MessageImpl for ErrorMessageImpl {
fn level(&self) -> &dyn Display {
&self.level
}
fn content(&self) -> &dyn Display {
&self.content
}
fn instant(&self) -> SystemTime {
self.instant
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl ErrorMessageImpl {
pub fn error(&self) -> &dyn Error {
&*self.content
}
}
pub struct Message {
m_impl: Box<dyn MessageImpl + Send + Sync>,
}
impl Message {
pub fn new(m_impl: Box<dyn MessageImpl + Send + Sync>) -> Self {
Message { m_impl }
}
pub fn level(&self) -> &dyn Display {
self.m_impl.level()
}
pub fn content(&self) -> &dyn Display {
self.m_impl.content()
}
pub fn instant(&self) -> SystemTime {
self.m_impl.instant()
}
pub fn implementation(&self) -> &dyn MessageImpl {
&*self.m_impl
}
pub fn unwrap(self) -> Box<dyn MessageImpl + Send + Sync> {
self.m_impl
}
}
pub struct MessageFactory {}
impl MessageFactory {
pub fn string_msg<S1, S2>(level: S1, content: S2) -> Message
where
S1: Into<Cow<'static, str>>,
S2: Into<Cow<'static, str>>,
{
Message {
m_impl: Box::new(StringMessageImpl {
level: level.into(),
content: content.into(),
instant: SystemTime::now(),
}),
}
}
#[cfg(feature = "json")]
pub fn json_msg<S>(level: S, content: Value) -> Message
where
S: Into<Cow<'static, str>>,
{
Message {
m_impl: Box::new(JsonMessageImpl {
level: level.into(),
content: content.into(),
instant: SystemTime::now(),
}),
}
}
pub fn error_msg<S>(level: S, content: Box<dyn Error + Send + Sync>) -> Message
where
S: Into<Cow<'static, str>>,
{
Message {
m_impl: Box::new(ErrorMessageImpl {
level: level.into(),
content,
instant: SystemTime::now(),
}),
}
}
}