FIY some of your links are without target(empty).
Hmmm, I’ve tried your alternative approach. This works on 0.16. Yeah, maybe you can get away without updateFrom* functions. Cases where you can only use updateFrom* don’t immediately come to my mind.
const std = @import("std");
const Io = std.Io;
const Config = struct {
const default_steps = 150;
steps: u32 = default_steps,
accumulator: u64 = 0,
plugins: []u8 = &.{},
tri_state: ?bool = null,
fn update(self: *Config, arena: std.mem.Allocator, other: Config) !void {
if (other.steps != default_steps) {
self.steps = other.steps;
}
if (other.tri_state) |b| self.tri_state = b;
self.accumulator += other.accumulator;
self.plugins = try arena.realloc(self.plugins, self.plugins.len + other.plugins.len);
@memcpy(self.plugins[self.plugins.len - other.plugins.len ..], other.plugins);
}
};
pub fn main(init: std.process.Init) !void {
const arena: std.mem.Allocator = init.arena.allocator();
const io = init.io;
var stdout_buffer: [1024]u8 = undefined;
var stdout_file_writer: Io.File.Writer = .init(.stdout(), io, &stdout_buffer);
const stdout_writer = &stdout_file_writer.interface;
var v = try std.zon.parse.fromSliceAlloc(
Config,
arena,
".{.accumulator=1}",
null,
.{},
);
try stdout_writer.print("{any}\n", .{v});
var other = try std.zon.parse.fromSliceAlloc(
Config,
arena,
".{.steps=12,.plugins=.{1,2},.tri_state=true}",
null,
.{},
);
try v.update(arena, other);
try stdout_writer.print("{any}\n", .{v});
other = try std.zon.parse.fromSliceAlloc(
Config,
arena,
".{.accumulator=5, .plugins=.{3,4},.tri_state=false}",
null,
.{},
);
try v.update(arena, other);
try stdout_writer.print("{any}\n", .{v});
try stdout_writer.flush(); // Don't forget to flush!
}
// outputs
// .{ .steps = 150, .accumulator = 1, .plugins = { }, .tri_state = null }
// .{ .steps = 12, .accumulator = 1, .plugins = { 1, 2 }, .tri_state = true }
// .{ .steps = 12, .accumulator = 6, .plugins = { 1, 2, 3, 4 }, .tri_state = false }