ircv3_parse 4.0.0

Zero-copy parser for IRCv3 messages
Documentation
use std::fmt;

use proptest::{
    prelude::{prop, Just, Strategy},
    prop_compose, prop_oneof,
};

#[derive(Debug, Clone, PartialEq)]
pub enum ParamsType {
    MiddlesOnly(Vec<String>),
    TrailingOnly(String),
    MiddlesTrailing(Vec<String>, String),
    None,
}

impl ParamsType {
    pub fn raw(&self) -> String {
        match self {
            Self::MiddlesOnly(middles) => {
                if middles.is_empty() {
                    String::new()
                } else {
                    middles.join(" ")
                }
            }
            Self::TrailingOnly(trailing) => trailing.to_string(),
            Self::MiddlesTrailing(middles, trailing) => {
                if middles.is_empty() {
                    trailing.to_string()
                } else {
                    format!("{} :{}", middles.join(" "), trailing)
                }
            }
            Self::None => String::new(),
        }
    }
}

impl fmt::Display for ParamsType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::MiddlesOnly(middles) => {
                if middles.is_empty() {
                    write!(f, "{}", String::new())
                } else {
                    write!(f, " {}", middles.join(" "))
                }
            }
            Self::TrailingOnly(trailing) => write!(f, " :{}", trailing),
            Self::MiddlesTrailing(middles, trailing) => {
                if middles.is_empty() {
                    write!(f, " :{}", trailing)
                } else {
                    write!(f, " {} :{}", middles.join(" "), trailing)
                }
            }
            Self::None => write!(f, "{}", String::new()),
        }
    }
}

prop_compose! {
    pub fn params_strategy()(
        params in prop_oneof![
            middles().prop_map(ParamsType::MiddlesOnly),
            (middles(), trailing()).prop_map(|(m, t)| ParamsType::MiddlesTrailing(m, t)),
            trailing().prop_map(ParamsType::TrailingOnly),
            Just(ParamsType::None),

        ]
    ) -> ParamsType { params }
}

prop_compose! {
    pub fn middles()(
        middles in prop::collection::vec("[a-zA-Z0-9#&+!.-]+", 0..=14)
    )-> Vec<String> { middles }
}

prop_compose! {
    pub fn trailing()(
        trailing in "[^\r\n\0]{0,500}"
    ) -> String { trailing }
}