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}