Skip to content

Commit ce4f66b

Browse files
committed
0.11.11: fixes #119, fixes #136
1 parent 98dcb57 commit ce4f66b

File tree

5 files changed

+45
-15
lines changed

5 files changed

+45
-15
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "json"
3-
version = "0.11.10"
3+
version = "0.11.11"
44
authors = ["Maciej Hirsz <[email protected]>"]
55
description = "JSON implementation in Rust"
66
repository = "https://github.com/maciejhirsz/json-rust"

src/object.rs

+21-6
Original file line numberDiff line numberDiff line change
@@ -298,14 +298,19 @@ impl Object {
298298
/// to be a `&str` slice and not an owned `String`. The internals of
299299
/// `Object` will handle the heap allocation of the key if needed for
300300
/// better performance.
301+
#[inline]
301302
pub fn insert(&mut self, key: &str, value: JsonValue) {
303+
self.insert_index(key, value);
304+
}
305+
306+
pub(crate) fn insert_index(&mut self, key: &str, value: JsonValue) -> usize {
302307
let key = key.as_bytes();
303308
let hash = hash_key(key);
304309

305310
if self.store.len() == 0 {
306311
self.store.push(Node::new(value, hash, key.len()));
307312
self.store[0].key.attach(key);
308-
return;
313+
return 0;
309314
}
310315

311316
let mut node = unsafe { &mut *self.node_at_index_mut(0) };
@@ -314,28 +319,38 @@ impl Object {
314319
loop {
315320
if hash == node.key.hash && key == node.key.as_bytes() {
316321
node.value = value;
317-
return;
322+
return parent;
318323
} else if hash < node.key.hash {
319324
if node.left != 0 {
320325
parent = node.left;
321326
node = unsafe { &mut *self.node_at_index_mut(node.left) };
322327
continue;
323328
}
324-
self.store[parent].left = self.add_node(key, value, hash);
325-
return;
329+
let index = self.add_node(key, value, hash);
330+
self.store[parent].left = index;
331+
332+
return index;
326333
} else {
327334
if node.right != 0 {
328335
parent = node.right;
329336
node = unsafe { &mut *self.node_at_index_mut(node.right) };
330337
continue;
331338
}
332-
self.store[parent].right = self.add_node(key, value, hash);
333-
return;
339+
let index = self.add_node(key, value, hash);
340+
self.store[parent].right = index;
341+
342+
return index;
334343
}
335344
}
336345
}
337346

338347
#[inline]
348+
pub(crate) fn override_at(&mut self, index: usize, value: JsonValue) {
349+
self.store[index].value = value;
350+
}
351+
352+
#[inline]
353+
#[deprecated(since="0.11.11", note="Was only meant for internal use")]
339354
pub fn override_last(&mut self, value: JsonValue) {
340355
if let Some(node) = self.store.last_mut() {
341356
node.value = value;

src/parser.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -669,10 +669,10 @@ impl<'a> Parser<'a> {
669669
return self.unexpected_character()
670670
}
671671

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

675-
stack.push(StackBlock::Object(object));
675+
stack.push(StackBlock::Object(object, index));
676676

677677
ch = expect_byte_ignore_whitespace!(self);
678678

@@ -738,18 +738,18 @@ impl<'a> Parser<'a> {
738738
}
739739
},
740740

741-
Some(StackBlock::Object(mut object)) => {
742-
object.override_last(value);
741+
Some(StackBlock::Object(mut object, index)) => {
742+
object.override_at(index, value);
743743

744744
ch = expect_byte_ignore_whitespace!(self);
745745

746746
match ch {
747747
b',' => {
748748
expect!(self, b'"');
749-
object.insert(expect_string!(self), JsonValue::Null);
749+
let index = object.insert_index(expect_string!(self), JsonValue::Null);
750750
expect!(self, b':');
751751

752-
stack.push(StackBlock::Object(object));
752+
stack.push(StackBlock::Object(object, index));
753753

754754
ch = expect_byte_ignore_whitespace!(self);
755755

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

772772
enum StackBlock {
773773
Array(Vec<JsonValue>),
774-
Object(Object),
774+
Object(Object, usize),
775775
}
776776

777777
// All that hard work, and in the end it's just a single function in the API.

src/value/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,6 @@ impl JsonValue {
385385
}
386386

387387
/// Works on `JsonValue::Array` - pushes a new value to the array.
388-
#[must_use]
389388
pub fn push<T>(&mut self, value: T) -> Result<()>
390389
where T: Into<JsonValue> {
391390
match *self {

tests/parse.rs

+16
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,22 @@ fn parse_object() {
153153
});
154154
}
155155

156+
#[test]
157+
fn parse_object_duplicate_fields() {
158+
assert_eq!(parse(r#"
159+
160+
{
161+
"foo": 0,
162+
"bar": 1,
163+
"foo": 2
164+
}
165+
166+
"#).unwrap(), object!{
167+
"foo" => 2,
168+
"bar" => 1
169+
});
170+
}
171+
156172
#[test]
157173
fn parse_object_with_array(){
158174
assert_eq!(parse(r#"

0 commit comments

Comments
 (0)