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