Use a macro to cut down on the if statement boilerplate
This commit is contained in:
parent
a3b16acb13
commit
695219de02
53
src/lib.rs
53
src/lib.rs
@ -69,6 +69,19 @@ pub struct JSON {
|
||||
i: usize,
|
||||
}
|
||||
|
||||
/// Cut down the if boilerplate
|
||||
///
|
||||
/// Thanks to `uwaterloodudette` on reddit
|
||||
macro_rules! try_parse {
|
||||
($( $e:expr ),* ) => {
|
||||
$(
|
||||
if let Some(v) = $e? {
|
||||
return Ok(v);
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl JSON {
|
||||
/// Private constructor
|
||||
fn new(json: &str) -> Self {
|
||||
@ -82,34 +95,22 @@ impl JSON {
|
||||
fn parse_value(&mut self) -> Result<JSONValue, ParseError> {
|
||||
self.skip_whitespace();
|
||||
|
||||
return if let Some(string) = self.parse_string()? {
|
||||
Ok(string)
|
||||
} else if let Some(number) = self.parse_number()? {
|
||||
Ok(number)
|
||||
} else if let Some(object) = self.parse_object()? {
|
||||
Ok(object)
|
||||
} else if let Some(array) = self.parse_array()? {
|
||||
Ok(array)
|
||||
} else if let Some(t) = self.parse_keyword("true", JSONValue::True)? {
|
||||
Ok(t)
|
||||
} else if let Some(f) = self.parse_keyword("false", JSONValue::False)? {
|
||||
Ok(f)
|
||||
} else if let Some(n) = self.parse_keyword("null", JSONValue::Null)? {
|
||||
Ok(n)
|
||||
} else {
|
||||
// Go through the parser methods, until you find
|
||||
// one that doesn't return a `None`
|
||||
try_parse!(
|
||||
self.parse_string(),
|
||||
self.parse_number(),
|
||||
self.parse_object(),
|
||||
self.parse_array(),
|
||||
self.parse_keyword("true", JSONValue::True),
|
||||
self.parse_keyword("false", JSONValue::False),
|
||||
self.parse_keyword("null", JSONValue::Null)
|
||||
);
|
||||
|
||||
// Every parser failed, so the syntax is probably incorrect
|
||||
Err(ParseError::UnexpectedEndOfInput(String::from(
|
||||
"Doesn't seem to be valid JSON",
|
||||
)))
|
||||
};
|
||||
|
||||
// Eagerly evaluated simpler alternative to the original option iterator chain
|
||||
// let value = self.parse_string()?
|
||||
// .or(self.parse_number()?)
|
||||
// .or(self.parse_object()?)
|
||||
// .or(self.parse_array()?)
|
||||
// .or(self.parse_keyword("true", JSONValue::True)?)
|
||||
// .or(self.parse_keyword("false", JSONValue::False)?)
|
||||
// .or(self.parse_keyword("null", JSONValue::Null)?);
|
||||
}
|
||||
|
||||
/// See if there's a `JSONValue::Object` next in the JSON
|
||||
@ -143,7 +144,7 @@ impl JSON {
|
||||
JSONValue::String(s) => s,
|
||||
_ => panic!("parse_string returned non-string value"),
|
||||
},
|
||||
None => panic!("Missing object key"),
|
||||
None => String::new(),
|
||||
};
|
||||
|
||||
self.skip_whitespace();
|
||||
|
Loading…
Reference in New Issue
Block a user