Skip to content

Commit

Permalink
Implement HashMap parsing
Browse files Browse the repository at this point in the history
closes #9
  • Loading branch information
sam701 committed Oct 18, 2024
1 parent 9511188 commit 88e6196
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ This is a top-down LL parser that parses directly into Zig structs.
* [x] Mapping to pointers
* [x] Mapping to integer and floats with lower bit number than defined by TOML, i.e. `i16`, `f32`.
* [x] Mapping to optional fields
* [x] Mapping to HashMaps

## Example
See [`example1.zig`](./examples/example1.zig) for the complete code that parses [`example.toml`](./examples/example1.toml)
Expand Down
1 change: 1 addition & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub const Time = datetime.Time;
pub const DateTime = datetime.DateTime;
pub const Value = value.Value;
pub const ValueList = value.ValueList;
pub const HashMap = struct_mapping.HashMap;

pub const Position = parser.Position;
pub const FieldPath = []const []const u8;
Expand Down
27 changes: 27 additions & 0 deletions src/struct_mapping.zig
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ pub const Context = struct {
};

pub fn intoStruct(ctx: *Context, comptime T: type, dest: *T, table: *Table) !void {
if (std.meta.hasFn(T, "tomlIntoStruct")) {
dest.* = try T.tomlIntoStruct(ctx, table);
return;
}
switch (@typeInfo(T)) {
.@"struct" => |info| {
inline for (info.fields) |field_info| {
Expand Down Expand Up @@ -181,3 +185,26 @@ fn setValue(ctx: *Context, comptime T: type, dest: *T, value: *const Value) !voi
else => return error.NotSupportedFieldType,
}
}

pub fn HashMap(comptime T: type) type {
return struct {
map: std.StringHashMap(T),

pub fn tomlIntoStruct(ctx: *Context, table: *Table) !@This() {
var map = std.StringHashMap(T).init(ctx.alloc);
errdefer map.deinit();

var it = table.iterator();
while (it.next()) |entry| {
var value: T = undefined;
try setValue(ctx, T, &value, entry.value_ptr);

const key: []u8 = try ctx.alloc.alloc(u8, entry.key_ptr.len);
@memcpy(key, entry.key_ptr.*);
try map.put(key, value);
}

return .{ .map = map };
}
};
}
16 changes: 16 additions & 0 deletions src/tests.zig
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ test "parse into struct" {
e1: E1,
tab1: Table,
tab2: *Table,
hm: main.HashMap(Tt),
hm2: *main.HashMap(Tt),
};

var p = main.Parser(Aa).init(testing.allocator);
Expand Down Expand Up @@ -124,6 +126,20 @@ test "parse into struct" {
try testing.expectEqualSlices(u8, "str1", aa.tab1.get("b").?.table.get("val").?.string);
try testing.expectEqual(4, aa.tab2.get("a").?.table.get("val").?.integer);
try testing.expectEqualSlices(u8, "str2", aa.tab2.get("b").?.table.get("val").?.string);

try testing.expectEqual(3, aa.hm.map.get("f1").?.aa);
try testing.expectEqual(4, aa.hm.map.get("f1").?.bb);
try testing.expectEqual(5, aa.hm.map.get("f2").?.aa);
try testing.expectEqual(6, aa.hm.map.get("f2").?.bb);
try testing.expectEqual(10, aa.hm.map.get("f3").?.aa);
try testing.expectEqual(11, aa.hm.map.get("f3").?.bb);

try testing.expectEqual(3, aa.hm2.map.get("f1").?.aa);
try testing.expectEqual(4, aa.hm2.map.get("f1").?.bb);
try testing.expectEqual(5, aa.hm2.map.get("f2").?.aa);
try testing.expectEqual(6, aa.hm2.map.get("f2").?.bb);
try testing.expectEqual(10, aa.hm2.map.get("f3").?.aa);
try testing.expectEqual(11, aa.hm2.map.get("f3").?.bb);
}

test "optionals (--release=fast)" {
Expand Down
14 changes: 14 additions & 0 deletions test/doc1.toml.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,17 @@ val = "str1"
val = 4
[tab2.b]
val = "str2"

[hm]
f1 = {aa= 3, bb = 4}
f2 = {aa = 5, bb = 6}
[hm.f3]
aa = 10
bb = 11

[hm2]
f1 = {aa= 3, bb = 4}
f2 = {aa = 5, bb = 6}
[hm2.f3]
aa = 10
bb = 11

0 comments on commit 88e6196

Please sign in to comment.