queryparse/
lib.rs

1#![allow(dead_code)]
2use std::result;
3
4#[derive(Debug)]
5enum ParseError {
6    MissingDelimiter,
7    MalformedString,
8}
9
10type ParseResult<T> = result::Result<T, ParseError>;
11
12pub struct QueryPair {
13    param: String,
14    value: String
15}
16
17pub fn parse_query(query: &str) -> Option<Vec<QueryPair>> {
18    let mut parsed: Vec<QueryPair> = Vec::new();
19    for part in query.split('&') {
20        match get_pair(&part) {
21            Ok(pair) => parsed.push(pair),
22            Err(_) => break
23        }
24    }
25    match parsed.len() {
26        0 => None,
27        _ => Some(parsed)
28    }
29}
30
31fn get_pair(raw: &str) -> ParseResult<QueryPair> {
32    let pieces: Vec<_> = raw.split('=').collect();
33    if pieces.len() < 2 {
34        Err(ParseError::MissingDelimiter)
35    } else if pieces.len() > 2 {
36        Err(ParseError::MalformedString)
37    } else {
38        Ok(QueryPair{param: String::from(pieces[0]), value: String::from(pieces[1])})
39    }
40}
41
42#[test]
43fn test_single_param() {
44    let single_param: &'static str = "test=true";
45    let parsed = parse_query(&single_param);
46    match parsed {
47        Some(p) => assert!(p.len() == 1),
48        None => panic!("failed to parse 'test=true'")
49    }
50}
51
52#[test]
53fn test_multiple_param() {
54    let multi_param: &'static str = "test1=true&test2=false";
55    let parsed = parse_query(&multi_param);
56    match parsed {
57        Some(p) => assert!(p.len() == 2),
58        None => panic!("failed to parse 'test1=true,test2=false'")
59    }
60}