#[derive(Debug)]
pub enum Json {
OBJECT {
name: String,
value: Box<Json>,
},
JSON(Vec<Json>),
ARRAY(Vec<Json>),
STRING(String),
NUMBER(f64),
BOOL(bool),
NULL,
}
impl Json {
pub fn new() -> Json {
Json::JSON(Vec::new())
}
pub fn add(&mut self, value: Json) -> &mut Json {
match self {
Json::JSON(values) => {
match value {
Json::OBJECT { name, value } => {
values.push( Json::OBJECT { name, value } );
return self;
},
Json::JSON(_) => {
panic!("A `Json::JSON` may not be added to a `Json::JSON` if it is not within a `Json::OBJECT`.");
},
Json::ARRAY(vals) => {
values.push( Json::ARRAY(vals) );
return self;
},
Json::STRING(val) => {
values.push( Json::STRING(val) );
return self;
},
Json::NUMBER(val) => {
values.push( Json::NUMBER(val) );
return self;
},
Json::BOOL(val) => {
values.push( Json::BOOL(val) );
return self;
},
Json::NULL => {
values.push( Json::NULL );
return self;
}
}
},
Json::OBJECT{ name: _, value: obj_val} => {
match obj_val.unbox_mut() {
Json::JSON(values) => {
match value {
Json::OBJECT { name, value } => {
values.push( Json::OBJECT { name, value } );
return self;
},
Json::JSON(_) => {
panic!("A `Json::JSON` may not be added to a `Json::JSON` if it is not within a `Json::OBJECT`.");
},
Json::ARRAY(vals) => {
values.push( Json::ARRAY(vals) );
return self;
},
Json::STRING(val) => {
values.push( Json::STRING(val) );
return self;
},
Json::NUMBER(val) => {
values.push( Json::NUMBER(val) );
return self;
},
Json::BOOL(val) => {
values.push( Json::BOOL(val) );
return self;
},
Json::NULL => {
values.push( Json::NULL );
return self;
}
}
},
Json::ARRAY(values) => {
match value {
Json::OBJECT { name, value } => {
values.push( Json::OBJECT { name, value } );
return self;
},
Json::JSON(vals) => {
values.push( Json::JSON(vals) );
return self;
},
Json::ARRAY(vals) => {
values.push( Json::ARRAY(vals) );
return self;
},
Json::STRING(val) => {
values.push( Json::STRING(val) );
return self;
},
Json::NUMBER(val) => {
values.push( Json::NUMBER(val) );
return self;
},
Json::BOOL(val) => {
values.push( Json::BOOL(val) );
return self;
},
Json::NULL => {
values.push( Json::NULL );
return self;
}
}
},
json => {
panic!("The function `add(`&mut self`,`name: String`,`value: Json`)` may only be called on a `Json::JSON`, `Json::ARRAY` or `Json::OBJECT` holding a `Json::JSON` or `Json::ARRAY`. It was called on: {:?}",json);
}
}
},
Json::ARRAY(values) => {
match value {
Json::OBJECT { name, value } => {
values.push( Json::OBJECT { name, value } );
return self;
},
Json::JSON(vals) => {
values.push( Json::JSON(vals) );
return self;
},
Json::ARRAY(vals) => {
values.push( Json::ARRAY(vals) );
return self;
},
Json::STRING(val) => {
values.push( Json::STRING(val) );
return self;
},
Json::NUMBER(val) => {
values.push( Json::NUMBER(val) );
return self;
},
Json::BOOL(val) => {
values.push( Json::BOOL(val) );
return self;
},
Json::NULL => {
values.push( Json::NULL );
return self;
}
}
},
json => {
panic!("The function `add(`&mut self`,`name: String`,`value: Json`)` may only be called on a `Json::JSON`, `Json::ARRAY` or `Json::OBJECT` holding a `Json::JSON` or `Json::ARRAY`. It was called on: {:?}",json);
}
}
}
pub fn get(&self,search: &str) -> Option<&Json> {
match self {
Json::JSON(values) => {
for n in 0..values.len() {
match &values[n] {
Json::OBJECT { name, value: _ } => {
match name == search {
true => {
return Some(&values[n]);
},
false => {},
}
},
_ => {}
}
}
return None;
},
Json::OBJECT { name: _, value } => {
match value.unbox() {
Json::JSON(values) => {
for n in 0..values.len() {
match &values[n] {
Json::OBJECT { name, value: _ } => {
match name == search {
true => {
return Some(&values[n]);
},
false => {},
}
},
_ => {}
}
}
return None;
},
json => {
panic!("The function `get(`&self`,`search: &str`)` may only be called on a `Json::JSON` or a `Json::OBJECT` holding a `Json::JSON`. I was called on: {:?}",json);
},
}
}
json => {
panic!("The function `get(`&self`,`search: &str`)` may only be called on a `Json::JSON`. I was called on: {:?}",json);
}
}
}
pub fn get_mut(&mut self, search: &str) -> Option<&mut Json> {
match self {
Json::JSON(values) => {
for n in 0..values.len() {
match &values[n] {
Json::OBJECT { name, value: _ } => {
match name == search {
true => {
return Some(&mut values[n]);
},
false => {},
}
},
_ => {}
}
}
return None;
},
Json::OBJECT { name: _, value } => {
match value.unbox_mut() {
Json::JSON(values) => {
for n in 0..values.len() {
match &values[n] {
Json::OBJECT { name, value: _ } => {
match name == search {
true => {
return Some(&mut values[n]);
},
false => {},
}
},
_ => {}
}
}
return None;
},
json => {
panic!("The function `get_mut(`&self`,`search: &str`)` may only be called on a `Json::JSON` or a `Json::OBJECT` holding a `Json::JSON`. I was called on: {:?}",json);
},
}
}
json => {
panic!("The function `get_mut(`&self`,`search: &str`)` may only be called on a `Json::JSON` or a `Json::OBJECT` holding a `Json::JSON`. I was called on: {:?}",json);
}
}
}
pub fn unbox(&self) -> &Json {
self
}
pub fn unbox_mut(&mut self) -> &mut Json {
self
}
pub fn print(&self) -> String {
let mut result = String::new();
match self {
Json::OBJECT { name, value } => {
result.push_str(&format!("\"{}\":{}",name,value.print()));
},
Json::JSON(values) => {
result.push('{');
for n in 0..values.len() {
result.push_str(&values[n].print());
result.push(',');
}
result.pop();
result.push('}');
},
Json::ARRAY(values) => {
result.push('[');
for n in 0..values.len() {
result.push_str(&values[n].print());
result.push(',');
}
result.pop();
result.push(']');
},
Json::STRING(val) => {
result.push_str(&format!("\"{}\"",val));
},
Json::NUMBER(val) => {
result.push_str(&format!("{}",val));
},
Json::BOOL(val) => {
match val {
true => {
result.push_str("true");
},
false => {
result.push_str("false")
},
}
},
Json::NULL => {
result.push_str("null");
},
}
result
}
pub fn parse(input: &[u8]) -> Result<Json,(usize,&'static str)> {
let mut incr: usize = 0;
match input[incr] as char {
'{' => {
return Self::parse_json(input,&mut incr);
},
'\"' => {
return Self::parse_string(input,&mut incr);
},
'[' => {
return Self::parse_array(input,&mut incr);
},
't' => {
return Self::parse_bool(input,&mut incr);
},
'f' => {
return Self::parse_bool(input,&mut incr);
},
'n' => {
return Self::parse_null(input,&mut incr);
},
'0' => {
return Self::parse_number(input,&mut incr);
},
'1' => {
return Self::parse_number(input,&mut incr);
},
'2' => {
return Self::parse_number(input,&mut incr);
},
'3' => {
return Self::parse_number(input,&mut incr);
},
'4' => {
return Self::parse_number(input,&mut incr);
},
'5' => {
return Self::parse_number(input,&mut incr);
},
'6' => {
return Self::parse_number(input,&mut incr);
},
'7' => {
return Self::parse_number(input,&mut incr);
},
'8' => {
return Self::parse_number(input,&mut incr);
},
'9' => {
return Self::parse_number(input,&mut incr);
},
_ => {
return Err( (incr,"Not a valid json format") );
}
}
}
fn parse_object(input: &[u8],incr: &mut usize,name: String) -> Result<Json,(usize,&'static str)> {
match input[*incr] as char {
':' => {
},
_ => {
return Err( (*incr,"Error parsing object.") );
}
}
*incr += 1;
match *incr < input.len() {
true => {}
false => {
return Err( (*incr,"Error parsing object.") );
}
}
match input[*incr] as char {
'{' => {
match Self::parse_json(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'[' => {
match Self::parse_array(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'\"' => {
match Self::parse_string(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
't' => {
match Self::parse_bool(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'f' => {
match Self::parse_bool(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'n' => {
match Self::parse_null(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'0' => {
match Self::parse_number(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'1' => {
match Self::parse_number(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'2' => {
match Self::parse_number(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'3' => {
match Self::parse_number(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
} ,
'4' => {
match Self::parse_number(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'5' => {
match Self::parse_number(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'6' => {
match Self::parse_number(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'7' => {
match Self::parse_number(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'8' => {
match Self::parse_number(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
'9' => {
match Self::parse_number(input,incr) {
Ok(json) => {
return Ok(
Json::OBJECT {
name,
value: Box::new( json )
}
)
},
Err(e) => {
return Err(e);
}
}
},
_ => {
return Err( (*incr,"Error parsing object.") );
}
}
}
fn parse_json(input: &[u8], incr: &mut usize) -> Result<Json,(usize,&'static str)> {
let mut result: Vec<Json> = Vec::new();
match input[*incr] as char {
'{' => {}
_ => {
return Err( (*incr,"Error parsing json.") );
}
}
*incr += 1;
match *incr < input.len() {
true => {}
false => {
return Err( (*incr,"Error parsing json.") );
}
}
loop {
match input[*incr] as char {
',' => {
*incr += 1;
},
'\"' => {
match Self::parse_string(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'[' => {
match Self::parse_array(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
't' => {
match Self::parse_bool(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'f' => {
match Self::parse_bool(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'n' => {
match Self::parse_null(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'0' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'1' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'2' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'3' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
} ,
'4' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'5' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'6' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'7' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'8' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'9' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'}' => {
*incr += 1;
return Ok( Json::JSON( result ) );
},
'{' => {
match Self::parse_json(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
_ => {
return Err( (*incr,"Error parsing json.") );
}
}
}
}
fn parse_array(input: &[u8], incr: &mut usize) -> Result<Json,(usize,&'static str)> {
let mut result: Vec<Json> = Vec::new();
match input[*incr] as char {
'[' => {}
_ => {
return Err( (*incr,"Error parsing array.") );
}
}
*incr += 1;
match *incr < input.len() {
true => {}
false => {
return Err( (*incr,"Error parsing array.") );
}
}
loop {
match input[*incr] as char {
',' => {
*incr += 1;
},
'\"' => {
match Self::parse_string(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'[' => {
match Self::parse_array(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'{' => {
match Self::parse_json(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
't' => {
match Self::parse_bool(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'f' => {
match Self::parse_bool(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'n' => {
match Self::parse_null(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'0' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'1' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'2' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'3' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
} ,
'4' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'5' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'6' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'7' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'8' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
'9' => {
match Self::parse_number(input,incr) {
Ok(json) => {
result.push( json );
},
Err(e) => {
return Err(e);
}
}
},
']' => {
*incr += 1;
return Ok( Json::ARRAY( result ) );
}
_ => {
return Err( (*incr,"Error parsing array.") );
}
}
}
}
fn parse_string(input: &[u8], incr: &mut usize) -> Result<Json,(usize,&'static str)> {
let mut result = String::new();
match input[*incr] as char {
'\"' => {}
_ => {
return Err( (*incr,"Error parsing string.") );
}
}
*incr += 1;
match *incr < input.len() {
true => {}
false => {
return Err( (*incr,"Error parsing string.") );
}
}
loop {
match input[*incr] as char {
'\"' => {
*incr += 1;
match *incr < input.len() {
true => {
match input[*incr] as char {
':' => {
return Self::parse_object(input,incr,result);
},
_ => {
return Ok( Json::STRING( result ) );
}
}
},
false => {
return Ok( Json::STRING( result ) );
}
}
},
c => {
result.push(c);
*incr += 1;
match *incr < input.len() {
true => {}
false => {
return Err( (*incr,"Error parsing string.") );
}
}
}
}
}
}
fn parse_number(input: &[u8], incr: &mut usize) -> Result<Json,(usize,&'static str)> {
let mut result = String::new();
loop {
match input[*incr] as char {
'}' => {
break;
},
']' => {
break;
},
',' => {
break;
},
c => {
result.push(c);
*incr += 1;
match *incr < input.len() {
true => {
},
false => {
match result.parse::<f64>() {
Ok(num) => {
return Ok( Json::NUMBER( num ) );
},
Err(_) => {
return Err( (*incr,"Error parsing number.") );
}
}
}
}
}
}
}
match result.parse::<f64>() {
Ok(num) => {
return Ok( Json::NUMBER( num ) );
},
Err(_) => {
return Err( (*incr,"Error parsing number.") );
}
}
}
fn parse_bool(input: &[u8], incr: &mut usize) -> Result<Json,(usize,&'static str)> {
let mut result = String::new();
loop {
match input[*incr] as char {
',' => {
break;
},
']' => {
break;
},
'}' => {
break;
},
c => {
result.push(c);
*incr += 1;
match *incr < input.len() {
true => {}
false => {
match result == "true" {
true => {
return Ok( Json::BOOL( true ) );
},
false => {}
}
match result == "false" {
true => {
return Ok( Json::BOOL( false ) );
},
false => {}
}
return Err( (*incr,"Error parsing bool.") );
}
}
}
}
}
match result == "true" {
true => {
return Ok( Json::BOOL( true ) );
},
false => {}
}
match result == "false" {
true => {
return Ok( Json::BOOL( false ) );
},
false => {}
}
return Err( (*incr,"Error parsing bool.") );
}
fn parse_null(input: &[u8], incr: &mut usize) -> Result<Json,(usize,&'static str)> {
let mut result = String::new();
loop {
match input[*incr] as char {
',' => {
break;
},
']' => {
break;
},
'}' => {
break;
},
c => {
result.push(c);
*incr += 1;
match *incr < input.len() {
true => {}
false => {
match result == "null" {
true => {
return Ok( Json::NULL );
},
false => {
return Err( (*incr,"Error parsing null.") );
}
}
}
}
}
}
}
match result == "null" {
true => {
return Ok( Json::NULL );
},
false => {
return Err( (*incr,"Error parsing null.") );
}
}
}
}
#[cfg(test)]
mod tests;