Skip to content

Commit

Permalink
0.11.11: fixes #119, fixes #136
Browse files Browse the repository at this point in the history
  • Loading branch information
maciejhirsz committed Nov 10, 2017
1 parent 98dcb57 commit ce4f66b
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "json"
version = "0.11.10"
version = "0.11.11"
authors = ["Maciej Hirsz <maciej.hirsz@gmail.com>"]
description = "JSON implementation in Rust"
repository = "https://github.com/maciejhirsz/json-rust"
Expand Down
27 changes: 21 additions & 6 deletions src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,14 +298,19 @@ impl Object {
/// to be a `&str` slice and not an owned `String`. The internals of
/// `Object` will handle the heap allocation of the key if needed for
/// better performance.
#[inline]
pub fn insert(&mut self, key: &str, value: JsonValue) {
self.insert_index(key, value);
}

pub(crate) fn insert_index(&mut self, key: &str, value: JsonValue) -> usize {
let key = key.as_bytes();
let hash = hash_key(key);

if self.store.len() == 0 {
self.store.push(Node::new(value, hash, key.len()));
self.store[0].key.attach(key);
return;
return 0;
}

let mut node = unsafe { &mut *self.node_at_index_mut(0) };
Expand All @@ -314,28 +319,38 @@ impl Object {
loop {
if hash == node.key.hash && key == node.key.as_bytes() {
node.value = value;
return;
return parent;
} else if hash < node.key.hash {
if node.left != 0 {
parent = node.left;
node = unsafe { &mut *self.node_at_index_mut(node.left) };
continue;
}
self.store[parent].left = self.add_node(key, value, hash);
return;
let index = self.add_node(key, value, hash);
self.store[parent].left = index;

return index;
} else {
if node.right != 0 {
parent = node.right;
node = unsafe { &mut *self.node_at_index_mut(node.right) };
continue;
}
self.store[parent].right = self.add_node(key, value, hash);
return;
let index = self.add_node(key, value, hash);
self.store[parent].right = index;

return index;
}
}
}

#[inline]
pub(crate) fn override_at(&mut self, index: usize, value: JsonValue) {
self.store[index].value = value;
}

#[inline]
#[deprecated(since="0.11.11", note="Was only meant for internal use")]
pub fn override_last(&mut self, value: JsonValue) {
if let Some(node) = self.store.last_mut() {
node.value = value;
Expand Down
14 changes: 7 additions & 7 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,10 +669,10 @@ impl<'a> Parser<'a> {
return self.unexpected_character()
}

object.insert(expect_string!(self), JsonValue::Null);
let index = object.insert_index(expect_string!(self), JsonValue::Null);
expect!(self, b':');

stack.push(StackBlock::Object(object));
stack.push(StackBlock::Object(object, index));

ch = expect_byte_ignore_whitespace!(self);

Expand Down Expand Up @@ -738,18 +738,18 @@ impl<'a> Parser<'a> {
}
},

Some(StackBlock::Object(mut object)) => {
object.override_last(value);
Some(StackBlock::Object(mut object, index)) => {
object.override_at(index, value);

ch = expect_byte_ignore_whitespace!(self);

match ch {
b',' => {
expect!(self, b'"');
object.insert(expect_string!(self), JsonValue::Null);
let index = object.insert_index(expect_string!(self), JsonValue::Null);
expect!(self, b':');

stack.push(StackBlock::Object(object));
stack.push(StackBlock::Object(object, index));

ch = expect_byte_ignore_whitespace!(self);

Expand All @@ -771,7 +771,7 @@ impl<'a> Parser<'a> {

enum StackBlock {
Array(Vec<JsonValue>),
Object(Object),
Object(Object, usize),
}

// All that hard work, and in the end it's just a single function in the API.
Expand Down
1 change: 0 additions & 1 deletion src/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ impl JsonValue {
}

/// Works on `JsonValue::Array` - pushes a new value to the array.
#[must_use]
pub fn push<T>(&mut self, value: T) -> Result<()>
where T: Into<JsonValue> {
match *self {
Expand Down
16 changes: 16 additions & 0 deletions tests/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,22 @@ fn parse_object() {
});
}

#[test]
fn parse_object_duplicate_fields() {
assert_eq!(parse(r#"
{
"foo": 0,
"bar": 1,
"foo": 2
}
"#).unwrap(), object!{
"foo" => 2,
"bar" => 1
});
}

#[test]
fn parse_object_with_array(){
assert_eq!(parse(r#"
Expand Down

0 comments on commit ce4f66b

Please sign in to comment.