Skip to content

Commit

Permalink
Merge aeac82a into 2c53203
Browse files Browse the repository at this point in the history
  • Loading branch information
rspencer01 committed Jul 12, 2023
2 parents 2c53203 + aeac82a commit ab3d515
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 2 deletions.
8 changes: 7 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub enum JSONParsingError {
CannotParseObject,
/// Attempt to parse an object that is not a string as an string
CannotParseString,
/// Attempt to parse an object that is not a boolean as a boolean
CannotParseBoolean,
/// The key is not present in the object
KeyNotFound,
/// There was an unexpected token in the input stream
Expand Down Expand Up @@ -52,6 +54,9 @@ impl core::fmt::Display for JSONParsingError {
Self::CannotParseString => {
write!(f, "error parsing string")
}
Self::CannotParseBoolean => {
write!(f, "error parsing boolean")
}
Self::CannotParseObject => {
write!(f, "error parsing object")
}
Expand Down Expand Up @@ -83,13 +88,14 @@ mod test {
messages.insert(JSONParsingError::CannotParseInteger.to_string());
messages.insert(JSONParsingError::CannotParseObject.to_string());
messages.insert(JSONParsingError::CannotParseString.to_string());
messages.insert(JSONParsingError::CannotParseBoolean.to_string());
messages.insert(JSONParsingError::KeyNotFound.to_string());
messages.insert(JSONParsingError::UnexpectedToken.to_string());
messages.insert(JSONParsingError::EndOfStream.to_string());
messages.insert(JSONParsingError::TooShortEscapeSequence.to_string());
messages.insert(JSONParsingError::InvalidUnicodeEscapeSequence.to_string());
messages.insert(JSONParsingError::InvalidEscapeSequence('q').to_string());
messages.insert(JSONParsingError::InvalidEscapeSequence('v').to_string());
assert_eq!(messages.len(), 12);
assert_eq!(messages.len(), 13);
}
}
75 changes: 74 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

#![doc = include_str!("../README.md")]
#![no_std]

mod error;
pub use error::JSONParsingError;
Expand Down Expand Up @@ -121,6 +120,8 @@ impl<'a> JSONValue<'a> {
Ok(value)
}

/// Parse a payload and return the JSONValue appearing as its prefix, along with the length of
/// that prefix
fn parse_with_len(contents: &'a str) -> Result<(JSONValue, usize), JSONParsingError> {
let (contents, whitespace_trimmed) = trim_start(contents);
let (value_type, value_len) = match contents.chars().next() {
Expand Down Expand Up @@ -247,6 +248,50 @@ impl<'a> JSONValue<'a> {
))
}

/// Checks if the [`JSONValue`] is null
///
/// If the value is malformed, returns false.
///
/// ### Example
/// ```
/// # use microjson::{JSONValue, JSONParsingError};
/// let value = JSONValue::load("null");
/// assert_eq!(value.is_null(), true);
///
/// let value = JSONValue::load("1293");
/// assert_eq!(value.is_null(), false);
/// ```
pub fn is_null(&self) -> bool {
self.contents.trim_end() == "null"
}

/// Reads the [`JSONValue`] as a boolean
///
/// If the type is not a [`JSONValueType::Boolean`], returns an `Err`.
///
/// ### Example
/// ```
/// # use microjson::{JSONValue, JSONParsingError};
/// let value = JSONValue::load("true");
/// assert_eq!(value.read_boolean(), Ok(true));
///
/// let value = JSONValue::load("f");
/// assert_eq!(value.read_boolean(), Err(JSONParsingError::CannotParseBoolean));
/// ```
pub fn read_boolean(&self) -> Result<bool, JSONParsingError> {
if self.value_type != JSONValueType::Bool {
return Err(JSONParsingError::CannotParseBoolean);
}
let contents = self.contents.trim_end();
if contents == "true" {
Ok(true)
} else if contents == "false" {
Ok(false)
} else {
Err(JSONParsingError::CannotParseBoolean)
}
}

/// Reads the [`JSONValue`] as an integer
///
/// If the type is not a [`JSONValueType::Number`], returns an `Err`.
Expand Down Expand Up @@ -516,6 +561,23 @@ mod test {
use super::*;
extern crate std;

#[test]
fn is_null() {
assert_eq!(JSONValue::load("null").is_null(), true);
assert_eq!(JSONValue::load("1234").is_null(), false);
assert_eq!(JSONValue::load("<!or").is_null(), false);
}

#[test]
fn boolean() {
assert_eq!(JSONValue::load("true").read_boolean(), Ok(true));
assert_eq!(JSONValue::load("false").read_boolean(), Ok(false));
assert_eq!(
JSONValue::load("foo").read_boolean(),
Err(JSONParsingError::CannotParseBoolean)
);
}

#[test]
fn integer() {
let (value, value_len) = JSONValue::parse_with_len("42").unwrap();
Expand Down Expand Up @@ -733,4 +795,15 @@ mod test {
assert_eq!(item.unwrap().0, *expected_key);
}
}

#[test]
fn empty_object() {
let json_value = JSONValue::load("{}");
assert_eq!(json_value.value_type, JSONValueType::Object);
assert_eq!(
json_value.get_key_value("foo").err(),
Some(JSONParsingError::KeyNotFound)
);
assert_eq!(json_value.iter_object().unwrap().count(), 0);
}
}

0 comments on commit ab3d515

Please sign in to comment.