<commit_before>use std::net::ToSocketAddrs;
use std::convert::AsRef;
use std::net;
use std::io::Write;
use rustc_serialize::Encodable;
use time;
use record::Record;
use record::FluentError;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Fluent<A>
    where A: ToSocketAddrs
{
    addr: A,
    tag: String,
}

impl<A: ToSocketAddrs> Fluent<A> {
    /// Create Fluent type.
    ///
    /// ### Usage
    ///
    /// ```
    /// use fruently::fluent::Fluent;
    /// let fruently_with_str_tag = Fluent::new("0.0.0.0:24224", "test");
    /// let fruently_with_string_tag = Fluent::new("0.0.0.0:24224", "test".to_string());
    /// ```
    pub fn new<T>(addr: A, tag: T) -> Fluent<A>
        where T: AsRef<str>
    {
        Fluent {
            addr: addr,
            tag: format!("{}", tag.as_ref()),
        }
    }

    /// Post record into Fluentd. Without time version.
    pub fn post<T>(self, record: T) -> Result<(), FluentError>
        where T: Encodable
    {
        let time = time::now();
        return self.post_with_time(record, time);
    }

    /// Post record into Fluentd. With time version.
    pub fn post_with_time<T>(self, record: T, time: time::Tm) -> Result<(), FluentError>
        where T: Encodable
    {
        let record = Record::new(self.tag, time, record);
        let message = try!(record.make_forwardable_json());
        let mut stream = try!(net::TcpStream::connect(self.addr));
        let _ = stream.write(&message.into_bytes());
        drop(stream);

        Ok(())
    }
}

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

    #[test]
    fn create_fruently() {
        let fruently = Fluent::new("0.0.0.0:24224", "test");
        let expected = Fluent {
            addr: "0.0.0.0:24224",
            tag: "test".to_string(),
        };
        assert_eq!(expected, fruently);
    }

    #[test]
    #[cfg(feature="fluentd")]
    fn post_to_fluentd() {
        use std::collections::HashMap;

        let fruently = Fluent::new("0.0.0.0:24224", "test");
        let mut obj: HashMap<String, String> = HashMap::new();
        obj.insert("hey".to_string(), "Rust!".to_string());
        let result = fruently.post(obj);
        let is_ok = match result {
            Ok(()) => true,
            _ => false,
        };
        assert_eq!(true, is_ok);
    }
}
<commit_msg>fluent: Handle error properly<commit_after>use std::net::ToSocketAddrs;
use std::convert::AsRef;
use std::net;
use std::io::Write;
use rustc_serialize::Encodable;
use time;
use record::Record;
use record::FluentError;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Fluent<A>
    where A: ToSocketAddrs
{
    addr: A,
    tag: String,
}

impl<A: ToSocketAddrs> Fluent<A> {
    /// Create Fluent type.
    ///
    /// ### Usage
    ///
    /// ```
    /// use fruently::fluent::Fluent;
    /// let fruently_with_str_tag = Fluent::new("0.0.0.0:24224", "test");
    /// let fruently_with_string_tag = Fluent::new("0.0.0.0:24224", "test".to_string());
    /// ```
    pub fn new<T>(addr: A, tag: T) -> Fluent<A>
        where T: AsRef<str>
    {
        Fluent {
            addr: addr,
            tag: format!("{}", tag.as_ref()),
        }
    }

    /// Post record into Fluentd. Without time version.
    pub fn post<T>(self, record: T) -> Result<(), FluentError>
        where T: Encodable
    {
        let time = time::now();
        return self.post_with_time(record, time);
    }

    /// Post record into Fluentd. With time version.
    pub fn post_with_time<T>(self, record: T, time: time::Tm) -> Result<(), FluentError>
        where T: Encodable
    {
        let record = Record::new(self.tag, time, record);
        let message = try!(record.make_forwardable_json());
        let mut stream = try!(net::TcpStream::connect(self.addr));
        let result = stream.write(&message.into_bytes());
        drop(stream);

        match result {
            Ok(_) => Ok(()),
            Err(v) => Err(From::from(v)),
        }
    }
}

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

    #[test]
    fn create_fruently() {
        let fruently = Fluent::new("0.0.0.0:24224", "test");
        let expected = Fluent {
            addr: "0.0.0.0:24224",
            tag: "test".to_string(),
        };
        assert_eq!(expected, fruently);
    }

    #[test]
    #[cfg(feature="fluentd")]
    fn post_to_fluentd() {
        use std::collections::HashMap;

        let fruently = Fluent::new("0.0.0.0:24224", "test");
        let mut obj: HashMap<String, String> = HashMap::new();
        obj.insert("hey".to_string(), "Rust!".to_string());
        let result = fruently.post(obj);
        let is_ok = match result {
            Ok(()) => true,
            _ => false,
        };
        assert_eq!(true, is_ok);
    }
}

{'fraction_non_alphanumeric': 0.17588682432432431, 'fraction_numerical': 0.01900337837837838, 'mean_word_length': 2.269151138716356, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 10, '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': '2302234', 'n_tokens_mistral': 1663, 'n_tokens_neox': 1638, 'n_words': 353}