<commit_before>extern crate time;

use std::ascii::AsciiExt;

use time::get_time;

/// Are two chars the same? Optionally ignoring the case.
///
/// # Examples
///
/// ```
/// use util::match_char;
/// assert!( match_char(&('a' as u8), &('a' as u8), false));
/// assert!( match_char(&('a' as u8), &('a' as u8), true));
/// assert!(!match_char(&('a' as u8), &('A' as u8), false));
/// assert!( match_char(&('a' as u8), &('A' as u8), true));
/// ```
#[must_use]
pub fn match_char(e1: &u8, e2: &u8, ignore_case: bool) -> bool {
    if ignore_case {
        // FIXME: redis uses tolower() which is locale aware
        return e1.to_ascii_lowercase() == e2.to_ascii_lowercase();
    } else {
        return e1 == e2;
    }
}

/// Whether an element matches a glob-like pattern. Optionally ignores case.
///
/// # Examples
///
/// ```
/// use util::glob_match;
/// assert!(glob_match(&b"".to_vec(), &b"".to_vec(), false));
/// assert!(glob_match(&b"foo*baz".to_vec(), &b"foobarbaz".to_vec(), false));
/// assert!(!glob_match(&b"foo*baz".to_vec(), &b"foobazbar".to_vec(), false));
/// assert!(glob_match(&b"fooba?".to_vec(), &b"foobar".to_vec(), false));
/// assert!(glob_match(&b"fooba?".to_vec(), &b"foobaz".to_vec(), false));
/// assert!(!glob_match(&b"fooba?".to_vec(), &b"foofoo".to_vec(), false));
/// ```
#[must_use]
pub fn glob_match(pattern: &Vec<u8>, element: &Vec<u8>, ignore_case: bool) -> bool {
    let mut patternpos = 0;
    let mut elementpos = 0;
    let star = 42u8; /* '*' */
    let question_mark = 63u8; /* '?' */
    let backslash = 92u8; /* '\\' */
    let open_bracket = 91u8; /* '[' */
    let close_bracket = 93u8; /* '[' */
    while patternpos < pattern.len() {
        match pattern[patternpos] {
            x if x == star => {
                while patternpos + 1 < pattern.len() && pattern[patternpos + 1] == star {
                    patternpos += 1;
                }
                if patternpos == pattern.len() {
                    return true;
                }
                for i in elementpos..(element.len() + 1) {
                    if glob_match(&pattern[patternpos + 1..].to_vec(), &element[i..].to_vec(), ignore_case) {
                        return true;
                    }
                }
                return false;
            },
            x if x == question_mark => {
                if elementpos >= element.len() {
                    return false;
                }
                elementpos += 1;
            },
            x if x == backslash => {
                patternpos += 1;
                if elementpos >= element.len(){
                    return false;
                }
                if !match_char(&pattern[patternpos], &element[elementpos], ignore_case) {
                    return false;
                }
                elementpos += 1;
            },
            x if x == open_bracket => {
                patternpos += 1;
                let not = pattern[patternpos] == ('^' as u8);
                if not {
                    patternpos += 1;
                }
                let mut matched = false;
                loop {
                    if pattern[patternpos] == backslash {
                        patternpos += 1;
                        if pattern[patternpos] == element[elementpos] {
                            matched = true;
                        }
                    } else if pattern[patternpos] == close_bracket {
                        break;
                    } else if patternpos >= pattern.len() {
                        patternpos += 1;
                        break;
                    } else if pattern.len() >= patternpos + 3 && pattern[patternpos + 1] == ('-' as u8) {
                        let mut start = pattern[patternpos];
                        let mut end = pattern[patternpos + 2];
                        let mut c = element[elementpos];
                        if start > end {
                            let t = start;
                            start = end;
                            end = t;
                        }
                        if ignore_case {
                            start = start.to_ascii_lowercase();
                            end = end.to_ascii_lowercase();
                            c = c.to_ascii_lowercase();
                        }
                        patternpos += 2;
                        if c >= start && c <= end {
                            matched = true;
                        }
                    } else {
                        if match_char(&pattern[patternpos], &element[elementpos], ignore_case) {
                            matched = true;
                        }
                    }
                    patternpos += 1;
                }
                if not {
                    matched = !matched;
                }
                if !matched {
                    return false;
                }
                elementpos += 1;
            },
            _ => {
                if elementpos >= element.len(){
                    return false;
                }
                if !match_char(&pattern[patternpos], &element[elementpos], ignore_case) {
                    return false;
                }
                elementpos += 1;
            },
        }
        patternpos += 1;
        if elementpos == element.len() {
            for p in patternpos..pattern.len() {
                if pattern[p] != star {
                    break;
                }
            }
            break;
        }
    }

    if patternpos == pattern.len() && elementpos == element.len() {
        return true;
    }
    return false;
}

/// Current timestamp in microseconds
pub fn ustime() -> i64 {
    let tv = get_time();
    tv.sec * 1000000 + (tv.nsec / 1000) as i64
}

/// Current timestamp in milliseconds
pub fn mstime() -> i64 {
    ustime() / 1000
}

/// Parses a config line string.
///
/// # Examples
/// ```
/// # use util::splitargs;
/// #
/// let res = splitargs(b"hello world").unwrap();
/// assert_eq!(res, vec![b"hello".to_vec(), b"world".to_vec()]);
/// ```
///
/// ```
/// # use util::splitargs;
/// #
/// let res = splitargs(b"foo \"bar baz\"").unwrap();
/// assert_eq!(res, vec![b"foo".to_vec(), b"bar baz".to_vec()]);
/// ```
pub fn splitargs(args: &[u8]) -> Result<Vec<Vec<u8>>, ()> {
    let mut i = 0;
    let mut result = Vec::new();
    for _ in args {
        while i < args.len() && (args[i] == 0 || (args[i] as char).is_whitespace()) { i += 1; }
        if i >=  args.len() { break; }
        let mut inq = false;
        let mut insq = false;
        let mut done = false;
        let mut current = Vec::new();
        while !done && i < args.len() {
            let p = args[i] as char;
            if inq {
                if p == '\\' && (args[i + 1] as char) == 'x' {
                    if let Some(c1) = (args[i + 2] as char).to_digit(16) {
                        if let Some(c2) = (args[i + 3] as char).to_digit(16) {
                            current.push((c1 * 16 + c2) as u8);
                            i += 3;
                        }
                    }
                } else if p == '"'{
                    // closing quote must be followed by a space or nothing at all
                    i += 1;
                    if i != args.len() && !(args[i] as char).is_whitespace() { return Err(()); }
                    inq = false;
                    done = true;
                } else if p == '\\' && i + 1 < args.len() {
                    i += 1;
                    let c = match args[i] as char {
                        'n' => '\n',
                        'r' => '\r',
                        't' => '\t',
                        // FIXME: Rust does not recognize '\a' and '\b'?
                        'b' => 'b',
                        'a' => 'a',
                        c => c as char,
                    } as u8;
                    current.push(c);
                } else {
                    current.push(args[i]);
                }
            } else if insq {
                if p == '\'' {
                    // closing quote must be followed by a space or nothing at all
                    i += 1;
                    if i != args.len() && !(args[i] as char).is_whitespace() { return Err(()); }
                    insq = false;
                    done = true;
                } else if p == '\\' && i + 1 < args.len() && (args[i + 1] as char == '\'') {
                    current.push(args[i + 1]);
                    i += 1;
                } else {
                    current.push(args[i]);
                }
            } else {
                match p as char {
                    ' ' => done = true,
                    '\t' => done = true,
                    '\n' => done = true,
                    '\r' => done = true,
                    '\0' => done = true,
                    '"' => inq = true,
                    '\'' => insq = true,
                    _ => current.push(args[i]),
                }
            }
            i += 1;
        }
        result.push(current);
        if i >=  args.len() {
            if inq || insq {
                return Err(());
            }
            break;
        }
    }
    Ok(result)
}

/// Creates an array of four `u8` from a `u32`.
pub fn htonl(v: u32) -> [u8; 4] {
    // maybe it should use C api instead?
    [
        ((v >> 24) & 0xFF) as u8,
        ((v >> 16) & 0xFF) as u8,
        ((v >> 8) & 0xFF) as u8,
        ((v >> 0) & 0xFF) as u8,
    ]
}

#[cfg(test)]
mod test_util {
    use std::{u8, u32};
    use std::thread::sleep_ms;

    use super::{mstime, splitargs, glob_match, htonl};

    #[test]
    fn mstime_sleep() {
        let start = mstime();
        sleep_ms(100);
        let end = mstime();
        assert!(start < end && start + 100 <= end && start + 500 > end);
    }

    #[test]
    fn glob_match_empty() {
        assert!(glob_match(&b"".to_vec(), &b"".to_vec(), true));
    }

    #[test]
    fn glob_match_star() {
        assert!(glob_match(&b"*".to_vec(), &b"".to_vec(), true));
        assert!(glob_match(&b"*".to_vec(), &b"hello world".to_vec(), true));
        assert!(glob_match(&b"**".to_vec(), &b"hello world".to_vec(), true));
        assert!(glob_match(&b"hello*".to_vec(), &b"hello world".to_vec(), true));
        assert!(glob_match(&b"*world".to_vec(), &b"hello world".to_vec(), true));
        assert!(!glob_match(&b"foo*".to_vec(), &b"hello world".to_vec(), true));
        assert!(!glob_match(&b"*bar".to_vec(), &b"hello world".to_vec(), true));
        assert!(!glob_match(&b"*bar".to_vec(), &b"".to_vec(), true));
    }

    #[test]
    fn glob_match_question_mark() {
        assert!(!glob_match(&b"?".to_vec(), &b"".to_vec(), true));
        assert!(glob_match(&b"?".to_vec(), &b"a".to_vec(), true));
        assert!(!glob_match(&b"?".to_vec(), &b"aa".to_vec(), true));
        assert!(glob_match(&b"a?".to_vec(), &b"aa".to_vec(), true));
    }

    #[test]
    fn glob_match_backslash() {
        assert!(glob_match(&b"\\*asd".to_vec(), &b"*asd".to_vec(), true));
        assert!(!glob_match(&b"\\*d".to_vec(), &b"*asd".to_vec(), true));
        assert!(glob_match(&b"\\?a".to_vec(), &b"?a".to_vec(), true));
        assert!(!glob_match(&b"\\?a".to_vec(), &b"ba".to_vec(), true));
    }

    #[test]
    fn glob_match_brackets() {
        assert!(glob_match(&b"[abc]".to_vec(), &b"a".to_vec(), true));
        assert!(!glob_match(&b"[^abc]".to_vec(), &b"a".to_vec(), true));
        assert!(glob_match(&b"[abc]b".to_vec(), &b"ab".to_vec(), true));
        assert!(!glob_match(&b"[abc]".to_vec(), &b"ab".to_vec(), true));
        assert!(glob_match(&b"[\\]*]".to_vec(), &b"]".to_vec(), true));
        assert!(!glob_match(&b"[\\]*]".to_vec(), &b"a".to_vec(), true));
    }

    #[test]
    fn splitargs_quotes() {
        assert_eq!(splitargs(&b"\"\\x9f\"".to_vec()).unwrap(), vec![vec![159u8]]);
        assert_eq!(splitargs(&b"\"\"".to_vec()).unwrap(), vec![vec![]]);
        assert_eq!(splitargs(&b"\"\\thello\\n\"".to_vec()).unwrap(), vec![b"\thello\n".to_vec()]);
        assert!(splitargs(&b"\"a".to_vec()).is_err());
    }

    #[test]
    fn splitargs_singlequotes() {
        assert_eq!(splitargs(&b"\'\\x9f\'".to_vec()).unwrap(), vec![b"\\x9f".to_vec()]);
        assert_eq!(splitargs(&b"\'\'".to_vec()).unwrap(), vec![vec![]]);
        assert_eq!(splitargs(&b"\'\\\'\'".to_vec()).unwrap(), vec![b"'".to_vec()]);
        assert_eq!(splitargs(&b"\'\\thello\\n\'".to_vec()).unwrap(), vec![b"\\thello\\n".to_vec()]);
        assert!(splitargs(&b"\'a".to_vec()).is_err());
    }

    #[test]
    fn splitargs_misc() {
        assert_eq!(splitargs(&b"hello world".to_vec()).unwrap(), vec![b"hello".to_vec(), b"world".to_vec()]);
        assert_eq!(splitargs(&b"\'hello\' world".to_vec()).unwrap(), vec![b"hello".to_vec(), b"world".to_vec()]);
        assert_eq!(splitargs(&b"\"hello\" world".to_vec()).unwrap(), vec![b"hello".to_vec(), b"world".to_vec()]);
        assert!(splitargs(&b"\"hello\"world".to_vec()).is_err());
        assert!(splitargs(&b"\'hello\'world".to_vec()).is_err());
    }

    #[test]
    fn htonl_basic() {
        assert_eq!(htonl(1), [0, 0, 0, 1]);
        assert_eq!(htonl(256), [0, 0, 1, 0]);
        assert_eq!(htonl(u32::MAX), [u8::MAX, u8::MAX, u8::MAX, u8::MAX]);
    }
}
<commit_msg>Use characters for easier understanding<commit_after>extern crate time;

use std::ascii::AsciiExt;

use time::get_time;

/// Are two chars the same? Optionally ignoring the case.
///
/// # Examples
///
/// ```
/// use util::match_char;
/// assert!( match_char(&('a' as u8), &('a' as u8), false));
/// assert!( match_char(&('a' as u8), &('a' as u8), true));
/// assert!(!match_char(&('a' as u8), &('A' as u8), false));
/// assert!( match_char(&('a' as u8), &('A' as u8), true));
/// ```
#[must_use]
pub fn match_char(e1: &u8, e2: &u8, ignore_case: bool) -> bool {
    if ignore_case {
        // FIXME: redis uses tolower() which is locale aware
        return e1.to_ascii_lowercase() == e2.to_ascii_lowercase();
    } else {
        return e1 == e2;
    }
}

/// Whether an element matches a glob-like pattern. Optionally ignores case.
///
/// # Examples
///
/// ```
/// use util::glob_match;
/// assert!(glob_match(&b"".to_vec(), &b"".to_vec(), false));
/// assert!(glob_match(&b"foo*baz".to_vec(), &b"foobarbaz".to_vec(), false));
/// assert!(!glob_match(&b"foo*baz".to_vec(), &b"foobazbar".to_vec(), false));
/// assert!(glob_match(&b"fooba?".to_vec(), &b"foobar".to_vec(), false));
/// assert!(glob_match(&b"fooba?".to_vec(), &b"foobaz".to_vec(), false));
/// assert!(!glob_match(&b"fooba?".to_vec(), &b"foofoo".to_vec(), false));
/// ```
#[must_use]
pub fn glob_match(pattern: &Vec<u8>, element: &Vec<u8>, ignore_case: bool) -> bool {
    let mut patternpos = 0;
    let mut elementpos = 0;

    let star          = '*' as u8;
    let question_mark = '?' as u8;
    let backslash     = '\\' as u8;
    let open_bracket  = '[' as u8;
    let close_bracket = ']' as u8;

    while patternpos < pattern.len() {
        match pattern[patternpos] {
            x if x == star => {
                while patternpos + 1 < pattern.len() && pattern[patternpos + 1] == star {
                    patternpos += 1;
                }
                if patternpos == pattern.len() {
                    return true;
                }
                for i in elementpos..(element.len() + 1) {
                    if glob_match(&pattern[patternpos + 1..].to_vec(), &element[i..].to_vec(), ignore_case) {
                        return true;
                    }
                }
                return false;
            },
            x if x == question_mark => {
                if elementpos >= element.len() {
                    return false;
                }
                elementpos += 1;
            },
            x if x == backslash => {
                patternpos += 1;
                if elementpos >= element.len(){
                    return false;
                }
                if !match_char(&pattern[patternpos], &element[elementpos], ignore_case) {
                    return false;
                }
                elementpos += 1;
            },
            x if x == open_bracket => {
                patternpos += 1;
                let not = pattern[patternpos] == ('^' as u8);
                if not {
                    patternpos += 1;
                }
                let mut matched = false;
                loop {
                    if pattern[patternpos] == backslash {
                        patternpos += 1;
                        if pattern[patternpos] == element[elementpos] {
                            matched = true;
                        }
                    } else if pattern[patternpos] == close_bracket {
                        break;
                    } else if patternpos >= pattern.len() {
                        patternpos += 1;
                        break;
                    } else if pattern.len() >= patternpos + 3 && pattern[patternpos + 1] == ('-' as u8) {
                        let mut start = pattern[patternpos];
                        let mut end = pattern[patternpos + 2];
                        let mut c = element[elementpos];
                        if start > end {
                            let t = start;
                            start = end;
                            end = t;
                        }
                        if ignore_case {
                            start = start.to_ascii_lowercase();
                            end = end.to_ascii_lowercase();
                            c = c.to_ascii_lowercase();
                        }
                        patternpos += 2;
                        if c >= start && c <= end {
                            matched = true;
                        }
                    } else {
                        if match_char(&pattern[patternpos], &element[elementpos], ignore_case) {
                            matched = true;
                        }
                    }
                    patternpos += 1;
                }
                if not {
                    matched = !matched;
                }
                if !matched {
                    return false;
                }
                elementpos += 1;
            },
            _ => {
                if elementpos >= element.len(){
                    return false;
                }
                if !match_char(&pattern[patternpos], &element[elementpos], ignore_case) {
                    return false;
                }
                elementpos += 1;
            },
        }
        patternpos += 1;
        if elementpos == element.len() {
            for p in patternpos..pattern.len() {
                if pattern[p] != star {
                    break;
                }
            }
            break;
        }
    }

    if patternpos == pattern.len() && elementpos == element.len() {
        return true;
    }
    return false;
}

/// Current timestamp in microseconds
pub fn ustime() -> i64 {
    let tv = get_time();
    tv.sec * 1000000 + (tv.nsec / 1000) as i64
}

/// Current timestamp in milliseconds
pub fn mstime() -> i64 {
    ustime() / 1000
}

/// Parses a config line string.
///
/// # Examples
/// ```
/// # use util::splitargs;
/// #
/// let res = splitargs(b"hello world").unwrap();
/// assert_eq!(res, vec![b"hello".to_vec(), b"world".to_vec()]);
/// ```
///
/// ```
/// # use util::splitargs;
/// #
/// let res = splitargs(b"foo \"bar baz\"").unwrap();
/// assert_eq!(res, vec![b"foo".to_vec(), b"bar baz".to_vec()]);
/// ```
pub fn splitargs(args: &[u8]) -> Result<Vec<Vec<u8>>, ()> {
    let mut i = 0;
    let mut result = Vec::new();
    for _ in args {
        while i < args.len() && (args[i] == 0 || (args[i] as char).is_whitespace()) { i += 1; }
        if i >=  args.len() { break; }
        let mut inq = false;
        let mut insq = false;
        let mut done = false;
        let mut current = Vec::new();
        while !done && i < args.len() {
            let p = args[i] as char;
            if inq {
                if p == '\\' && (args[i + 1] as char) == 'x' {
                    if let Some(c1) = (args[i + 2] as char).to_digit(16) {
                        if let Some(c2) = (args[i + 3] as char).to_digit(16) {
                            current.push((c1 * 16 + c2) as u8);
                            i += 3;
                        }
                    }
                } else if p == '"'{
                    // closing quote must be followed by a space or nothing at all
                    i += 1;
                    if i != args.len() && !(args[i] as char).is_whitespace() { return Err(()); }
                    inq = false;
                    done = true;
                } else if p == '\\' && i + 1 < args.len() {
                    i += 1;
                    let c = match args[i] as char {
                        'n' => '\n',
                        'r' => '\r',
                        't' => '\t',
                        // FIXME: Rust does not recognize '\a' and '\b'?
                        'b' => 'b',
                        'a' => 'a',
                        c => c as char,
                    } as u8;
                    current.push(c);
                } else {
                    current.push(args[i]);
                }
            } else if insq {
                if p == '\'' {
                    // closing quote must be followed by a space or nothing at all
                    i += 1;
                    if i != args.len() && !(args[i] as char).is_whitespace() { return Err(()); }
                    insq = false;
                    done = true;
                } else if p == '\\' && i + 1 < args.len() && (args[i + 1] as char == '\'') {
                    current.push(args[i + 1]);
                    i += 1;
                } else {
                    current.push(args[i]);
                }
            } else {
                match p as char {
                    ' ' => done = true,
                    '\t' => done = true,
                    '\n' => done = true,
                    '\r' => done = true,
                    '\0' => done = true,
                    '"' => inq = true,
                    '\'' => insq = true,
                    _ => current.push(args[i]),
                }
            }
            i += 1;
        }
        result.push(current);
        if i >=  args.len() {
            if inq || insq {
                return Err(());
            }
            break;
        }
    }
    Ok(result)
}

/// Creates an array of four `u8` from a `u32`.
pub fn htonl(v: u32) -> [u8; 4] {
    // maybe it should use C api instead?
    [
        ((v >> 24) & 0xFF) as u8,
        ((v >> 16) & 0xFF) as u8,
        ((v >> 8) & 0xFF) as u8,
        ((v >> 0) & 0xFF) as u8,
    ]
}

#[cfg(test)]
mod test_util {
    use std::{u8, u32};
    use std::thread::sleep_ms;

    use super::{mstime, splitargs, glob_match, htonl};

    #[test]
    fn mstime_sleep() {
        let start = mstime();
        sleep_ms(100);
        let end = mstime();
        assert!(start < end && start + 100 <= end && start + 500 > end);
    }

    #[test]
    fn glob_match_empty() {
        assert!(glob_match(&b"".to_vec(), &b"".to_vec(), true));
    }

    #[test]
    fn glob_match_star() {
        assert!(glob_match(&b"*".to_vec(), &b"".to_vec(), true));
        assert!(glob_match(&b"*".to_vec(), &b"hello world".to_vec(), true));
        assert!(glob_match(&b"**".to_vec(), &b"hello world".to_vec(), true));
        assert!(glob_match(&b"hello*".to_vec(), &b"hello world".to_vec(), true));
        assert!(glob_match(&b"*world".to_vec(), &b"hello world".to_vec(), true));
        assert!(!glob_match(&b"foo*".to_vec(), &b"hello world".to_vec(), true));
        assert!(!glob_match(&b"*bar".to_vec(), &b"hello world".to_vec(), true));
        assert!(!glob_match(&b"*bar".to_vec(), &b"".to_vec(), true));
    }

    #[test]
    fn glob_match_question_mark() {
        assert!(!glob_match(&b"?".to_vec(), &b"".to_vec(), true));
        assert!(glob_match(&b"?".to_vec(), &b"a".to_vec(), true));
        assert!(!glob_match(&b"?".to_vec(), &b"aa".to_vec(), true));
        assert!(glob_match(&b"a?".to_vec(), &b"aa".to_vec(), true));
    }

    #[test]
    fn glob_match_backslash() {
        assert!(glob_match(&b"\\*asd".to_vec(), &b"*asd".to_vec(), true));
        assert!(!glob_match(&b"\\*d".to_vec(), &b"*asd".to_vec(), true));
        assert!(glob_match(&b"\\?a".to_vec(), &b"?a".to_vec(), true));
        assert!(!glob_match(&b"\\?a".to_vec(), &b"ba".to_vec(), true));
    }

    #[test]
    fn glob_match_brackets() {
        assert!(glob_match(&b"[abc]".to_vec(), &b"a".to_vec(), true));
        assert!(!glob_match(&b"[^abc]".to_vec(), &b"a".to_vec(), true));
        assert!(glob_match(&b"[abc]b".to_vec(), &b"ab".to_vec(), true));
        assert!(!glob_match(&b"[abc]".to_vec(), &b"ab".to_vec(), true));
        assert!(glob_match(&b"[\\]*]".to_vec(), &b"]".to_vec(), true));
        assert!(!glob_match(&b"[\\]*]".to_vec(), &b"a".to_vec(), true));
    }

    #[test]
    fn splitargs_quotes() {
        assert_eq!(splitargs(&b"\"\\x9f\"".to_vec()).unwrap(), vec![vec![159u8]]);
        assert_eq!(splitargs(&b"\"\"".to_vec()).unwrap(), vec![vec![]]);
        assert_eq!(splitargs(&b"\"\\thello\\n\"".to_vec()).unwrap(), vec![b"\thello\n".to_vec()]);
        assert!(splitargs(&b"\"a".to_vec()).is_err());
    }

    #[test]
    fn splitargs_singlequotes() {
        assert_eq!(splitargs(&b"\'\\x9f\'".to_vec()).unwrap(), vec![b"\\x9f".to_vec()]);
        assert_eq!(splitargs(&b"\'\'".to_vec()).unwrap(), vec![vec![]]);
        assert_eq!(splitargs(&b"\'\\\'\'".to_vec()).unwrap(), vec![b"'".to_vec()]);
        assert_eq!(splitargs(&b"\'\\thello\\n\'".to_vec()).unwrap(), vec![b"\\thello\\n".to_vec()]);
        assert!(splitargs(&b"\'a".to_vec()).is_err());
    }

    #[test]
    fn splitargs_misc() {
        assert_eq!(splitargs(&b"hello world".to_vec()).unwrap(), vec![b"hello".to_vec(), b"world".to_vec()]);
        assert_eq!(splitargs(&b"\'hello\' world".to_vec()).unwrap(), vec![b"hello".to_vec(), b"world".to_vec()]);
        assert_eq!(splitargs(&b"\"hello\" world".to_vec()).unwrap(), vec![b"hello".to_vec(), b"world".to_vec()]);
        assert!(splitargs(&b"\"hello\"world".to_vec()).is_err());
        assert!(splitargs(&b"\'hello\'world".to_vec()).is_err());
    }

    #[test]
    fn htonl_basic() {
        assert_eq!(htonl(1), [0, 0, 0, 1]);
        assert_eq!(htonl(256), [0, 0, 1, 0]);
        assert_eq!(htonl(u32::MAX), [u8::MAX, u8::MAX, u8::MAX, u8::MAX]);
    }
}
<|endoftext|>


<commit_before><commit_msg>Update pattern.rs<commit_after><|endoftext|>


<commit_before>//! Endpoints for getting and synchronizing events.

/// [GET /_matrix/client/r0/rooms/{roomId}/state](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-state)
pub mod get_state_events {
    use ruma_identifiers::RoomId;
    use ruma_events::collections::only;

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// This API endpoint's path parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct PathParams {
        pub room_id: RoomId
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = PathParams;
        type QueryParams = ();
        type Response = Vec<only::StateEvent>;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(params: Self::PathParams) -> String {
            format!(
                "/_matrix/client/r0/rooms/{}/state",
                params.room_id
            )
        }

        fn router_path() -> &'static str {
            "/_matrix/client/r0/rooms/:room_id/state"
        }

        fn name() -> &'static str {
            "get_state_events"
        }

        fn description() -> &'static str {
            "Get state events for a room."
        }

        fn requires_authentication() -> bool {
            true
        }

        fn rate_limited() -> bool {
            false
        }
    }
}

/// [GET /_matrix/client/r0/rooms/{roomId}/state/{eventType}](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype)
pub mod get_state_events_for_empty_key {
    use ruma_identifiers::RoomId;

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// This API endpoint's path parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct PathParams {
        pub room_id: RoomId,
        pub event_type: String
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = PathParams;
        type QueryParams = ();
        type Response = ::serde_json::Value;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(params: Self::PathParams) -> String {
            format!(
                "/_matrix/client/r0/rooms/{}/state/{}",
                params.room_id,
                params.event_type
            )
        }

        fn router_path() -> &'static str {
            "/_matrix/client/r0/rooms/:room_id/state/:event_type"
        }

        fn name() -> &'static str {
            "get_state_events_for_empty_key"
        }

        fn description() -> &'static str {
            "Get state events of a given type associated with the empty key."
        }

        fn requires_authentication() -> bool {
            true
        }

        fn rate_limited() -> bool {
            false
        }
    }
}

/// [GET /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype-state-key)
pub mod get_state_events_for_key {
    use ruma_identifiers::RoomId;

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// This API endpoint's path parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct PathParams {
        pub room_id: RoomId,
        pub event_type: String,
        pub state_key: String,
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = PathParams;
        type QueryParams = ();
        type Response = ::serde_json::Value;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(params: Self::PathParams) -> String {
            format!(
                "/_matrix/client/r0/rooms/{}/state/{}/{}",
                params.room_id,
                params.event_type,
                params.state_key
            )
        }

        fn router_path() -> &'static str {
            "/_matrix/client/r0/rooms/:room_id/state/:event_type/:state_key"
        }

        fn name() -> &'static str {
            "get_state_events_for_key"
        }

        fn description() -> &'static str {
            "Get state events associated with a given key."
        }

        fn requires_authentication() -> bool {
            true
        }

        fn rate_limited() -> bool {
            false
        }
    }
}

/// [GET /_matrix/client/r0/rooms/{roomId}/members](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-members)
pub mod get_member_events {
    use ruma_identifiers::RoomId;
    use ruma_events::room::member::MemberEvent;

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// This API endpoint's path parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct PathParams {
        pub room_id: RoomId,
    }

    /// This API endpoint's reponse.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Response {
        pub chunks: Vec<MemberEvent>
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = PathParams;
        type QueryParams = ();
        type Response = Response;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(params: Self::PathParams) -> String {
            format!(
                "/_matrix/client/r0/rooms/{}/members",
                params.room_id,
            )
        }

        fn router_path() -> &'static str {
            "/_matrix/client/r0/rooms/:room_id/members"
        }

        fn name() -> &'static str {
            "get_member_events"
        }

        fn description() -> &'static str {
            "Get membership events for a room."
        }

        fn requires_authentication() -> bool {
            // TODO: not marked as requiring auth in the spec, but
            // will return a 403 error is user is not a member of the
            // room anyway...
            false
        }

        fn rate_limited() -> bool {
            false
        }
    }
}

/// [GET /_matrix/client/r0/rooms/{roomId}/messages](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-messages)
pub mod get_message_events {
    use ruma_identifiers::RoomId;
    use ruma_events::collections::only;

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// This API endpoint's path parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct PathParams {
        pub room_id: RoomId,
        pub event_type: String
    }

    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub enum Direction {
        #[serde(rename="b")]
        Backward,
        #[serde(rename="f")]
        Forward
    }

    /// This API endpoint's query string parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct QueryParams {
        pub from: String,
        #[serde(skip_serializing_if = "Option::is_none")]
        pub to: Option<String>,
        pub dir: Direction,
        #[serde(skip_serializing_if = "Option::is_none")]
        pub limit: Option<u64>
    }

    /// This API endpoint's reponse.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Response {
        pub start: String,
        pub chunks: Vec<only::RoomEvent>,
        pub end: String
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = PathParams;
        type QueryParams = QueryParams;
        type Response = Response;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(params: Self::PathParams) -> String {
            format!(
                "/_matrix/client/r0/rooms/{}/messages",
                params.room_id,
            )
        }

        fn router_path() -> &'static str {
            "/_matrix/client/r0/rooms/:room_id/messages"
        }

        fn name() -> &'static str {
            "get_message_events"
        }

        fn description() -> &'static str {
            "Get message events for a room."
        }

        fn requires_authentication() -> bool {
            true
        }

        fn rate_limited() -> bool {
            false
        }
    }
}

/// [GET /_matrix/client/r0/sync](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-sync)
pub mod sync_events {
    use ruma_events::collections::only;
    use ruma_identifiers::RoomId;

    use std::collections::HashMap;

    use r0::filter::FilterDefinition;

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// Whether to set presence or not during sync.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub enum SetPresence {
        #[serde(rename="offline")]
        Offline
    }

    /// A filter represented either as its full JSON definition or the ID of a saved filter.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub enum Filter {
        /// A complete filter definition serialized to JSON.
        FilterDefinition(FilterDefinition),
        /// The ID of a filter saved on the server.
        FilterId(String),
    }

    /// This API endpoint's query string parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct QueryParams {
        #[serde(skip_serializing_if = "Option::is_none")]
        pub filter: Option<Filter>,
        #[serde(skip_serializing_if = "Option::is_none")]
        pub since: Option<String>,
        #[serde(skip_serializing_if = "Option::is_none")]
        pub full_state: Option<bool>,
        #[serde(skip_serializing_if = "Option::is_none")]
        pub set_presence: Option<SetPresence>,
        #[serde(skip_serializing_if = "Option::is_none")]
        pub timeout: Option<u64>
    }

    /// Updates to rooms
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Rooms {
        pub leave: HashMap<RoomId, LeftRoom>,
        pub join: HashMap<RoomId, JoinedRoom>,
        pub invite: HashMap<RoomId, InvitedRoom>
    }

    /// Historical updates to left rooms
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct LeftRoom {
        pub timeline: Timeline,
        pub state: State
    }

    /// Updates to joined rooms
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct JoinedRoom {
        pub unread_notifications: UnreadNotificationsCount,
        pub timeline: Timeline,
        pub state: State,
        pub account_data: AccountData,
        pub ephemeral: Ephemeral
    }

    /// unread notifications count
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct UnreadNotificationsCount {
        pub highlight_count: u64,
        pub notification_count: u64
    }

    /// timeline
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Timeline {
        pub limited: bool,
        pub prev_batch: String,
        pub events: only::RoomEvent
    }

    /// state
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct State {
        pub events: only::StateEvent
    }

    /// account data
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct AccountData {
        pub events: only::Event
    }

    /// ephemeral
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Ephemeral {
        pub events: only::Event
    }

    /// invited room updates
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct InvitedRoom {
        pub invite_state: InviteState
    }

    /// invite state
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct InviteState {
        pub events: only::StateEvent
    }

    /// presence
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Presence {
        pub events: only::Event
    }

    /// This API endpoint's reponse.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Response {
        pub next_batch: String,
        pub rooms: Rooms,
        pub presence: Presence
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = ();
        type QueryParams = QueryParams;
        type Response = Response;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(_params: Self::PathParams) -> String {
            "/_matrix/client/r0/sync".to_string()
        }

        fn router_path() -> &'static str {
            "/_matrix/client/r0/sync"
        }

        fn name() -> &'static str {
            "sync"
        }

        fn description() -> &'static str {
            "Get all new events from all rooms since the last sync or a given point of time."
        }

        fn requires_authentication() -> bool {
            true
        }

        fn rate_limited() -> bool {
            false
        }
    }
}
<commit_msg>The member event response contains the field chunk, not chunks<commit_after>//! Endpoints for getting and synchronizing events.

/// [GET /_matrix/client/r0/rooms/{roomId}/state](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-state)
pub mod get_state_events {
    use ruma_identifiers::RoomId;
    use ruma_events::collections::only;

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// This API endpoint's path parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct PathParams {
        pub room_id: RoomId
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = PathParams;
        type QueryParams = ();
        type Response = Vec<only::StateEvent>;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(params: Self::PathParams) -> String {
            format!(
                "/_matrix/client/r0/rooms/{}/state",
                params.room_id
            )
        }

        fn router_path() -> &'static str {
            "/_matrix/client/r0/rooms/:room_id/state"
        }

        fn name() -> &'static str {
            "get_state_events"
        }

        fn description() -> &'static str {
            "Get state events for a room."
        }

        fn requires_authentication() -> bool {
            true
        }

        fn rate_limited() -> bool {
            false
        }
    }
}

/// [GET /_matrix/client/r0/rooms/{roomId}/state/{eventType}](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype)
pub mod get_state_events_for_empty_key {
    use ruma_identifiers::RoomId;

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// This API endpoint's path parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct PathParams {
        pub room_id: RoomId,
        pub event_type: String
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = PathParams;
        type QueryParams = ();
        type Response = ::serde_json::Value;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(params: Self::PathParams) -> String {
            format!(
                "/_matrix/client/r0/rooms/{}/state/{}",
                params.room_id,
                params.event_type
            )
        }

        fn router_path() -> &'static str {
            "/_matrix/client/r0/rooms/:room_id/state/:event_type"
        }

        fn name() -> &'static str {
            "get_state_events_for_empty_key"
        }

        fn description() -> &'static str {
            "Get state events of a given type associated with the empty key."
        }

        fn requires_authentication() -> bool {
            true
        }

        fn rate_limited() -> bool {
            false
        }
    }
}

/// [GET /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype-state-key)
pub mod get_state_events_for_key {
    use ruma_identifiers::RoomId;

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// This API endpoint's path parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct PathParams {
        pub room_id: RoomId,
        pub event_type: String,
        pub state_key: String,
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = PathParams;
        type QueryParams = ();
        type Response = ::serde_json::Value;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(params: Self::PathParams) -> String {
            format!(
                "/_matrix/client/r0/rooms/{}/state/{}/{}",
                params.room_id,
                params.event_type,
                params.state_key
            )
        }

        fn router_path() -> &'static str {
            "/_matrix/client/r0/rooms/:room_id/state/:event_type/:state_key"
        }

        fn name() -> &'static str {
            "get_state_events_for_key"
        }

        fn description() -> &'static str {
            "Get state events associated with a given key."
        }

        fn requires_authentication() -> bool {
            true
        }

        fn rate_limited() -> bool {
            false
        }
    }
}

/// [GET /_matrix/client/r0/rooms/{roomId}/members](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-members)
pub mod get_member_events {
    use ruma_identifiers::RoomId;
    use ruma_events::room::member::MemberEvent;

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// This API endpoint's path parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct PathParams {
        pub room_id: RoomId,
    }

    /// This API endpoint's reponse.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Response {
        pub chunk: Vec<MemberEvent>
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = PathParams;
        type QueryParams = ();
        type Response = Response;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(params: Self::PathParams) -> String {
            format!(
                "/_matrix/client/r0/rooms/{}/members",
                params.room_id,
            )
        }

        fn router_path() -> &'static str {
            "/_matrix/client/r0/rooms/:room_id/members"
        }

        fn name() -> &'static str {
            "get_member_events"
        }

        fn description() -> &'static str {
            "Get membership events for a room."
        }

        fn requires_authentication() -> bool {
            // TODO: not marked as requiring auth in the spec, but
            // will return a 403 error is user is not a member of the
            // room anyway...
            false
        }

        fn rate_limited() -> bool {
            false
        }
    }
}

/// [GET /_matrix/client/r0/rooms/{roomId}/messages](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-messages)
pub mod get_message_events {
    use ruma_identifiers::RoomId;
    use ruma_events::collections::only;

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// This API endpoint's path parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct PathParams {
        pub room_id: RoomId,
        pub event_type: String
    }

    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub enum Direction {
        #[serde(rename="b")]
        Backward,
        #[serde(rename="f")]
        Forward
    }

    /// This API endpoint's query string parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct QueryParams {
        pub from: String,
        #[serde(skip_serializing_if = "Option::is_none")]
        pub to: Option<String>,
        pub dir: Direction,
        #[serde(skip_serializing_if = "Option::is_none")]
        pub limit: Option<u64>
    }

    /// This API endpoint's reponse.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Response {
        pub start: String,
        pub chunk: Vec<only::RoomEvent>,
        pub end: String
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = PathParams;
        type QueryParams = QueryParams;
        type Response = Response;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(params: Self::PathParams) -> String {
            format!(
                "/_matrix/client/r0/rooms/{}/messages",
                params.room_id,
            )
        }

        fn router_path() -> &'static str {
            "/_matrix/client/r0/rooms/:room_id/messages"
        }

        fn name() -> &'static str {
            "get_message_events"
        }

        fn description() -> &'static str {
            "Get message events for a room."
        }

        fn requires_authentication() -> bool {
            true
        }

        fn rate_limited() -> bool {
            false
        }
    }
}

/// [GET /_matrix/client/r0/sync](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-sync)
pub mod sync_events {
    use ruma_events::collections::only;
    use ruma_identifiers::RoomId;

    use std::collections::HashMap;

    use r0::filter::FilterDefinition;

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// Whether to set presence or not during sync.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub enum SetPresence {
        #[serde(rename="offline")]
        Offline
    }

    /// A filter represented either as its full JSON definition or the ID of a saved filter.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub enum Filter {
        /// A complete filter definition serialized to JSON.
        FilterDefinition(FilterDefinition),
        /// The ID of a filter saved on the server.
        FilterId(String),
    }

    /// This API endpoint's query string parameters.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct QueryParams {
        #[serde(skip_serializing_if = "Option::is_none")]
        pub filter: Option<Filter>,
        #[serde(skip_serializing_if = "Option::is_none")]
        pub since: Option<String>,
        #[serde(skip_serializing_if = "Option::is_none")]
        pub full_state: Option<bool>,
        #[serde(skip_serializing_if = "Option::is_none")]
        pub set_presence: Option<SetPresence>,
        #[serde(skip_serializing_if = "Option::is_none")]
        pub timeout: Option<u64>
    }

    /// Updates to rooms
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Rooms {
        pub leave: HashMap<RoomId, LeftRoom>,
        pub join: HashMap<RoomId, JoinedRoom>,
        pub invite: HashMap<RoomId, InvitedRoom>
    }

    /// Historical updates to left rooms
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct LeftRoom {
        pub timeline: Timeline,
        pub state: State
    }

    /// Updates to joined rooms
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct JoinedRoom {
        pub unread_notifications: UnreadNotificationsCount,
        pub timeline: Timeline,
        pub state: State,
        pub account_data: AccountData,
        pub ephemeral: Ephemeral
    }

    /// unread notifications count
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct UnreadNotificationsCount {
        pub highlight_count: u64,
        pub notification_count: u64
    }

    /// timeline
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Timeline {
        pub limited: bool,
        pub prev_batch: String,
        pub events: only::RoomEvent
    }

    /// state
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct State {
        pub events: only::StateEvent
    }

    /// account data
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct AccountData {
        pub events: only::Event
    }

    /// ephemeral
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Ephemeral {
        pub events: only::Event
    }

    /// invited room updates
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct InvitedRoom {
        pub invite_state: InviteState
    }

    /// invite state
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct InviteState {
        pub events: only::StateEvent
    }

    /// presence
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Presence {
        pub events: only::Event
    }

    /// This API endpoint's reponse.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Response {
        pub next_batch: String,
        pub rooms: Rooms,
        pub presence: Presence
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = ();
        type QueryParams = QueryParams;
        type Response = Response;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(_params: Self::PathParams) -> String {
            "/_matrix/client/r0/sync".to_string()
        }

        fn router_path() -> &'static str {
            "/_matrix/client/r0/sync"
        }

        fn name() -> &'static str {
            "sync"
        }

        fn description() -> &'static str {
            "Get all new events from all rooms since the last sync or a given point of time."
        }

        fn requires_authentication() -> bool {
            true
        }

        fn rate_limited() -> bool {
            false
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Rust: Problem 7<commit_after>/// # 10001st prime
/// ## Problem 7
/// By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
/// What is the 10 001st prime number?

use std::collections::TreeSet;

fn main() {
  let mut num = 3;
  let mut primes = TreeSet::<int>::new();
  primes.insert(2);

  while primes.len() != 10001 {
    if primes.iter().take_while(|&p| *p < num / 2).all(|&p| num % p != 0) {
      primes.insert(num);
    }
    num += 2;
  }
  println!("{}", primes.iter().nth(10000).unwrap())

}
<|endoftext|>


<commit_before>//! Matrix user identifiers.

use std::{
    convert::TryFrom,
    fmt::{Display, Formatter, Result as FmtResult},
};

#[cfg(feature = "diesel")]
use diesel::sql_types::Text;
use once_cell::sync::Lazy;
use regex::Regex;
use serde::{
    de::{Error as SerdeError, Unexpected, Visitor},
    Deserialize, Deserializer, Serialize, Serializer,
};
use url::Host;

use crate::{display, error::Error, generate_localpart, parse_id};

static USER_LOCALPART_PATTERN: Lazy<Regex> =
    Lazy::new(|| Regex::new(r"\A[a-z0-9._=-]+\z").expect("Failed to create user localpart regex."));

/// A Matrix user ID.
///
/// A `UserId` is generated randomly or converted from a string slice, and can be converted back
/// into a string as needed.
///
/// ```
/// # use std::convert::TryFrom;
/// # use ruma_identifiers::UserId;
/// assert_eq!(
///     UserId::try_from("@carl:example.com").unwrap().to_string(),
///     "@carl:example.com"
/// );
/// ```
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "diesel", derive(FromSqlRow, QueryId, AsExpression, SqlType))]
#[cfg_attr(feature = "diesel", sql_type = "Text")]
pub struct UserId {
    /// The hostname of the homeserver.
    hostname: Host,
    /// The user's unique ID.
    localpart: String,
    /// The network port of the homeserver.
    port: u16,
}

/// A serde visitor for `UserId`.
struct UserIdVisitor;

impl UserId {
    /// Attempts to generate a `UserId` for the given origin server with a localpart consisting of
    /// 12 random ASCII characters.
    ///
    /// Fails if the given homeserver cannot be parsed as a valid host.
    pub fn new(homeserver_host: &str) -> Result<Self, Error> {
        let user_id = format!(
            "@{}:{}",
            generate_localpart(12).to_lowercase(),
            homeserver_host
        );
        let (localpart, host, port) = parse_id('@', &user_id)?;

        Ok(Self {
            hostname: host,
            localpart: localpart.to_string(),
            port,
        })
    }

    /// Returns a `Host` for the user ID, containing the server name (minus the port) of the
    /// originating homeserver.
    ///
    /// The host can be either a domain name, an IPv4 address, or an IPv6 address.
    pub fn hostname(&self) -> &Host {
        &self.hostname
    }

    /// Returns the user's localpart.
    pub fn localpart(&self) -> &str {
        &self.localpart
    }

    /// Returns the port the originating homeserver can be accessed on.
    pub fn port(&self) -> u16 {
        self.port
    }
}

impl Display for UserId {
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        display(f, '@', &self.localpart, &self.hostname, self.port)
    }
}

impl Serialize for UserId {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl<'de> Deserialize<'de> for UserId {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_any(UserIdVisitor)
    }
}

impl<'a> TryFrom<&'a str> for UserId {
    type Error = Error;

    /// Attempts to create a new Matrix user ID from a string representation.
    ///
    /// The string must include the leading @ sigil, the localpart, a literal colon, and a valid
    /// server name.
    fn try_from(user_id: &'a str) -> Result<Self, Error> {
        let (localpart, host, port) = parse_id('@', user_id)?;
        let downcased_localpart = localpart.to_lowercase();

        if !USER_LOCALPART_PATTERN.is_match(&downcased_localpart) {
            return Err(Error::InvalidCharacters);
        }

        Ok(Self {
            hostname: host,
            port,
            localpart: downcased_localpart,
        })
    }
}

impl<'de> Visitor<'de> for UserIdVisitor {
    type Value = UserId;

    fn expecting(&self, formatter: &mut Formatter<'_>) -> FmtResult {
        write!(formatter, "a Matrix user ID as a string")
    }

    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
    where
        E: SerdeError,
    {
        match UserId::try_from(v) {
            Ok(user_id) => Ok(user_id),
            Err(_) => Err(SerdeError::invalid_value(Unexpected::Str(v), &self)),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use serde_json::{from_str, to_string};

    use super::UserId;
    use crate::error::Error;

    #[test]
    fn valid_user_id() {
        assert_eq!(
            UserId::try_from("@carl:example.com")
                .expect("Failed to create UserId.")
                .to_string(),
            "@carl:example.com"
        );
    }

    #[test]
    fn downcase_user_id() {
        assert_eq!(
            UserId::try_from("@CARL:example.com")
                .expect("Failed to create UserId.")
                .to_string(),
            "@carl:example.com"
        );
    }

    #[test]
    fn generate_random_valid_user_id() {
        let user_id = UserId::new("example.com")
            .expect("Failed to generate UserId.")
            .to_string();

        assert!(user_id.to_string().starts_with('@'));
        assert_eq!(user_id.len(), 25);
    }

    #[test]
    fn generate_random_invalid_user_id() {
        assert!(UserId::new("").is_err());
    }

    #[test]
    fn serialize_valid_user_id() {
        assert_eq!(
            to_string(&UserId::try_from("@carl:example.com").expect("Failed to create UserId."))
                .expect("Failed to convert UserId to JSON."),
            r#""@carl:example.com""#
        );
    }

    #[test]
    fn deserialize_valid_user_id() {
        assert_eq!(
            from_str::<UserId>(r#""@carl:example.com""#).expect("Failed to convert JSON to UserId"),
            UserId::try_from("@carl:example.com").expect("Failed to create UserId.")
        );
    }

    #[test]
    fn valid_user_id_with_explicit_standard_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:443")
                .expect("Failed to create UserId.")
                .to_string(),
            "@carl:example.com"
        );
    }

    #[test]
    fn valid_user_id_with_non_standard_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:5000")
                .expect("Failed to create UserId.")
                .to_string(),
            "@carl:example.com:5000"
        );
    }

    #[test]
    fn invalid_characters_in_user_id_localpart() {
        assert_eq!(
            UserId::try_from("@%%%:example.com").err().unwrap(),
            Error::InvalidCharacters
        );
    }

    #[test]
    fn missing_user_id_sigil() {
        assert_eq!(
            UserId::try_from("carl:example.com").err().unwrap(),
            Error::MissingSigil
        );
    }

    #[test]
    fn missing_user_id_delimiter() {
        assert_eq!(
            UserId::try_from("@carl").err().unwrap(),
            Error::MissingDelimiter
        );
    }

    #[test]
    fn invalid_user_id_host() {
        assert_eq!(
            UserId::try_from("@carl:/").err().unwrap(),
            Error::InvalidHost
        );
    }

    #[test]
    fn invalid_user_id_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:notaport")
                .err()
                .unwrap(),
            Error::InvalidHost
        );
    }
}
<commit_msg>Update set of allowed characters in UserId localpart<commit_after>//! Matrix user identifiers.

use std::{
    convert::TryFrom,
    fmt::{Display, Formatter, Result as FmtResult},
};

#[cfg(feature = "diesel")]
use diesel::sql_types::Text;
use once_cell::sync::Lazy;
use regex::Regex;
use serde::{
    de::{Error as SerdeError, Unexpected, Visitor},
    Deserialize, Deserializer, Serialize, Serializer,
};
use url::Host;

use crate::{display, error::Error, generate_localpart, parse_id};

// See https://matrix.org/docs/spec/appendices#user-identifiers
static USER_LOCALPART_PATTERN: Lazy<Regex> = Lazy::new(|| {
    Regex::new(r"\A[a-z0-9\-.=_/]+\z").expect("Failed to create user localpart regex.")
});

/// A Matrix user ID.
///
/// A `UserId` is generated randomly or converted from a string slice, and can be converted back
/// into a string as needed.
///
/// ```
/// # use std::convert::TryFrom;
/// # use ruma_identifiers::UserId;
/// assert_eq!(
///     UserId::try_from("@carl:example.com").unwrap().to_string(),
///     "@carl:example.com"
/// );
/// ```
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "diesel", derive(FromSqlRow, QueryId, AsExpression, SqlType))]
#[cfg_attr(feature = "diesel", sql_type = "Text")]
pub struct UserId {
    /// The hostname of the homeserver.
    hostname: Host,
    /// The user's unique ID.
    localpart: String,
    /// The network port of the homeserver.
    port: u16,
}

/// A serde visitor for `UserId`.
struct UserIdVisitor;

impl UserId {
    /// Attempts to generate a `UserId` for the given origin server with a localpart consisting of
    /// 12 random ASCII characters.
    ///
    /// Fails if the given homeserver cannot be parsed as a valid host.
    pub fn new(homeserver_host: &str) -> Result<Self, Error> {
        let user_id = format!(
            "@{}:{}",
            generate_localpart(12).to_lowercase(),
            homeserver_host
        );
        let (localpart, host, port) = parse_id('@', &user_id)?;

        Ok(Self {
            hostname: host,
            localpart: localpart.to_string(),
            port,
        })
    }

    /// Returns a `Host` for the user ID, containing the server name (minus the port) of the
    /// originating homeserver.
    ///
    /// The host can be either a domain name, an IPv4 address, or an IPv6 address.
    pub fn hostname(&self) -> &Host {
        &self.hostname
    }

    /// Returns the user's localpart.
    pub fn localpart(&self) -> &str {
        &self.localpart
    }

    /// Returns the port the originating homeserver can be accessed on.
    pub fn port(&self) -> u16 {
        self.port
    }
}

impl Display for UserId {
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        display(f, '@', &self.localpart, &self.hostname, self.port)
    }
}

impl Serialize for UserId {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl<'de> Deserialize<'de> for UserId {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_any(UserIdVisitor)
    }
}

impl<'a> TryFrom<&'a str> for UserId {
    type Error = Error;

    /// Attempts to create a new Matrix user ID from a string representation.
    ///
    /// The string must include the leading @ sigil, the localpart, a literal colon, and a valid
    /// server name.
    fn try_from(user_id: &'a str) -> Result<Self, Error> {
        let (localpart, host, port) = parse_id('@', user_id)?;
        let downcased_localpart = localpart.to_lowercase();

        if !USER_LOCALPART_PATTERN.is_match(&downcased_localpart) {
            return Err(Error::InvalidCharacters);
        }

        Ok(Self {
            hostname: host,
            port,
            localpart: downcased_localpart,
        })
    }
}

impl<'de> Visitor<'de> for UserIdVisitor {
    type Value = UserId;

    fn expecting(&self, formatter: &mut Formatter<'_>) -> FmtResult {
        write!(formatter, "a Matrix user ID as a string")
    }

    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
    where
        E: SerdeError,
    {
        match UserId::try_from(v) {
            Ok(user_id) => Ok(user_id),
            Err(_) => Err(SerdeError::invalid_value(Unexpected::Str(v), &self)),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use serde_json::{from_str, to_string};

    use super::UserId;
    use crate::error::Error;

    #[test]
    fn valid_user_id() {
        assert_eq!(
            UserId::try_from("@carl:example.com")
                .expect("Failed to create UserId.")
                .to_string(),
            "@carl:example.com"
        );
    }

    #[test]
    fn downcase_user_id() {
        assert_eq!(
            UserId::try_from("@CARL:example.com")
                .expect("Failed to create UserId.")
                .to_string(),
            "@carl:example.com"
        );
    }

    #[test]
    fn generate_random_valid_user_id() {
        let user_id = UserId::new("example.com")
            .expect("Failed to generate UserId.")
            .to_string();

        assert!(user_id.to_string().starts_with('@'));
        assert_eq!(user_id.len(), 25);
    }

    #[test]
    fn generate_random_invalid_user_id() {
        assert!(UserId::new("").is_err());
    }

    #[test]
    fn serialize_valid_user_id() {
        assert_eq!(
            to_string(&UserId::try_from("@carl:example.com").expect("Failed to create UserId."))
                .expect("Failed to convert UserId to JSON."),
            r#""@carl:example.com""#
        );
    }

    #[test]
    fn deserialize_valid_user_id() {
        assert_eq!(
            from_str::<UserId>(r#""@carl:example.com""#).expect("Failed to convert JSON to UserId"),
            UserId::try_from("@carl:example.com").expect("Failed to create UserId.")
        );
    }

    #[test]
    fn valid_user_id_with_explicit_standard_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:443")
                .expect("Failed to create UserId.")
                .to_string(),
            "@carl:example.com"
        );
    }

    #[test]
    fn valid_user_id_with_non_standard_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:5000")
                .expect("Failed to create UserId.")
                .to_string(),
            "@carl:example.com:5000"
        );
    }

    #[test]
    fn invalid_characters_in_user_id_localpart() {
        assert_eq!(
            UserId::try_from("@%%%:example.com").err().unwrap(),
            Error::InvalidCharacters
        );
    }

    #[test]
    fn missing_user_id_sigil() {
        assert_eq!(
            UserId::try_from("carl:example.com").err().unwrap(),
            Error::MissingSigil
        );
    }

    #[test]
    fn missing_user_id_delimiter() {
        assert_eq!(
            UserId::try_from("@carl").err().unwrap(),
            Error::MissingDelimiter
        );
    }

    #[test]
    fn invalid_user_id_host() {
        assert_eq!(
            UserId::try_from("@carl:/").err().unwrap(),
            Error::InvalidHost
        );
    }

    #[test]
    fn invalid_user_id_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:notaport")
                .err()
                .unwrap(),
            Error::InvalidHost
        );
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// Original implementation taken from rust-memchr
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch

/// A safe interface to `memchr`.
///
/// Returns the index corresponding to the first occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// memchr reduces to super-optimized machine code at around an order of
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
/// (See benchmarks.)
///
/// # Example
///
/// This shows how to find the first position of a byte in a byte string.
///
/// ```rust,ignore
/// use memchr::memchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memchr(b'k', haystack), Some(8));
/// ```
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
    // libc memchr
    #[cfg(not(target_os = "windows"))]
    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        use libc;

        let p = unsafe {
            libc::memchr(
                haystack.as_ptr() as *const libc::c_void,
                needle as libc::c_int,
                haystack.len() as libc::size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    // use fallback on windows, since it's faster
    #[cfg(target_os = "windows")]
    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        fallback::memchr(needle, haystack)
    }

    memchr_specific(needle, haystack)
}

/// A safe interface to `memrchr`.
///
/// Returns the index corresponding to the last occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// # Example
///
/// This shows how to find the last position of a byte in a byte string.
///
/// ```rust,ignore
/// use memchr::memrchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memrchr(b'o', haystack), Some(17));
/// ```
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {

    #[cfg(target_os = "linux")]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        use libc;

        // GNU's memrchr() will - unlike memchr() - error if haystack is empty.
        if haystack.is_empty() {return None}
        let p = unsafe {
            libc::memrchr(
                haystack.as_ptr() as *const libc::c_void,
                needle as libc::c_int,
                haystack.len() as libc::size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    #[cfg(not(target_os = "linux"))]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        haystack.iter().rposition(|&b| b == needle)
    }

    memrchr_specific(needle, haystack)
}

#[allow(dead_code)]
mod fallback {
    use cmp;
    use mem;

    const LO_U64: u64 = 0x0101010101010101;
    const HI_U64: u64 = 0x8080808080808080;

    // use truncation
    const LO_USIZE: usize = LO_U64 as usize;
    const HI_USIZE: usize = HI_U64 as usize;

    /// Return `true` if `x` contains any zero byte.
    ///
    /// From *Matters Computational*, J. Arndt
    ///
    /// "The idea is to subtract one from each of the bytes and then look for
    /// bytes where the borrow propagated all the way to the most significant
    /// bit."
    #[inline]
    fn contains_zero_byte(x: usize) -> bool {
        x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
    }

    #[cfg(target_pointer_width = "32")]
    #[inline]
    fn repeat_byte(b: u8) -> usize {
        let mut rep = (b as usize) << 8 | b as usize;
        rep = rep << 16 | rep;
        rep
    }

    #[cfg(target_pointer_width = "64")]
    #[inline]
    fn repeat_byte(b: u8) -> usize {
        let mut rep = (b as usize) << 8 | b as usize;
        rep = rep << 16 | rep;
        rep = rep << 32 | rep;
        rep
    }

    /// Return the first index matching the byte `a` in `text`.
    pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
        // Scan for a single byte value by reading two `usize` words at a time.
        //
        // Split `text` in three parts
        // - unaligned inital part, before the first word aligned address in text
        // - body, scan by 2 words at a time
        // - the last remaining part, < 2 word size
        let len = text.len();
        let ptr = text.as_ptr();
        let usize_bytes = mem::size_of::<usize>();

        // search up to an aligned boundary
        let align = (ptr as usize) & (usize_bytes- 1);
        let mut offset;
        if align > 0 {
            offset = cmp::min(usize_bytes - align, len);
            if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
                return Some(index);
            }
        } else {
            offset = 0;
        }

        // search the body of the text
        let repeated_x = repeat_byte(x);

        if len >= 2 * usize_bytes {
            while offset <= len - 2 * usize_bytes {
                unsafe {
                    let u = *(ptr.offset(offset as isize) as *const usize);
                    let v = *(ptr.offset((offset + usize_bytes) as isize) as *const usize);

                    // break if there is a matching byte
                    let zu = contains_zero_byte(u ^ repeated_x);
                    let zv = contains_zero_byte(v ^ repeated_x);
                    if zu || zv {
                        break;
                    }
                }
                offset += usize_bytes * 2;
            }
        }

        // find the byte after the point the body loop stopped
        text[offset..].iter().position(|elt| *elt == x).map(|i| offset + i)
    }

    /// Return the last index matching the byte `a` in `text`.
    pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
        // Scan for a single byte value by reading two `usize` words at a time.
        //
        // Split `text` in three parts
        // - unaligned tail, after the last word aligned address in text
        // - body, scan by 2 words at a time
        // - the first remaining bytes, < 2 word size
        let len = text.len();
        let ptr = text.as_ptr();
        let usize_bytes = mem::size_of::<usize>();

        // search to an aligned boundary
        let end_align = (ptr as usize + len) & (usize_bytes - 1);
        let mut offset;
        if end_align > 0 {
            offset = len - cmp::min(usize_bytes - end_align, len);
            if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
                return Some(offset + index);
            }
        } else {
            offset = len;
        }

        // search the body of the text
        let repeated_x = repeat_byte(x);

        while offset >= 2 * usize_bytes {
            unsafe {
                let u = *(ptr.offset(offset as isize - 2 * usize_bytes as isize) as *const usize);
                let v = *(ptr.offset(offset as isize - usize_bytes as isize) as *const usize);

                // break if there is a matching byte
                let zu = contains_zero_byte(u ^ repeated_x);
                let zv = contains_zero_byte(v ^ repeated_x);
                if zu || zv {
                    break;
                }
            }
            offset -= 2 * usize_bytes;
        }

        // find the byte before the point the body loop stopped
        text[..offset].iter().rposition(|elt| *elt == x)
    }

    // test fallback implementations on all plattforms
    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }
}

#[cfg(test)]
mod tests {
    // test the implementations for the current plattform
    use super::{memchr, memrchr};

    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }
}
<commit_msg>std: Use the fallback impl for memrchr on non-linux<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// Original implementation taken from rust-memchr
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch

/// A safe interface to `memchr`.
///
/// Returns the index corresponding to the first occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// memchr reduces to super-optimized machine code at around an order of
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
/// (See benchmarks.)
///
/// # Example
///
/// This shows how to find the first position of a byte in a byte string.
///
/// ```rust,ignore
/// use memchr::memchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memchr(b'k', haystack), Some(8));
/// ```
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
    // libc memchr
    #[cfg(not(target_os = "windows"))]
    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        use libc;

        let p = unsafe {
            libc::memchr(
                haystack.as_ptr() as *const libc::c_void,
                needle as libc::c_int,
                haystack.len() as libc::size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    // use fallback on windows, since it's faster
    #[cfg(target_os = "windows")]
    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        fallback::memchr(needle, haystack)
    }

    memchr_specific(needle, haystack)
}

/// A safe interface to `memrchr`.
///
/// Returns the index corresponding to the last occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// # Example
///
/// This shows how to find the last position of a byte in a byte string.
///
/// ```rust,ignore
/// use memchr::memrchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memrchr(b'o', haystack), Some(17));
/// ```
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {

    #[cfg(target_os = "linux")]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        use libc;

        // GNU's memrchr() will - unlike memchr() - error if haystack is empty.
        if haystack.is_empty() {return None}
        let p = unsafe {
            libc::memrchr(
                haystack.as_ptr() as *const libc::c_void,
                needle as libc::c_int,
                haystack.len() as libc::size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    #[cfg(not(target_os = "linux"))]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        fallback::memrchr(needle, haystack)
    }

    memrchr_specific(needle, haystack)
}

#[allow(dead_code)]
mod fallback {
    use cmp;
    use mem;

    const LO_U64: u64 = 0x0101010101010101;
    const HI_U64: u64 = 0x8080808080808080;

    // use truncation
    const LO_USIZE: usize = LO_U64 as usize;
    const HI_USIZE: usize = HI_U64 as usize;

    /// Return `true` if `x` contains any zero byte.
    ///
    /// From *Matters Computational*, J. Arndt
    ///
    /// "The idea is to subtract one from each of the bytes and then look for
    /// bytes where the borrow propagated all the way to the most significant
    /// bit."
    #[inline]
    fn contains_zero_byte(x: usize) -> bool {
        x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
    }

    #[cfg(target_pointer_width = "32")]
    #[inline]
    fn repeat_byte(b: u8) -> usize {
        let mut rep = (b as usize) << 8 | b as usize;
        rep = rep << 16 | rep;
        rep
    }

    #[cfg(target_pointer_width = "64")]
    #[inline]
    fn repeat_byte(b: u8) -> usize {
        let mut rep = (b as usize) << 8 | b as usize;
        rep = rep << 16 | rep;
        rep = rep << 32 | rep;
        rep
    }

    /// Return the first index matching the byte `a` in `text`.
    pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
        // Scan for a single byte value by reading two `usize` words at a time.
        //
        // Split `text` in three parts
        // - unaligned inital part, before the first word aligned address in text
        // - body, scan by 2 words at a time
        // - the last remaining part, < 2 word size
        let len = text.len();
        let ptr = text.as_ptr();
        let usize_bytes = mem::size_of::<usize>();

        // search up to an aligned boundary
        let align = (ptr as usize) & (usize_bytes- 1);
        let mut offset;
        if align > 0 {
            offset = cmp::min(usize_bytes - align, len);
            if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
                return Some(index);
            }
        } else {
            offset = 0;
        }

        // search the body of the text
        let repeated_x = repeat_byte(x);

        if len >= 2 * usize_bytes {
            while offset <= len - 2 * usize_bytes {
                unsafe {
                    let u = *(ptr.offset(offset as isize) as *const usize);
                    let v = *(ptr.offset((offset + usize_bytes) as isize) as *const usize);

                    // break if there is a matching byte
                    let zu = contains_zero_byte(u ^ repeated_x);
                    let zv = contains_zero_byte(v ^ repeated_x);
                    if zu || zv {
                        break;
                    }
                }
                offset += usize_bytes * 2;
            }
        }

        // find the byte after the point the body loop stopped
        text[offset..].iter().position(|elt| *elt == x).map(|i| offset + i)
    }

    /// Return the last index matching the byte `a` in `text`.
    pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
        // Scan for a single byte value by reading two `usize` words at a time.
        //
        // Split `text` in three parts
        // - unaligned tail, after the last word aligned address in text
        // - body, scan by 2 words at a time
        // - the first remaining bytes, < 2 word size
        let len = text.len();
        let ptr = text.as_ptr();
        let usize_bytes = mem::size_of::<usize>();

        // search to an aligned boundary
        let end_align = (ptr as usize + len) & (usize_bytes - 1);
        let mut offset;
        if end_align > 0 {
            offset = len - cmp::min(usize_bytes - end_align, len);
            if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
                return Some(offset + index);
            }
        } else {
            offset = len;
        }

        // search the body of the text
        let repeated_x = repeat_byte(x);

        while offset >= 2 * usize_bytes {
            unsafe {
                let u = *(ptr.offset(offset as isize - 2 * usize_bytes as isize) as *const usize);
                let v = *(ptr.offset(offset as isize - usize_bytes as isize) as *const usize);

                // break if there is a matching byte
                let zu = contains_zero_byte(u ^ repeated_x);
                let zv = contains_zero_byte(v ^ repeated_x);
                if zu || zv {
                    break;
                }
            }
            offset -= 2 * usize_bytes;
        }

        // find the byte before the point the body loop stopped
        text[..offset].iter().rposition(|elt| *elt == x)
    }

    // test fallback implementations on all plattforms
    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }
}

#[cfg(test)]
mod tests {
    // test the implementations for the current plattform
    use super::{memchr, memrchr};

    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }
}
<|endoftext|>


<commit_before><commit_msg>Add async fn test for #66695<commit_after>// build-pass
// edition:2018

static A: [i32; 5] = [1, 2, 3, 4, 5];

async fn fun() {
    let u = A[async { 1 }.await];
    match A {
        i if async { true }.await => (),
        _ => (),
    }
}

fn main() {
    async {
        let u = A[async { 1 }.await];
    };
    async {
        match A {
            i if async { true }.await => (),
            _ => (),
        }
    };
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/*!
# Rust-PortAudio

__Portaudio__ bindings for Rust

PortAudio provides a uniform application programming interface (API) across all
supported platforms.  You can think of the PortAudio library as a wrapper that
converts calls to the PortAudio API into calls to platform-specific native audio
APIs. Operating systems often offer more than one native audio API and some APIs
(such as JACK) may be available on multiple target operating systems.
PortAudio supports all the major native audio APIs on each supported platform.

# Installation

You must install on your computer the Portaudio libraries who is used for
the binding.

Portaudio is available with package management tools on Linux, or brew on Mac OS.

You can download it directly from the website :
[portaudio](http://www.portaudio.com/download.html)

Then clone the repo and build the library with the following command at the root
of the __rust-portaudio__ repository.

__rust-portaudio__ is build with the rustpkg tool :

```Shell
> rustpkg build portaudio
```

*/

#[crate_id = "portaudio#0.1"];

#[comment = "Portaudio binding for Rust"];
// #[license = "Zlib/png"];
#[crate_type = "dylib"];
#[crate_type = "rlib"];

#[feature(globs)];
#[warn(missing_doc)];
#[allow(dead_code)];
#[allow(visible_private_types)];

extern crate extra;

#[cfg(target_os="macos")]
#[cfg(target_os="linux")]
#[cfg(target_os="win32")]
mod c_library {
    #[link(name = "portaudio")]
    extern {}
}

pub mod types;
pub mod pa;

//#[doc(hidden)]
//pub mod user_traits;
//#[doc(hidden)]
//#[cfg(target_os="macos")]
//pub mod mac_core;
//pub mod asio;
#[doc(hidden)]
mod ffi;
<commit_msg>update to last Rust - libextra - ~[] -> remove warn temporary<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/*!
# Rust-PortAudio

__Portaudio__ bindings for Rust

PortAudio provides a uniform application programming interface (API) across all
supported platforms.  You can think of the PortAudio library as a wrapper that
converts calls to the PortAudio API into calls to platform-specific native audio
APIs. Operating systems often offer more than one native audio API and some APIs
(such as JACK) may be available on multiple target operating systems.
PortAudio supports all the major native audio APIs on each supported platform.

# Installation

You must install on your computer the Portaudio libraries who is used for
the binding.

Portaudio is available with package management tools on Linux, or brew on Mac OS.

You can download it directly from the website :
[portaudio](http://www.portaudio.com/download.html)

Then clone the repo and build the library with the following command at the root
of the __rust-portaudio__ repository.

__rust-portaudio__ is build with the rustpkg tool :

```Shell
> rustpkg build portaudio
```

*/

#[crate_id = "portaudio#0.1"];

#[comment = "Portaudio binding for Rust"];
// #[license = "Zlib/png"];
#[crate_type = "dylib"];
#[crate_type = "rlib"];

#[feature(globs)];
#[warn(missing_doc)];
#[allow(dead_code)];
#[allow(visible_private_types)];
#[allow(deprecated_owned_vector)];

#[cfg(target_os="macos")]
#[cfg(target_os="linux")]
#[cfg(target_os="win32")]
mod c_library {
    #[link(name = "portaudio")]
    extern {}
}

pub mod types;
pub mod pa;

//#[doc(hidden)]
//pub mod user_traits;
//#[doc(hidden)]
//#[cfg(target_os="macos")]
//pub mod mac_core;
//pub mod asio;
#[doc(hidden)]
mod ffi;
<|endoftext|>


<commit_before><commit_msg>Add first module to use db<commit_after>use dotenv::dotenv;
use std::ops::Deref;

use std::env;
use diesel::pg::PgConnection;
use diesel::r2d2::{self, ConnectionManager};

use rocket::http::Status;
use rocket::request::{self, FromRequest};
use rocket::{Outcome, Request, State};

pub type Pool = r2d2::Pool<ConnectionManager<PgConnection>>;

pub fn init_pool() -> Pool {
    dotenv().ok();
    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    let manager = ConnectionManager::<PgConnection>::new(database_url);
    r2d2::Pool::new(manager).expect("db pool");
}

pub struct Conn(pub r2d2::PooledConnection<ConnectionManager<PgConnection>>);

impl Deref for Conn {
    type Target = PgConnection;
    #[inline(always)]
    fn deref(&self) -> &Self::Target {
        &self.0
    }

}
impl <'a, 'r> FromRequest<'a, 'r> for Conn {
    type Error = ();
    fn from_request(request: &'a Request<'r>) -> request.:Outcome<Conn, ()> {
        let pool = request.guard::<State<Pool>>()?;
        match pool.get() {
            Ok(conn) => Outcome::Success(Conn(conn)),
            Err(_) => Outcome::Failure((Status::ServiceUnavailable, ())),
        }
    }
}

<|endoftext|>


<commit_before><commit_msg>Sync upsert example<commit_after>extern crate gauc;
extern crate env_logger;

use gauc::client::*;

fn main() {
    env_logger::init().unwrap();

    let mut client = Client::new("couchbase://korczis.com/default");

    let res = client.upsert_sync("hello_world_upsert_sync", "{{\"msg\": \"This is sync upsert!\"}}");
    println!("{:?}", res);

    let res = client.get_sync("hello_world_upsert_sync");
    println!("{:?}", res);
}
<|endoftext|>


<commit_before><commit_msg>account.setOnline method<commit_after><|endoftext|>


<commit_before><commit_msg>Add `yes` utility<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed bug with or and Daemon<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed json encoding with daemon<commit_after><|endoftext|>


<commit_before><commit_msg>practice<commit_after>fn main() {
    let number  = 2;

    println!("Tell me about {}", number);

    match number {
        1 => println!("One!"),
        2 | 3 | 5 | 7 | 11 => println!("This is a prime"),
        13...19 => println!("A teen"),
        _ => println!("Ain't special"),
    }

    let boolean = true;

    let binary = match boolean {
        false => 0,
        true => 1,
    };

    println!("{} -> {}", boolean, binary);
}
<|endoftext|>


<commit_before><commit_msg>Fix Option Error<commit_after><|endoftext|>


<commit_before><commit_msg>add simple dns lib<commit_after>extern crate libc;
use self::libc::{c_char, c_int};
use std::ffi::{CString, CStr};
use std::str::from_utf8;

#[link(name = "resolv")]
extern {
    pub fn __res_query(dname: *const c_char, class: c_int, typef: c_int,
               answer: *const u8, anslen: c_int) -> c_int;
}

#[test]
fn query() {
    let dname = CString::new("_leader._tcp.mesos").unwrap();
    let ans: *const u8 = 0 as *const u8;
    let class: c_int = 33;
    let typef: c_int = 33;
    unsafe {
        let r = __res_query(dname.as_ptr(), class, typef,
                           ans, 1);
        println!("res_query -> {:?}", r);
    }
}
<|endoftext|>