allow outputting default values
All checks were successful
Generic zig build / build (push) Successful in 30s
All checks were successful
Generic zig build / build (push) Successful in 30s
This commit is contained in:
parent
a99adb0b29
commit
12b755660e
1 changed files with 41 additions and 4 deletions
45
src/srf.zig
45
src/srf.zig
|
|
@ -412,6 +412,7 @@ pub const Record = struct {
|
||||||
fields_allocated: [fields_len]bool = .{false} ** fields_len,
|
fields_allocated: [fields_len]bool = .{false} ** fields_len,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
source_value: T,
|
source_value: T,
|
||||||
|
format_options: FormatOptions,
|
||||||
cached_record: ?Record = null,
|
cached_record: ?Record = null,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
@ -419,12 +420,13 @@ pub const Record = struct {
|
||||||
|
|
||||||
pub const SourceType = T;
|
pub const SourceType = T;
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, source: T) Self {
|
pub fn init(allocator: std.mem.Allocator, source: T, options: FormatOptions) Self {
|
||||||
return .{
|
return .{
|
||||||
// SAFETY: fields_buf is set by record() and is guarded by fields_set
|
// SAFETY: fields_buf is set by record() and is guarded by fields_set
|
||||||
.fields_buf = undefined,
|
.fields_buf = undefined,
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.source_value = source,
|
.source_value = source,
|
||||||
|
.format_options = options,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -442,7 +444,7 @@ pub const Record = struct {
|
||||||
) !usize {
|
) !usize {
|
||||||
if (default_value_ptr) |d| {
|
if (default_value_ptr) |d| {
|
||||||
const default_val: *const field_type = @ptrCast(@alignCast(d));
|
const default_val: *const field_type = @ptrCast(@alignCast(d));
|
||||||
if (std.meta.eql(val, default_val.*)) return inx;
|
if (!self.format_options.emit_default_values and std.meta.eql(val, default_val.*)) return inx;
|
||||||
}
|
}
|
||||||
const value = try self.formatField(field_type, field_name, val);
|
const value = try self.formatField(field_type, field_name, val);
|
||||||
self.fields_buf[inx] = .{
|
self.fields_buf[inx] = .{
|
||||||
|
|
@ -562,7 +564,13 @@ pub const Record = struct {
|
||||||
///
|
///
|
||||||
/// Call `deinit()` to free any allocations made for custom-formatted fields.
|
/// Call `deinit()` to free any allocations made for custom-formatted fields.
|
||||||
pub fn from(comptime T: type, allocator: std.mem.Allocator, val: T) !OwnedRecord(T) {
|
pub fn from(comptime T: type, allocator: std.mem.Allocator, val: T) !OwnedRecord(T) {
|
||||||
return OwnedRecord(T).init(allocator, val);
|
return OwnedRecord(T).init(allocator, val, .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Internal function to allow an OwnedRecord to see format options necessary
|
||||||
|
/// to emit default values
|
||||||
|
fn fromWithOptions(comptime T: type, allocator: std.mem.Allocator, val: T, options: FormatOptions) !OwnedRecord(T) {
|
||||||
|
return OwnedRecord(T).init(allocator, val, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Coerce a `Record` to a Zig struct or tagged union. For each field in `T`,
|
/// Coerce a `Record` to a Zig struct or tagged union. For each field in `T`,
|
||||||
|
|
@ -1118,6 +1126,9 @@ pub const FormatOptions = struct {
|
||||||
/// and just format the record. This is useful for appending to an existing
|
/// and just format the record. This is useful for appending to an existing
|
||||||
/// srf file rather than overwriting all the data
|
/// srf file rather than overwriting all the data
|
||||||
emit_directives: bool = true,
|
emit_directives: bool = true,
|
||||||
|
|
||||||
|
/// When set to true, this will output all values, even if they are the default values
|
||||||
|
emit_default_values: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Returns a `Formatter` for writing pre-built `Record` values to a writer.
|
/// Returns a `Formatter` for writing pre-built `Record` values to a writer.
|
||||||
|
|
@ -1150,7 +1161,12 @@ pub fn FromFormatter(comptime T: type) type {
|
||||||
for (self.value) |item| {
|
for (self.value) |item| {
|
||||||
if (!first and self.options.long_format) try writer.writeByte('\n');
|
if (!first and self.options.long_format) try writer.writeByte('\n');
|
||||||
first = false;
|
first = false;
|
||||||
var owned_record = Record.from(T, self.allocator, item) catch
|
var owned_record = Record.fromWithOptions(
|
||||||
|
T,
|
||||||
|
self.allocator,
|
||||||
|
item,
|
||||||
|
self.options,
|
||||||
|
) catch
|
||||||
return std.Io.Writer.Error.WriteFailed;
|
return std.Io.Writer.Error.WriteFailed;
|
||||||
defer owned_record.deinit();
|
defer owned_record.deinit();
|
||||||
const record = owned_record.record() catch return std.Io.Writer.Error.WriteFailed;
|
const record = owned_record.record() catch return std.Io.Writer.Error.WriteFailed;
|
||||||
|
|
@ -2038,6 +2054,27 @@ test "fmtFrom commas" {
|
||||||
\\
|
\\
|
||||||
, result);
|
, result);
|
||||||
}
|
}
|
||||||
|
test "fmtFrom outputs defaults with option" {
|
||||||
|
// Example: serialize typed Zig values directly to SRF format.
|
||||||
|
const Data = struct {
|
||||||
|
name: []const u8 = "bob",
|
||||||
|
age: u8,
|
||||||
|
};
|
||||||
|
const values: []const Data = &.{
|
||||||
|
.{ .age = 30 },
|
||||||
|
};
|
||||||
|
var buf: [4096]u8 = undefined;
|
||||||
|
const result = try std.fmt.bufPrint(
|
||||||
|
&buf,
|
||||||
|
"{f}",
|
||||||
|
.{fmtFrom(Data, std.testing.allocator, values, .{ .emit_default_values = true })},
|
||||||
|
);
|
||||||
|
try std.testing.expectEqualStrings(
|
||||||
|
\\#!srfv1
|
||||||
|
\\name::bob,age:num:30
|
||||||
|
\\
|
||||||
|
, result);
|
||||||
|
}
|
||||||
test "parse with diagnostics" {
|
test "parse with diagnostics" {
|
||||||
// Example: batch parsing collects all records and fields into slices.
|
// Example: batch parsing collects all records and fields into slices.
|
||||||
// Prefer `iterator` for streaming; use `parse` when random access to
|
// Prefer `iterator` for streaming; use `parse` when random access to
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue