<commit_before>use super::Encoder;
use flowgger::config::Config;
use flowgger::record::{Record, SDValue};
use serde_json;
use serde_json::builder::ObjectBuilder;
use serde_json::value::Value;

#[derive(Clone)]
pub struct GelfEncoder {
    extra: Vec<(String, String)>,
}

impl GelfEncoder {
    pub fn new(config: &Config) -> GelfEncoder {
        let extra = match config.lookup("output.gelf_extra") {
            None => Vec::new(),
            Some(extra) => extra
                .as_table()
                .expect("output.gelf_extra must be a list of key/value pairs")
                .into_iter()
                .map(|(k, v)| {
                    (
                        k.to_owned(),
                        v.as_str()
                            .expect("output.gelf_extra values must be strings")
                            .to_owned(),
                    )
                }).collect(),
        };
        GelfEncoder { extra: extra }
    }
}

impl Encoder for GelfEncoder {
    fn encode(&self, record: Record) -> Result<Vec<u8>, &'static str> {
        let mut map = ObjectBuilder::new()
            .insert("version".to_owned(), Value::String("1.1".to_owned()))
            .insert(
                "host".to_owned(),
                Value::String(record.hostname.unwrap_or_else(|| "unknown".to_owned())),
            ).insert(
                "short_message".to_owned(),
                Value::String(record.msg.unwrap_or_else(|| "-".to_owned())),
            ).insert("timestamp".to_owned(), Value::F64(record.ts));
        if let Some(severity) = record.severity {
            map = map.insert("level".to_owned(), Value::U64(u64::from(severity)));
        }
        if let Some(full_msg) = record.full_msg {
            map = map.insert("full_message".to_owned(), Value::String(full_msg));
        }
        if let Some(appname) = record.appname {
            map = map.insert("application_name".to_owned(), Value::String(appname));
        }
        if let Some(procid) = record.procid {
            map = map.insert("process_id".to_owned(), Value::String(procid));
        }
        for (name, value) in self.extra.iter().cloned() {
            map = map.insert(name, Value::String(value));
        }<commit_msg>unwrap_or_else() obviously won't work on a string<commit_after>use super::Encoder;
use flowgger::config::Config;
use flowgger::record::{Record, SDValue};
use serde_json;
use serde_json::builder::ObjectBuilder;
use serde_json::value::Value;

#[derive(Clone)]
pub struct GelfEncoder {
    extra: Vec<(String, String)>,
}

impl GelfEncoder {
    pub fn new(config: &Config) -> GelfEncoder {
        let extra = match config.lookup("output.gelf_extra") {
            None => Vec::new(),
            Some(extra) => extra
                .as_table()
                .expect("output.gelf_extra must be a list of key/value pairs")
                .into_iter()
                .map(|(k, v)| {
                    (
                        k.to_owned(),
                        v.as_str()
                            .expect("output.gelf_extra values must be strings")
                            .to_owned(),
                    )
                }).collect(),
        };
        GelfEncoder { extra: extra }
    }
}

impl Encoder for GelfEncoder {
    fn encode(&self, record: Record) -> Result<Vec<u8>, &'static str> {
        let mut map = ObjectBuilder::new()
            .insert("version".to_owned(), Value::String("1.1".to_owned()))
            .insert(
                "host".to_owned(),
                Value::String(if record.hostname.is_empty() {
                    "unknown".to_owned()
                } else {
                    record.hostname
                }),
            ).insert(
                "short_message".to_owned(),
                Value::String(record.msg.unwrap_or_else(|| "-".to_owned())),
            ).insert("timestamp".to_owned(), Value::F64(record.ts));
        if let Some(severity) = record.severity {
            map = map.insert("level".to_owned(), Value::U64(u64::from(severity)));
        }
        if let Some(full_msg) = record.full_msg {
            map = map.insert("full_message".to_owned(), Value::String(full_msg));
        }
        if let Some(appname) = record.appname {
            map = map.insert("application_name".to_owned(), Value::String(appname));
        }
        if let Some(procid) = record.procid {
            map = map.insert("process_id".to_owned(), Value::String(procid));
        }
        for (name, value) in self.extra.iter().cloned() {
            map = map.insert(name, Value::String(value));
        }
{'fraction_non_alphanumeric': 0.14893617021276595, 'fraction_numerical': 0.0039079461571862786, 'mean_word_length': 1.8597144630664184, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4024573', 'n_tokens_mistral': 1355, 'n_tokens_neox': 1323, 'n_words': 253}