commit ae008b316b879f4cf0332071cd8d8c8c5679d8dd
parent ed1689dfbef1b30ab1f4f59083ab1bd1dffa9b0a
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 9 May 2022 15:44:26 +0200
encoding::json: fix tests
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
2 files changed, 29 insertions(+), 27 deletions(-)
diff --git a/encoding/json/+test/value.ha b/encoding/json/+test/value.ha
@@ -1,14 +1,15 @@
@test fn object() void = {
let obj = newobject();
- defer finish(&obj);
+ defer finish(obj);
set(&obj, "hello", "world");
set(&obj, "foo", "bar");
set(&obj, "the answer", 42.0);
- assert(get(&obj, "hello") as str == "world");
- assert(get(&obj, "foo") as str == "foo");
- assert(get(&obj, "the answer") as str == 42.0);
+ // XXX: Match overhaul?
+ assert(*(get(&obj, "hello") as *value) as str == "world");
+ assert(*(get(&obj, "foo") as *value) as str == "bar");
+ assert(*(get(&obj, "the answer") as *value) as f64 == 42.0);
assert(get(&obj, "nonexistent") is void);
del(&obj, "hello");
diff --git a/encoding/json/value.ha b/encoding/json/value.ha
@@ -1,11 +1,13 @@
use hash::fnv;
use strings;
+use fmt; // XXX TEMP
+use types;
// TODO: Resize table as appropriate
-def DEFAULT_OBJECT_BUCKETS: size = 32;
+def OBJECT_BUCKETS: size = 32;
export type object = struct {
- buckets: [][](str, value),
+ buckets: [OBJECT_BUCKETS][](str, value),
};
// A JSON value.
@@ -14,9 +16,7 @@ export type value = (f64 | str | bool | _null | []value | object);
// Initializes a new (empty) JSON object. Call [[finish]] to free associated
// resources when you're done using it.
export fn newobject() object = {
- return object {
- buckets = alloc([[]...], DEFAULT_OBJECT_BUCKETS),
- };
+ return object { ... };
};
// Gets a value from a JSON object. The return value is borrowed from the
@@ -32,18 +32,17 @@ export fn get(obj: *object, key: str) (*value | void) = {
};
// Sets a value in a JSON object. Assumes ownership over the provided value.
-export fn set(obj: *object, key: str, val: const *value) void = {
- const val = dup(val);
+export fn set(obj: *object, key: str, val: value) void = {
const hash = fnv::string64(key): size;
const bucket = &obj.buckets[hash % len(obj.buckets)];
for (let i = 0z; i < len(bucket); i += 1) {
if (bucket[i].0 == key) {
- finish(&bucket[i].1);
- bucket[i].1 = val;
+ finish(bucket[i].1);
+ bucket[i].1 = dup(val);
return;
};
};
- append(bucket, (strings::dup(key), val));
+ append(bucket, (strings::dup(key), dup(val)));
};
// Deletes a value from a JSON object.
@@ -53,7 +52,7 @@ export fn del(obj: *object, key: str) void = {
for (let i = 0z; i < len(bucket); i += 1) {
if (bucket[i].0 == key) {
free(bucket[i].0);
- finish(&bucket[i].1);
+ finish(bucket[i].1);
delete(bucket[i]);
break;
};
@@ -62,40 +61,42 @@ export fn del(obj: *object, key: str) void = {
// Duplicates a JSON value. The caller must pass the return value to [[finish]]
// to free associated resources when they're done using it.
-export fn dup(val: *value) value = {
- // XXX: Match overhaul
- match (*val) {
+export fn dup(val: value) value = {
+ match (val) {
case let s: str =>
return strings::dup(s);
case let v: []value =>
let new: []value = alloc([], len(v));
for (let i = 0z; i < len(v); i += 1) {
- append(new, dup(&v[i]));
+ append(new, dup(v[i]));
};
return new;
case let o: object =>
abort(); // TODO: Implement me after iter
+ case =>
+ return val;
};
};
// Frees state associated with a JSON value.
-export fn finish(val: *value) void = {
- // XXX: Match overhaul
- match (*val) {
+export fn finish(val: value) void = {
+ match (val) {
case let s: str =>
free(s);
case let v: []value =>
for (let i = 0z; i < len(v); i += 1) {
- finish(&v[i]);
+ finish(v[i]);
};
free(v);
case let o: object =>
for (let i = 0z; i < len(o.buckets); i += 1) {
- for (let j = 0z; j < len(o.buckets[i]); j += 1) {
- free(&o.buckets[i][j].0);
- finish(&o.buckets[i][j].1);
+ const bucket = &o.buckets[i];
+ for (let j = 0z; j < len(bucket); j += 1) {
+ free(bucket[j].0);
+ finish(bucket[j].1);
};
- free(o.buckets[i]);
+ // TODO: https://todo.sr.ht/~sircmpwn/hare/690
+ //free(bucket);
};
case => void;
};