<commit_before>pub mod message;

use std::net::TcpStream;
use std::io;
use std::io::{BufReader, Write, BufRead, Error};
use irc::message::{Message, MessageError};

/// Represents an error caused by reading a [`Message`] from the server.
/// [`Message`]: message/enum.Message.html
#[derive(Debug)]
pub enum ReadLineError {
    /// The error is related to the connection.
    Connection(Error),
    /// The error is related to the attempt to parse the message received from the server.
    Message(MessageError),
}

/// Represents a TCP connection to an IRC server.
pub struct Connection {
    /// Utility field to allow easy reading from the server.
    reader: BufReader<TcpStream>,
}

impl Connection {
    /// Connects to the specified IRC server.
    pub fn new(host: &str) -> Result<Connection, io::Error> {
        let socket = TcpStream::connect(host)?;
        Ok(Connection {
            reader: BufReader::new(socket)
        })
    }

    /// Sends login credentials to the IRC server.
    pub fn login(&mut self, username: &str, oauth: &str) -> Result<(), io::Error> {
        let mut socket = self.reader.get_mut();

        writeln!(socket, "USER {} 0 * :{}", username, username)?;
        writeln!(socket, "PASS {}", oauth)?;
        writeln!(socket, "NICK {}", username)?;
        writeln!(socket, "CAP REQ :twitch.tv/membership")?;

        Ok(())
    }

    /// Sends a `&str` to the IRC server immediately.
    pub fn write_line(&mut self, string: &str) -> Result<(), io::Error> {
        let socket = self.reader.get_mut();
        writeln!(socket, "{}", string)?;
        socket.flush()
    }

    /// Reads a line directly from the connected server.
    pub fn read_line_raw(&mut self) -> Result<String, Error> {
        let mut line = String::new();
        self.reader.read_line(&mut line)?;

        Ok(line)
    }

    /// Reads a line from the server and parses a [`Message`] from it.
    /// [`Message`]: message/enum.Message.html
    pub fn read_line(&mut self) -> Result<Message, ReadLineError> {
        match self.read_line_raw() {
            Ok(line) => {
                match Message::parse(&line) {
                    Ok(msg)  => Ok(msg),
                    Err(err) => Err(ReadLineError::Message(err)),
                }
            },
            Err(err) => Err(ReadLineError::Connection(err)),
        }
    }
}<commit_msg>Simplify error handling<commit_after>pub mod message;

use std::net::TcpStream;
use std::io;
use std::io::{BufReader, Write, BufRead, Error};
use irc::message::{Message, MessageError};

/// Represents an error caused by reading a [`Message`] from the server.
/// [`Message`]: message/enum.Message.html
#[derive(Debug)]
pub enum ReadLineError {
    /// The error is related to the connection.
    Connection(Error),
    /// The error is related to the attempt to parse the message received from the server.
    Message(MessageError),
}

/// Represents a TCP connection to an IRC server.
pub struct Connection {
    /// Utility field to allow easy reading from the server.
    reader: BufReader<TcpStream>,
}

impl Connection {
    /// Connects to the specified IRC server.
    pub fn new(host: &str) -> Result<Connection, io::Error> {
        let socket = TcpStream::connect(host)?;
        Ok(Connection {
            reader: BufReader::new(socket)
        })
    }

    /// Sends login credentials to the IRC server.
    pub fn login(&mut self, username: &str, oauth: &str) -> Result<(), io::Error> {
        let mut socket = self.reader.get_mut();

        writeln!(socket, "USER {} 0 * :{}", username, username)?;
        writeln!(socket, "PASS {}", oauth)?;
        writeln!(socket, "NICK {}", username)?;
        writeln!(socket, "CAP REQ :twitch.tv/membership")?;

        Ok(())
    }

    /// Sends a `&str` to the IRC server immediately.
    pub fn write_line(&mut self, string: &str) -> Result<(), io::Error> {
        let socket = self.reader.get_mut();
        writeln!(socket, "{}", string)?;
        socket.flush()
    }

    /// Reads a line directly from the connected server.
    pub fn read_line_raw(&mut self) -> Result<String, Error> {
        let mut line = String::new();
        self.reader.read_line(&mut line)?;

        Ok(line)
    }

    /// Reads a line from the server and parses a [`Message`] from it.
    /// [`Message`]: message/enum.Message.html
    pub fn read_line(&mut self) -> Result<Message, ReadLineError> {
        match self.read_line_raw() {
            Ok(line) => Message::parse(&line).map_err(ReadLineError::Message),
            Err(err) => Err(ReadLineError::Connection(err)),
        }
    }
}
{'fraction_non_alphanumeric': 0.14912090297373562, 'fraction_numerical': 0.0004341219882787063, 'mean_word_length': 2.6, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 31, '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': '3469163', 'n_tokens_mistral': 1371, 'n_tokens_neox': 1357, 'n_words': 415}