dbus-message-parser 4.3.1

Libary to encode and decode DBus message
Documentation
use super::MatchRuleError;

enum State {
    OutsideSingleQuotes,
    OutsideSingleQuotesBackslash,
    InsideSingleQuotes,
}

pub(super) fn unescape(string: &str) -> Result<String, MatchRuleError> {
    let mut result = String::new();
    let mut state = State::OutsideSingleQuotes;
    for c in string.chars() {
        match state {
            State::OutsideSingleQuotes => match c {
                '\\' => state = State::OutsideSingleQuotesBackslash,
                '\'' => state = State::InsideSingleQuotes,
                c => result.push(c),
            },
            State::OutsideSingleQuotesBackslash => match c {
                '\\' => result.push('\\'),
                '\'' => {
                    result.push('\'');
                    state = State::OutsideSingleQuotes
                }
                c => {
                    result.push('\\');
                    result.push(c);
                    state = State::OutsideSingleQuotes
                }
            },
            State::InsideSingleQuotes => match c {
                '\'' => state = State::OutsideSingleQuotes,
                c => result.push(c),
            },
        }
    }

    match state {
        State::OutsideSingleQuotes => Ok(result),
        State::OutsideSingleQuotesBackslash => {
            result.push('\\');
            Ok(result)
        }
        State::InsideSingleQuotes => Err(MatchRuleError::ValueClosingQuote),
    }
}

#[cfg(test)]
mod tests {
    use crate::match_rule::MatchRuleError;

    use super::unescape;

    #[test]
    fn unescape_1() {
        assert_eq!(unescape("\\").unwrap(), "\\")
    }

    #[test]
    fn unescape_2() {
        assert_eq!(unescape("\\'").unwrap(), "'")
    }

    #[test]
    fn unescape_3() {
        assert_eq!(unescape("\\\\").unwrap(), "\\\\")
    }

    #[test]
    fn unescape_4() {
        assert_eq!(unescape("\\a").unwrap(), "\\a")
    }

    #[test]
    fn unescape_5() {
        assert_eq!(unescape("'a'").unwrap(), "a")
    }

    #[test]
    fn unescape_error() {
        assert_eq!(unescape("'"), Err(MatchRuleError::ValueClosingQuote))
    }
}