Pybites Logo Rust Platform

Mini Parser

Level: intro (score: 1)

🚀 These intro exercises are prep for our Rust Intro Cohort Program.

🎯 Mini Parser Challenge: Parse a Primitive

You’ll parse a single JSON‑style primitive from a string:

  • true, false, null
  • integer (base‑10, optional leading + or -, at least one digit)

Ignore leading/trailing ASCII whitespace. Input must contain exactly one primitive (no extra trailing chars after trimming).


Your task

Define:

#[derive(Debug, PartialEq, Eq)]
pub enum JsonValue {
    Bool(bool),
    Null,
    Number(i64),
}

#[derive(Debug, PartialEq, Eq)]
pub enum ParseError {
    Empty,
    Invalid,
    Overflow,
}
 

Implement:

pub fn parse_primitive(input: &str) -> Result<JsonValue, ParseError>
 

Rules:

  • Trim ASCII whitespace first; if empty → Err(ParseError::Empty)
  • Accept exactly "true", "false", "null"
  • Else parse an integer with optional +/- prefix; on parse failure → Invalid
  • If the integer doesn’t fit in i64Overflow
  • Reject any extra non‑whitespace after the token (e.g. "123abc") → Invalid

💡 Hints

  • Use trim() to strip ws; then decide which branch to take.
  • For integers, manually scan the sign and digits; don’t accept _ or empty digits.
  • Use i128 for accumulation and check bounds against i64::MIN..=i64::MAX before casting.

Example tests:

use JsonValue::*; use ParseError::*;

assert_eq!(parse_primitive("true"), Ok(Bool(true)));
assert_eq!(parse_primitive(" false "), Ok(Bool(false)));
assert_eq!(parse_primitive("null"), Ok(Null));

assert_eq!(parse_primitive("42"), Ok(Number(42)));
assert_eq!(parse_primitive("-7"), Ok(Number(-7)));
assert_eq!(parse_primitive("+9"), Ok(Number(9)));

assert_eq!(parse_primitive(""), Err(Empty));
assert_eq!(parse_primitive("  "), Err(Empty));
assert_eq!(parse_primitive("12x"), Err(Invalid));