carboncopy 0.3.0

A user (programmer) interface for asynchronous logging in Rust
Documentation
use super::{Entry, Level};
use data_encoding::BASE64URL_NOPAD;
use serde::{Serialize, Serializer};

#[derive(Serialize)]
pub struct EntryContainer<T: Clone + Serialize> {
    lvl: Level,

    #[serde(flatten)]
    entry: Entry<T>,
}

pub fn serialize<T: Clone + Serialize>(entry: Entry<T>, level: Level) -> String {
    serde_json::to_string(&EntryContainer::<T> {
        lvl: level,
        entry: entry,
    })
    .unwrap() // TODO: examine if will explode
}

pub fn as_base64<S>(vec: &Option<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    // unwrap safety: function wouldn't be called if vec == None
    serializer.serialize_str(BASE64URL_NOPAD.encode(vec.as_ref().unwrap()).as_str())
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::Tags;

    #[test]
    fn serialize_text_message() {
        let entry1 = Entry::<String>::new("asffdf".into(), false, None, None);
        assert_eq!(
            "{\"lvl\":\"FATAL\",\"msg\":\"asffdf\"}\n",
            entry1.json(Level::FATAL)
        );

        let entry2 = Entry::<String>::new(
            "today is Monday".into(),
            true,
            Some(vec![191, 22, 213, 49, 5, 60, 166]),
            Some(Tags::new(vec!["abc".into(), "def".into()]).unwrap()),
        );
        let time = entry2.created.unwrap();
        assert_eq!(
            format!(
                "{{\"lvl\":\"DEBUG\",\"msg\":\"today is Monday\",\"ts\":\"{}\",\"spid\":\"vxbVMQU8pg\",\"tags\":[\"abc\",\"def\"]}}\n",
                time.to_rfc3339_opts(chrono::SecondsFormat::Nanos, true)
            ),
            entry2.json(Level::DEBUG)
        );
    }

    #[test]
    fn serialize_composite_json() {
        // dummy type
        #[derive(Clone, Serialize)]
        struct JsonMessage {
            name: String,
            age: i32,
        }

        let entry = Entry::<JsonMessage>::new(
            JsonMessage {
                name: "John Smith".into(),
                age: 99,
            },
            false,
            None,
            Some(Tags::new(vec!["1234".into()]).unwrap()),
        );
        assert_eq!(
            entry.json(Level::TRACE),
            "{\"lvl\":\"TRACE\",\"msg\":{\"name\":\"John Smith\",\"age\":99},\"tags\":[\"1234\"]}\n",
        );
    }
}