<commit_before>use std::collections::HashMap;
use std::io;
use std::slice::Iter;

use listener::Listener;
use settings::Settings;
use loirc::{self, connect};
use loirc::{ActivityMonitor, Code, Event, Message, Prefix, Writer};

/// Represents the status of a user inside of a channel.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ChannelUserStatus {
    /// User has special status.
    Normal,
    /// User has voice status.
    Voice,
    /// User has operator status.
    Operator,
    /// User has owner status.
    Owner,
}

/// Represents a user inside of a channel.
#[derive(Debug)]
pub struct ChannelUser {
    /// Nickname of the user.
    pub nickname: String,
    /// Status of the user inside the channel.
    pub status: ChannelUserStatus,
}

impl ChannelUser {

    fn from_raw(raw: &str) -> ChannelUser {
        let status = match raw.chars().next() {
            Some('&') => ChannelUserStatus::Owner,
            Some('@') => ChannelUserStatus::Operator,
            Some('+') => ChannelUserStatus::Voice,
            _ => ChannelUserStatus::Normal,
        };
        ChannelUser {
            nickname: (if status == ChannelUserStatus::Normal { raw } else { &raw[1..] }).into(),
            status: status,
        }
    }
}

/// Represents a channel.
#[derive(Debug)]
pub struct Channel {
    users: Vec<ChannelUser>,
    /// Name of the channel.
    pub name: String,
    /// Topic of the channel.
    pub topic: Option<String>,
}

impl Channel {

    /// Get a user by nickname from this channel.
    pub fn get_user(&self, nickname: &str) -> Option<&ChannelUser> {
        match self.users.iter().position(|u| u.nickname == nickname) {
            Some(idx) => Some(&self.users[idx]),
            None => None,
        }
    }

    /// Get a mutable reference to a user by nickname.
    fn get_user_mut(&mut self, nickname: &str) -> Option<&mut ChannelUser> {
        match self.users.iter_mut().position(|u| u.nickname == nickname) {
            Some(idx) => Some(&mut self.users[idx]),
            None => None,
        }
    }

    /// Get an iterator that iterates over the channel's users.
    pub fn users(&self) -> Iter<ChannelUser> {
        self.users.iter()
    }

}
/// Status of the connection.
#[derive(Debug)]
pub enum ConnectionStatus {
    /// Connection was closed.
    Closed(&'static str),
    /// Connection is alive.
    Connected,
    /// Connection was dropped.
    Disconnected,
    /// Attempting to reconnect.
    Reconnecting,
}

/// Errors that can occur.
#[derive(Debug)]
pub enum Error {
    /// Connection is already closed.
    AlreadyClosed,
    /// Connection is already disconnected.
    AlreadyDisconnected,
    /// Connection was manually closed.
    Closed,
    /// Connection was dropped.
    ///
    /// A reconnection might be in process.
    Disconnected,
    /// I/O error.
    IoError(io::Error),
    /// The message contains a line break.
    Multiline,
}

impl From<loirc::Error> for Error {
    fn from(err: loirc::Error) -> Error {
        match err {
            loirc::Error::AlreadyClosed => Error::AlreadyClosed,
            loirc::Error::AlreadyDisconnected => Error::AlreadyDisconnected,
            loirc::Error::Closed => Error::Closed,
            loirc::Error::Disconnected => Error::Disconnected,
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::IoError(err)
    }
}

/// Represents the state of this connection.
pub struct Irc {
    writer: Writer,
    channels: HashMap<String, Channel>,
    /// Status of the connection.
    pub status: ConnectionStatus,
}

impl Irc {

    fn new(writer: Writer) -> Irc {
        Irc {
            writer: writer,
            status: ConnectionStatus::Connected,
            channels: HashMap::new(),
        }
    }

    /// Get a channel by name.
    pub fn get_channel_by_name(&self, name: &str) -> Option<&Channel> {
        self.get_channel_by_id(&name.to_lowercase())
    }

    /// Get a channel by id.
    pub fn get_channel_by_id(&self, id: &str) -> Option<&Channel> {
        self.channels.get(id)
    }

    // Ensure a channel if it does not exist.
    fn ensure_channel_exists(&mut self, name: &str, id: &str) {
        if !self.channels.contains_key(id) {
            self.channels.insert(id.into(), Channel {
                name: name.into(),
                users: Vec::new(),
                topic: None,
            });
        }
    }

    fn channel_set_topic(&mut self, channel_id: &str, topic: &str) {
        let channel = some_or_return!(self.channels.get_mut(channel_id));
        channel.topic = if topic.len() == 0 {
            None
        } else {
            Some(topic.into())
        };
    }
<commit_msg>Make get_channel_by_id private<commit_after>use std::collections::HashMap;
use std::io;
use std::slice::Iter;

use listener::Listener;
use settings::Settings;
use loirc::{self, connect};
use loirc::{ActivityMonitor, Code, Event, Message, Prefix, Writer};

/// Represents the status of a user inside of a channel.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ChannelUserStatus {
    /// User has special status.
    Normal,
    /// User has voice status.
    Voice,
    /// User has operator status.
    Operator,
    /// User has owner status.
    Owner,
}

/// Represents a user inside of a channel.
#[derive(Debug)]
pub struct ChannelUser {
    /// Nickname of the user.
    pub nickname: String,
    /// Status of the user inside the channel.
    pub status: ChannelUserStatus,
}

impl ChannelUser {

    fn from_raw(raw: &str) -> ChannelUser {
        let status = match raw.chars().next() {
            Some('&') => ChannelUserStatus::Owner,
            Some('@') => ChannelUserStatus::Operator,
            Some('+') => ChannelUserStatus::Voice,
            _ => ChannelUserStatus::Normal,
        };
        ChannelUser {
            nickname: (if status == ChannelUserStatus::Normal { raw } else { &raw[1..] }).into(),
            status: status,
        }
    }
}

/// Represents a channel.
#[derive(Debug)]
pub struct Channel {
    users: Vec<ChannelUser>,
    /// Name of the channel.
    pub name: String,
    /// Topic of the channel.
    pub topic: Option<String>,
}

impl Channel {

    /// Get a user by nickname from this channel.
    pub fn get_user(&self, nickname: &str) -> Option<&ChannelUser> {
        match self.users.iter().position(|u| u.nickname == nickname) {
            Some(idx) => Some(&self.users[idx]),
            None => None,
        }
    }

    /// Get a mutable reference to a user by nickname.
    fn get_user_mut(&mut self, nickname: &str) -> Option<&mut ChannelUser> {
        match self.users.iter_mut().position(|u| u.nickname == nickname) {
            Some(idx) => Some(&mut self.users[idx]),
            None => None,
        }
    }

    /// Get an iterator that iterates over the channel's users.
    pub fn users(&self) -> Iter<ChannelUser> {
        self.users.iter()
    }

}
/// Status of the connection.
#[derive(Debug)]
pub enum ConnectionStatus {
    /// Connection was closed.
    Closed(&'static str),
    /// Connection is alive.
    Connected,
    /// Connection was dropped.
    Disconnected,
    /// Attempting to reconnect.
    Reconnecting,
}

/// Errors that can occur.
#[derive(Debug)]
pub enum Error {
    /// Connection is already closed.
    AlreadyClosed,
    /// Connection is already disconnected.
    AlreadyDisconnected,
    /// Connection was manually closed.
    Closed,
    /// Connection was dropped.
    ///
    /// A reconnection might be in process.
    Disconnected,
    /// I/O error.
    IoError(io::Error),
    /// The message contains a line break.
    Multiline,
}

impl From<loirc::Error> for Error {
    fn from(err: loirc::Error) -> Error {
        match err {
            loirc::Error::AlreadyClosed => Error::AlreadyClosed,
            loirc::Error::AlreadyDisconnected => Error::AlreadyDisconnected,
            loirc::Error::Closed => Error::Closed,
            loirc::Error::Disconnected => Error::Disconnected,
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::IoError(err)
    }
}

/// Represents the state of this connection.
pub struct Irc {
    writer: Writer,
    channels: HashMap<String, Channel>,
    /// Status of the connection.
    pub status: ConnectionStatus,
}

impl Irc {

    fn new(writer: Writer) -> Irc {
        Irc {
            writer: writer,
            status: ConnectionStatus::Connected,
            channels: HashMap::new(),
        }
    }

    /// Get a channel by name.
    pub fn get_channel_by_name(&self, name: &str) -> Option<&Channel> {
        self.get_channel_by_id(&name.to_lowercase())
    }

    /// Get a reference to a channel by id.
    fn get_channel_by_id(&self, id: &str) -> Option<&Channel> {
        self.channels.get(id)
    }

    // Ensure a channel if it does not exist.
    fn ensure_channel_exists(&mut self, name: &str, id: &str) {
        if !self.channels.contains_key(id) {
            self.channels.insert(id.into(), Channel {
                name: name.into(),
                users: Vec::new(),
                topic: None,
            });
        }
    }

    fn channel_set_topic(&mut self, channel_id: &str, topic: &str) {
        let channel = some_or_return!(self.channels.get_mut(channel_id));
        channel.topic = if topic.len() == 0 {
            None
        } else {
            Some(topic.into())
        };
    }

{'fraction_non_alphanumeric': 0.1355002110595188, 'fraction_numerical': 0.00042211903756859433, 'mean_word_length': 2.20493743659114, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 65, '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': '2517697', 'n_tokens_mistral': 2837, 'n_tokens_neox': 2770, 'n_words': 794}