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,
|
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 {
|
impl JSON {
|
||||||
/// Private constructor
|
/// Private constructor
|
||||||
fn new(json: &str) -> Self {
|
fn new(json: &str) -> Self {
|
||||||
@ -82,34 +95,22 @@ impl JSON {
|
|||||||
fn parse_value(&mut self) -> Result<JSONValue, ParseError> {
|
fn parse_value(&mut self) -> Result<JSONValue, ParseError> {
|
||||||
self.skip_whitespace();
|
self.skip_whitespace();
|
||||||
|
|
||||||
return if let Some(string) = self.parse_string()? {
|
// Go through the parser methods, until you find
|
||||||
Ok(string)
|
// one that doesn't return a `None`
|
||||||
} else if let Some(number) = self.parse_number()? {
|
try_parse!(
|
||||||
Ok(number)
|
self.parse_string(),
|
||||||
} else if let Some(object) = self.parse_object()? {
|
self.parse_number(),
|
||||||
Ok(object)
|
self.parse_object(),
|
||||||
} else if let Some(array) = self.parse_array()? {
|
self.parse_array(),
|
||||||
Ok(array)
|
self.parse_keyword("true", JSONValue::True),
|
||||||
} else if let Some(t) = self.parse_keyword("true", JSONValue::True)? {
|
self.parse_keyword("false", JSONValue::False),
|
||||||
Ok(t)
|
self.parse_keyword("null", JSONValue::Null)
|
||||||
} else if let Some(f) = self.parse_keyword("false", JSONValue::False)? {
|
);
|
||||||
Ok(f)
|
|
||||||
} else if let Some(n) = self.parse_keyword("null", JSONValue::Null)? {
|
// Every parser failed, so the syntax is probably incorrect
|
||||||
Ok(n)
|
|
||||||
} else {
|
|
||||||
Err(ParseError::UnexpectedEndOfInput(String::from(
|
Err(ParseError::UnexpectedEndOfInput(String::from(
|
||||||
"Doesn't seem to be valid JSON",
|
"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
|
/// See if there's a `JSONValue::Object` next in the JSON
|
||||||
@ -143,7 +144,7 @@ impl JSON {
|
|||||||
JSONValue::String(s) => s,
|
JSONValue::String(s) => s,
|
||||||
_ => panic!("parse_string returned non-string value"),
|
_ => panic!("parse_string returned non-string value"),
|
||||||
},
|
},
|
||||||
None => panic!("Missing object key"),
|
None => String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.skip_whitespace();
|
self.skip_whitespace();
|
||||||
|
Loading…
Reference in New Issue
Block a user