Skip to content

Commit

Permalink
Errors when spaces are present before/after bool values in the yaml f…
Browse files Browse the repository at this point in the history
…iles. (#19)
  • Loading branch information
BitlyTwiser authored Sep 15, 2024
1 parent 55f90f5 commit ff146e2
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 4 deletions.
9 changes: 9 additions & 0 deletions resources/multiple_elements.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
elements:
- name: Example Name
bool_val: true
int_val: 0
float_val: 3.14
- name: Example Name 2
bool_val: false
int_val: 120
float_val: 56.123
14 changes: 14 additions & 0 deletions resources/yaml-test-suite/98YD-mixed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
elemennts:
- name: Spec Example 5.5. Comment Indicator
from: http://www.yaml.org/spec/1.2/spec.html#id2773032
tags: spec comment empty
yaml: |
# Comment only.
tree: |
+STR
-STR
json: ""
dump: ""
bool_val: true
bool_val_b2: false
bool_val_with_spaces: true
2 changes: 1 addition & 1 deletion resources/yaml-test-suite/98YD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ elemennts:
+STR
-STR
json: ""
dump: ""
dump: ""
10 changes: 7 additions & 3 deletions src/root.zig
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ pub fn Ymlz(comptime Destination: type) type {

fn parseStringExpression(self: *Self, raw_line: []const u8, depth: usize, is_multiline: bool) ![]const u8 {
const expression = try self.parseSimpleExpression(raw_line, depth, is_multiline);
const value = self.getExpressionValue(expression);
const value = self.getExpressionValueWithTrim(expression);

if (value.len == 0) return value;

Expand Down Expand Up @@ -417,6 +417,10 @@ pub fn Ymlz(comptime Destination: type) type {
return str;
}

fn getExpressionValueWithTrim(self: *Self, expression: Expression) []const u8 {
return std.mem.trim(u8, self.getExpressionValue(expression), " ");
}

fn getExpressionValue(self: *Self, expression: Expression) []const u8 {
_ = self;

Expand All @@ -429,7 +433,7 @@ pub fn Ymlz(comptime Destination: type) type {

fn parseBooleanExpression(self: *Self, raw_line: []const u8, depth: usize) !bool {
const expression = try self.parseSimpleExpression(raw_line, depth, false);
const value = self.getExpressionValue(expression);
const value = self.getExpressionValueWithTrim(expression);

const isBooleanTrue = std.mem.eql(u8, value, "True") or std.mem.eql(u8, value, "true") or std.mem.eql(u8, value, "On") or std.mem.eql(u8, value, "on");

Expand All @@ -448,7 +452,7 @@ pub fn Ymlz(comptime Destination: type) type {

fn parseNumericExpression(self: *Self, comptime T: type, raw_line: []const u8, depth: usize) !T {
const expression = try self.parseSimpleExpression(raw_line, depth, false);
const value = self.getExpressionValue(expression);
const value = self.getExpressionValueWithTrim(expression);

switch (@typeInfo(T)) {
.Int => {
Expand Down
82 changes: 82 additions & 0 deletions src/tests.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,88 @@ const expect = std.testing.expect;

const Ymlz = @import("root.zig").Ymlz;

test "Multiple elements in yaml file" {
const MultiElement = struct {
name: []const u8,
bool_val: bool,
int_val: u8,
float_val: f64,
};

const Elements = struct { elements: []MultiElement };

const yml_file_location = try std.fs.cwd().realpathAlloc(
std.testing.allocator,
"./resources/multiple_elements.yml",
);
defer std.testing.allocator.free(yml_file_location);

var ymlz = try Ymlz(Elements).init(std.testing.allocator);
const result = try ymlz.loadFile(yml_file_location);
defer ymlz.deinit(result);

// Ensure both elements are parsed as expected and we have 2
try expect(result.elements.len == 2);

// Test 1st element
try expect(result.elements[0].bool_val == true);
try expect(std.mem.eql(u8, result.elements[0].name, "Example Name"));

// Ensure 1st element does *not* have spaces (A space is manually entered into the yaml file)
try expect(!std.mem.eql(u8, result.elements[0].name, "Example Name "));

// Test 2nd element
try expect(result.elements[1].bool_val == false);
try expect(std.mem.eql(u8, result.elements[1].name, "Example Name 2"));

// Test Ints
try expect(result.elements[0].int_val == 0);
try expect(result.elements[1].int_val == 120);

// Test floats
try expect(result.elements[0].float_val == 3.14);
try expect(result.elements[1].float_val == 56.123);
}

test "98YD with bools" {
const Element = struct {
name: []const u8,
from: []const u8,
tags: []const u8,
yaml: []const u8,
tree: []const u8,
json: []const u8,
dump: []const u8,
bool_val: bool,
bool_val_2: bool,
bool_val_with_spaces: bool,
};

const Experiment = struct {
elements: []Element,
};

const yml_file_location = try std.fs.cwd().realpathAlloc(
std.testing.allocator,
"./resources/yaml-test-suite/98YD-mixed.yml",
);
defer std.testing.allocator.free(yml_file_location);

var ymlz = try Ymlz(Experiment).init(std.testing.allocator);
const result = try ymlz.loadFile(yml_file_location);
defer ymlz.deinit(result);

const element = result.elements[0];

// Test booleans
try expect(element.bool_val == true);
try expect(element.bool_val_2 == false);
try expect(element.bool_val_with_spaces == true);

try expect(std.mem.eql(u8, element.name, "Spec Example 5.5. Comment Indicator"));
try expect(element.dump.len == 0);
}

test "98YD" {
const Element = struct {
name: []const u8,
Expand Down

0 comments on commit ff146e2

Please sign in to comment.