sedregex 0.2.5

Sed-like regex library
Documentation
use crate::{command::Command, regex_flags::RegexFlags, splitting_iter::SlashSplitIter, ErrorKind};
use std::borrow::Cow;

/// A structure holding all the data to execute a regular expression substitution.
#[derive(Debug, PartialEq)]
pub struct ReplaceData<'a> {
    /// Search pattern.
    pub pattern: Cow<'a, str>,
    /// Replace data.
    pub with: Cow<'a, str>,
    /// Regex flags.
    pub flags: RegexFlags,
}

impl<'a> ReplaceData<'a> {
    /// Splits the given string into a `ReplaceData` object.
    pub fn new(data: &'a str) -> Result<Self, ErrorKind> {
        let mut it = SlashSplitIter::from(data);
        let _command: Command = match it.next() {
            Some(cmd) => cmd.parse()?,
            None => return Err(ErrorKind::NotEnoughSegments),
        };
        let pattern = it.next().ok_or(ErrorKind::NotEnoughSegments)?;
        let with = it.next().ok_or(ErrorKind::NotEnoughSegments)?;
        let flags = match it.next() {
            Some(s) => s.parse()?,
            None => RegexFlags::default(),
        };
        Ok(ReplaceData {
            pattern,
            with,
            flags,
        })
    }
}

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

    #[test]
    fn global_insensitive() {
        let data = r"s/ahahaha/l世界l\/wut/gi";
        assert_eq!(
            Ok(ReplaceData {
                pattern: "ahahaha".into(),
                with: "l世界l/wut".into(),
                flags: vec!(RegexFlag::Global, RegexFlag::CaseInsensitive).into(),
            }),
            ReplaceData::new(data),
        );
    }

    #[test]
    fn corner() {
        let cmd = r"s/lol/wut\//gi";
        assert_eq!(
            Ok(ReplaceData {
                pattern: "lol".into(),
                with: r"wut/".into(),
                flags: vec!(RegexFlag::CaseInsensitive, RegexFlag::Global).into()
            }),
            ReplaceData::new(cmd)
        );
    }

    #[test]
    fn no_flags() {
        let data = r"s/aha\/haha/lolwut/";
        assert_eq!(
            Ok(ReplaceData {
                pattern: "aha/haha".into(),
                with: "lolwut".into(),
                flags: vec!().into(),
            }),
            ReplaceData::new(data),
        );
    }

    #[test]
    fn no_flags2() {
        let data = r"s/aha\/haha/lolwut";
        assert_eq!(
            Ok(ReplaceData {
                pattern: "aha/haha".into(),
                with: "lolwut".into(),
                flags: vec!().into(),
            }),
            ReplaceData::new(data),
        );
    }

    #[test]
    fn empty_with() {
        let data = r"s/aha\/haha/";
        assert_eq!(Err(ErrorKind::NotEnoughSegments), ReplaceData::new(data),);
    }

    #[test]
    fn unknown_command() {
        let data = "wtf/what/with/";
        assert_eq!(
            Err(ErrorKind::UnknownCommand("wtf".into())),
            ReplaceData::new(data),
        );
    }

    #[test]
    fn unknown_flag() {
        let data = "s/what/with/u";
        assert_eq!(Err(ErrorKind::UnknownFlag('u')), ReplaceData::new(data),);
    }
}