gdritter repos httputils / master src / matching.rs
master

Tree @master (Download .tar.gz)

matching.rs @masterraw · history · blame

/// Find out whether the `spec_str` matches the `string_str`.
/// The former can contain the wildcard character `*`.
///
/// # Examples
///
/// ```
/// assert!(do_match("foo", "foo"));
/// assert!(do_match("*o",  "foo"));
/// assert!(do_match("f*o", "foo"));
/// assert!(do_match("f*",  "foo"));
/// ```
pub fn do_match(spec_str: &str, string_str: &str) -> bool {
    let spec = spec_str.as_bytes();
    let string = string_str.as_bytes();
    let mut stack = vec![(0, 0)];
    while let Some((i, j)) = stack.pop() {
        if i >= spec.len() && j >= spec.len() {
            return true;
        } else if i >= spec.len() || j >= string_str.len() {
            continue;
        } else if spec[i] == 0x2a {
            stack.push((i,   j+1));
            stack.push((i+1, j+1));
        } else if spec[i] == string[j] {
            stack.push((i+1, j+1));
        }
    }
    false
}

#[test]
fn test_match() {
    assert!(do_match("foo",  "foo"));
    assert!(do_match("*oo",  "foo"));
    assert!(do_match("f*o",  "foo"));
    assert!(do_match("fo*",  "foo"));
    assert!(do_match("f*",   "foo"));
    assert!(do_match("*o",   "foo"));
    assert!(do_match("*",    "foo"));
    assert!(!do_match("foo", "bar"));
    assert!(!do_match("f*",  "bar"));
}