Skip to content

Commit 0d1442c

Browse files
wip. more thorough tests
1 parent d1ab25b commit 0d1442c

File tree

11 files changed

+482
-156
lines changed

11 files changed

+482
-156
lines changed

out.txt

Lines changed: 3 additions & 3 deletions
Large diffs are not rendered by default.

src/get_array.nr

Lines changed: 142 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,36 +27,115 @@ impl<let NumBytes: u32, let NumPackedFields: u16, let MaxNumTokens: u16, let Max
2727
let (exists, key_index) = self.key_exists_impl(key, KeyBytes);
2828
let entry: JSONEntry = JSONEntry::from_field(self.packed_json_entries[key_index]);
2929

30+
assert(
31+
(entry.entry_type - BEGIN_ARRAY_TOKEN) * exists as Field == 0, "key does not describe an object"
32+
);
33+
34+
let mut r = self;
35+
r.layer_id = entry.parent_index;
36+
r.root_id = entry.id;
37+
r.layer_context = ARRAY_LAYER;
38+
r.layer_index_in_transcript = key_index;
39+
40+
Option { _is_some: exists, _value: r }
41+
}
42+
43+
fn get_array_unchecked<let KeyBytes: u16>(self, key: [u8; KeyBytes]) -> Self {
44+
assert(self.layer_context != ARRAY_LAYER, "cannot extract array elements via a key");
45+
46+
let key_index = self.key_exists_impl_unchecked(key, KeyBytes);
47+
let entry: JSONEntry = JSONEntry::from_field(self.packed_json_entries[key_index]);
48+
3049
assert(entry.entry_type == BEGIN_ARRAY_TOKEN, "key does not describe an object");
3150

32-
let mut result: Option<JSON<NumBytes, NumPackedFields, MaxNumTokens, MaxNumValues>> = Option::none();
33-
if (exists) {
34-
let mut r = self;
35-
r.layer_id = entry.parent_index;
36-
r.layer_context = ARRAY_LAYER;
37-
r.layer_index_in_transcript = key_index;
38-
result = Option::some(r);
39-
}
40-
result
51+
let mut r = self;
52+
r.layer_id = entry.parent_index;
53+
r.root_id = entry.id;
54+
r.layer_context = ARRAY_LAYER;
55+
r.layer_index_in_transcript = key_index;
56+
57+
r
4158
}
4259

60+
fn get_array_unchecked_var<let KeyBytes: u16>(self, key: [u8; KeyBytes], key_length: u16) -> Self {
61+
assert(self.layer_context != ARRAY_LAYER, "cannot extract array elements via a key");
62+
63+
let key_index = self.key_exists_impl_unchecked(key, key_length);
64+
let entry: JSONEntry = JSONEntry::from_field(self.packed_json_entries[key_index]);
65+
66+
assert(entry.entry_type == BEGIN_ARRAY_TOKEN, "key does not describe an object");
67+
68+
let mut r = self;
69+
r.layer_id = entry.parent_index;
70+
r.root_id = entry.id;
71+
r.layer_context = ARRAY_LAYER;
72+
r.layer_index_in_transcript = key_index;
73+
74+
r
75+
}
4376
fn get_array_var<let KeyBytes: u16>(self, key: [u8; KeyBytes], key_length: u16) -> Option<Self> {
4477
assert(self.layer_context != ARRAY_LAYER, "cannot extract array elements via a key");
4578
let (exists, key_index) = self.key_exists_impl(key, key_length);
4679
let entry: JSONEntry = JSONEntry::from_field(self.packed_json_entries[key_index]);
4780

4881
// TODO: ADD A layer_context VARIABLE INTO JSON WHICH DESCRIBES WHETHER WE ARE AN OBJECT, ARRAY OR SINGLE VALUE
49-
assert(entry.entry_type == BEGIN_ARRAY_TOKEN, "key does not describe an object");
82+
assert(
83+
(entry.entry_type - BEGIN_ARRAY_TOKEN) * exists as Field == 0, "key does not describe an object"
84+
);
5085

51-
let mut result: Option<JSON<NumBytes, NumPackedFields, MaxNumTokens, MaxNumValues>> = Option::none();
52-
if (exists) {
53-
let mut r = self;
54-
r.layer_id = entry.parent_index;
55-
r.layer_context = ARRAY_LAYER;
56-
r.layer_index_in_transcript = key_index;
57-
result = Option::some(r);
58-
}
59-
result
86+
let mut r = self;
87+
r.layer_id = entry.parent_index;
88+
r.root_id = entry.id;
89+
r.layer_context = ARRAY_LAYER;
90+
r.layer_index_in_transcript = key_index;
91+
92+
Option { _is_some: exists, _value: r }
93+
}
94+
95+
fn get_array_from_array(self, array_index: Field) -> Option<Self> {
96+
assert(self.layer_context == ARRAY_LAYER, "can only acceess array elements from array");
97+
98+
let parent_entry = JSONEntry::from_field(self.packed_json_entries[self.layer_index_in_transcript]);
99+
100+
let valid = lt_field_16_bit(array_index, parent_entry.num_children);
101+
let entry_index = (parent_entry.child_pointer + array_index) * valid as Field;
102+
103+
let entry = JSONEntry::from_field(self.packed_json_entries[entry_index]);
104+
105+
assert(
106+
(entry.entry_type - BEGIN_ARRAY_TOKEN) * valid as Field == 0, "get_object_from_array: entry exists but is not an object!"
107+
);
108+
109+
let mut r = self;
110+
r.layer_id = entry.parent_index;
111+
r.root_id = entry.id;
112+
r.layer_context = ARRAY_LAYER;
113+
r.layer_index_in_transcript = entry_index;
114+
115+
Option { _is_some: valid, _value: r }
116+
}
117+
118+
fn get_array_from_array_unchecked(self, array_index: Field) -> Self {
119+
assert(self.layer_context == ARRAY_LAYER, "can only acceess array elements from array");
120+
121+
let parent_entry = JSONEntry::from_field(self.packed_json_entries[self.layer_index_in_transcript]);
122+
123+
let valid = lt_field_16_bit(array_index, parent_entry.num_children);
124+
assert(valid, "array overflow");
125+
let entry_index = (parent_entry.child_pointer + array_index);
126+
127+
let entry = JSONEntry::from_field(self.packed_json_entries[entry_index]);
128+
129+
assert(
130+
entry.entry_type == BEGIN_ARRAY_TOKEN, "get_array_from_array_unchecked: entry exists but is not an array!"
131+
);
132+
133+
let mut r = self;
134+
r.layer_id = entry.parent_index;
135+
r.root_id = entry.id;
136+
r.layer_context = ARRAY_LAYER;
137+
r.layer_index_in_transcript = entry_index;
138+
r
60139
}
61140

62141
fn map<U, let MaxElements: u32, let MaxElementBytes: u32>(
@@ -88,10 +167,53 @@ impl<let NumBytes: u32, let NumPackedFields: u16, let MaxNumTokens: u16, let Max
88167

89168
if (valid) {
90169
r[i] = f(
91-
JSONValue { length: child_entry.json_length, value: parsed_string, value_type: child_entry.entry_type }
170+
JSONValue { value: BoundedVec{ len: child_entry.json_length as u32, storage: parsed_string }, value_type: child_entry.entry_type }
92171
);
93172
}
94173
}
95174
r
96175
}
97176
}
177+
178+
#[test]
179+
fn test_array() {
180+
let text = "{ \"foo\": [ [1,2,3], [[3,4]], [[]], [], { \"bar\": [\"b\", \"a\", \"z\" ]} ]}";
181+
182+
let mut json: JSON<_, 7, 60, 60> = JSON::parse_json(text);
183+
184+
let first = json.get_array_unchecked("foo".as_bytes());
185+
assert(first.get_length() == 5);
186+
187+
let A = first.get_array_from_array_unchecked(0);
188+
assert(A.get_length() == 3);
189+
190+
let B = first.get_array_from_array_unchecked(1);
191+
assert(B.get_length() == 1);
192+
193+
let C = first.get_array_from_array(2).unwrap();
194+
assert(C.get_length() == 1);
195+
196+
// incorrect sorting. the object comes before the array. why?
197+
//
198+
let D = first.get_array_from_array_unchecked(3);
199+
assert(D.get_length() == 0);
200+
201+
let B_A = B.get_array_from_array_unchecked(0);
202+
assert(B_A.get_length() == 2);
203+
204+
let C_A = C.get_array_from_array_unchecked(0);
205+
assert(C_A.get_length() == 0);
206+
207+
let fake = first.get_array_from_array(5);
208+
assert(fake.is_some() == false);
209+
210+
let E = first.get_object_from_array_unchecked(4);
211+
212+
let entry_maybe = JSONEntry::from_field(E.packed_json_entries[E.layer_index_in_transcript]);
213+
println(f"entry = {entry_maybe}");
214+
let child = JSONEntry::from_field(E.packed_json_entries[entry_maybe.child_pointer]);
215+
println(f"target? = {child}");
216+
println(f"{E}");
217+
let E_A = E.get_array_unchecked("bar".as_bytes());
218+
assert(E_A.get_length() == 3);
219+
}

src/get_literal.nr

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,43 @@ impl<let NumBytes: u32, let NumPackedFields: u16, let MaxNumTokens: u16, let Max
108108

109109
extract_literal_from_array(parsed_string, entry.json_length)
110110
}
111+
112+
fn get_literal_from_array(self, array_index: Field) -> Option<JSONLiteral> {
113+
assert(self.layer_context == ARRAY_LAYER, "can only acceess array elements from array");
114+
115+
let parent_entry = JSONEntry::from_field(self.packed_json_entries[self.layer_index_in_transcript]);
116+
117+
let valid = lt_field_16_bit(array_index, parent_entry.num_children);
118+
let entry_index = (parent_entry.child_pointer + array_index) * valid as Field;
119+
120+
let entry = JSONEntry::from_field(self.packed_json_entries[entry_index]);
121+
122+
assert(
123+
(entry.entry_type - LITERAL_TOKEN) * valid as Field == 0, "get_literal_from_array: entry exists but is not a literal!"
124+
);
125+
126+
let mut parsed_string: [u8; MAX_LITERAL_LENGTH_AS_STRING] = self.extract_string_entry(entry);
127+
let result = extract_literal_from_array(parsed_string, entry.json_length);
128+
129+
Option { _is_some: valid, _value: result }
130+
}
131+
132+
fn get_literal_from_array_unchecked(self, array_index: Field) -> JSONLiteral {
133+
assert(self.layer_context == ARRAY_LAYER, "can only acceess array elements from array");
134+
135+
let parent_entry = JSONEntry::from_field(self.packed_json_entries[self.layer_index_in_transcript]);
136+
137+
let valid = lt_field_16_bit(array_index, parent_entry.num_children);
138+
assert(valid, "array overflow");
139+
let entry_index = (parent_entry.child_pointer + array_index);
140+
141+
let entry = JSONEntry::from_field(self.packed_json_entries[entry_index]);
142+
143+
assert(
144+
entry.entry_type == LITERAL_TOKEN, "get_literal_from_array_unchecked: entry exists but is not a literal!"
145+
);
146+
147+
let mut parsed_string: [u8; MAX_LITERAL_LENGTH_AS_STRING] = self.extract_string_entry(entry);
148+
extract_literal_from_array(parsed_string, entry.json_length)
149+
}
111150
}

src/get_number.nr

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl<let NumBytes: u32, let NumPackedFields: u16, let MaxNumTokens: u16, let Max
6666
extract_number_from_array(parsed_string, entry.json_length)
6767
}
6868

69-
fn get_array_element_as_number(self, array_index: Field) -> Option<u64> {
69+
fn get_number_from_array(self, array_index: Field) -> Option<u64> {
7070
assert(self.layer_context == ARRAY_LAYER, "can only acceess array elements from array");
7171

7272
let parent_entry = JSONEntry::from_field(self.packed_json_entries[self.layer_index_in_transcript]);
@@ -97,9 +97,7 @@ impl<let NumBytes: u32, let NumPackedFields: u16, let MaxNumTokens: u16, let Max
9797

9898
let entry = JSONEntry::from_field(self.packed_json_entries[entry_index]);
9999

100-
assert(
101-
(entry.entry_type - NUMERIC_TOKEN) * valid as Field == 0, "get_number: entry exists but is not a number!"
102-
);
100+
assert(entry.entry_type == NUMERIC_TOKEN, "get_number: entry exists but is not a number!");
103101

104102
let mut parsed_string: [u8; U64_LENGTH_AS_BASE10_STRING] = self.extract_string_entry(entry);
105103
extract_number_from_array(parsed_string, entry.json_length)

src/get_object.nr

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ impl<let NumBytes: u32, let NumPackedFields: u16, let MaxNumTokens: u16, let Max
2626

2727
let mut r = self;
2828
r.layer_id = entry.parent_index;
29+
r.root_id = entry.id;
2930
r.layer_context = OBJECT_LAYER;
3031
r.layer_index_in_transcript = key_index;
3132
Option { _is_some: exists, _value: r }
@@ -42,6 +43,7 @@ impl<let NumBytes: u32, let NumPackedFields: u16, let MaxNumTokens: u16, let Max
4243

4344
let mut r = self;
4445
r.layer_id = entry.parent_index;
46+
r.root_id = entry.id;
4547
r.layer_context = OBJECT_LAYER;
4648
r.layer_index_in_transcript = key_index;
4749
Option { _is_some: exists, _value: r }
@@ -55,6 +57,7 @@ impl<let NumBytes: u32, let NumPackedFields: u16, let MaxNumTokens: u16, let Max
5557

5658
let mut r = self;
5759
r.layer_id = entry.parent_index;
60+
r.root_id = entry.id;
5861
r.layer_context = OBJECT_LAYER;
5962
r.layer_index_in_transcript = key_index;
6063
r
@@ -68,8 +71,97 @@ impl<let NumBytes: u32, let NumPackedFields: u16, let MaxNumTokens: u16, let Max
6871

6972
let mut r = self;
7073
r.layer_id = entry.parent_index;
74+
r.root_id = entry.id;
7175
r.layer_context = OBJECT_LAYER;
7276
r.layer_index_in_transcript = key_index;
7377
r
7478
}
79+
80+
fn get_object_from_array(self, array_index: Field) -> Option<Self> {
81+
assert(self.layer_context == ARRAY_LAYER, "can only acceess array elements from array");
82+
83+
let parent_entry = JSONEntry::from_field(self.packed_json_entries[self.layer_index_in_transcript]);
84+
85+
let valid = lt_field_16_bit(array_index, parent_entry.num_children);
86+
let entry_index = (parent_entry.child_pointer + array_index) * valid as Field;
87+
88+
let entry = JSONEntry::from_field(self.packed_json_entries[entry_index]);
89+
90+
assert(
91+
(entry.entry_type - BEGIN_OBJECT_TOKEN) * valid as Field == 0, "get_object_from_array: entry exists but is not an object!"
92+
);
93+
94+
let mut r = self;
95+
r.layer_id = entry.parent_index;
96+
r.root_id = entry.id;
97+
r.layer_context = OBJECT_LAYER;
98+
r.layer_index_in_transcript = entry_index;
99+
100+
Option { _is_some: valid, _value: r }
101+
}
102+
103+
fn get_object_from_array_unchecked(self, array_index: Field) -> Self {
104+
assert(self.layer_context == ARRAY_LAYER, "can only acceess array elements from array");
105+
106+
let parent_entry = JSONEntry::from_field(self.packed_json_entries[self.layer_index_in_transcript]);
107+
108+
let valid = lt_field_16_bit(array_index, parent_entry.num_children);
109+
assert(valid, "array overflow");
110+
let entry_index = (parent_entry.child_pointer + array_index);
111+
112+
let entry = JSONEntry::from_field(self.packed_json_entries[entry_index]);
113+
assert(
114+
entry.entry_type == BEGIN_OBJECT_TOKEN, "get_object_from_array_unchecked: entry exists but is not an object!"
115+
);
116+
117+
let mut r = self;
118+
r.layer_id = entry.parent_index;
119+
r.root_id = entry.id;
120+
r.layer_context = OBJECT_LAYER;
121+
r.layer_index_in_transcript = entry_index;
122+
r
123+
}
124+
}
125+
126+
#[test]
127+
fn test_object() {
128+
let text = "{ \"foo\": [ [1,{ \"bartholomew tony Harrison III\": { \"hello\": \"world\" }},3], [[3,4]], [[]], [], { \"bar\": [\"b\", \"a\", \"z\" ]} ]}";
129+
130+
let mut json: JSON<_, 7, 60, 60> = JSON::parse_json(text);
131+
132+
let first = json.get_array_unchecked("foo".as_bytes());
133+
assert(first.get_length() == 5);
134+
135+
let A = first.get_array_from_array_unchecked(0);
136+
assert(A.get_length() == 3);
137+
138+
let B = A.get_object_from_array_unchecked(1);
139+
let B_alt = A.get_object_from_array(1);
140+
assert(B == B_alt.unwrap());
141+
142+
let C = B.get_object_unchecked("bartholomew tony Harrison III".as_bytes());
143+
assert(JSONEntry::from_field(C.packed_json_entries[C.layer_index_in_transcript]).num_children == 1);
144+
145+
let not_real = B.get_object("bartholomew tony Harrison IV".as_bytes());
146+
assert(not_real.is_some() == false);
147+
148+
let C = B.get_object_unchecked_var("bartholomew tony Harrison III".as_bytes(), 29);
149+
assert(JSONEntry::from_field(C.packed_json_entries[C.layer_index_in_transcript]).num_children == 1);
150+
151+
let C = B.get_object_var("bartholomew tony Harrison III".as_bytes(), 28);
152+
assert(C.is_some() == false);
153+
154+
let C = B.get_object_var("bartholomew tony Harrison IIIekurfgaeoiurh".as_bytes(), 29);
155+
assert(C.is_some() == true);
156+
157+
let second = first.get_object_from_array_unchecked(4);
158+
159+
let third = second.get_array_unchecked("bar".as_bytes());
160+
161+
let E: BoundedVec<u8, 1> = third.get_string_from_array_unchecked(0);
162+
let F: BoundedVec<u8, 1> = third.get_string_from_array_unchecked(1);
163+
let G: BoundedVec<u8, 1> = third.get_string_from_array_unchecked(2);
164+
assert(E.storage == "b".as_bytes());
165+
assert(F.storage == "a".as_bytes());
166+
assert(G.storage == "z".as_bytes());
75167
}

0 commit comments

Comments
 (0)