zig-std 0.1.1

Bindings to Zig `std`, with optional Rust `std` features
Documentation
const util = @import("../../util.zig");
const export_fn = util.export_fn;
const ReprCSlice = util.ReprCSlice;
const std_argon2 = @import("std").crypto.pwhash.argon2;

comptime {
	export_fn(calc_size, "zig_std_rs__crypto__pwhash__argon2__calc_size");
}

pub const Mode = enum(u8) {
	argon2d = 0,
	argon2i = 1,
	argon2id = 2,

	inline fn from_std(mode: std_argon2.Mode) @This() {
		return switch (mode) {
			.argon2d => .argon2d,
			.argon2i => .argon2i,
			.argon2id => .argon2id
		};
	}

	inline fn to_std(self: @This()) std_argon2.Mode {
		return switch (self) {
			.argon2d => .argon2d,
			.argon2i => .argon2i,
			.argon2id => .argon2id
		};
	}
};

pub const Params = extern struct {
	t: u32,
	m: u32,
	p: u32,

	secret: ReprCSlice(u8) = ReprCSlice(u8).from_slice(null),
	ad: ReprCSlice(u8) = ReprCSlice(u8).from_slice(null),

	inline fn from_std(params: std_argon2.Params) @This() {
		return .{
			.t = params.t,
			.m = params.m,
			.p = params.p,
			.secret = ReprCSlice(u8).from_slice(params.secret),
			.ad = ReprCSlice(u8).from_slice(params.ad)
		};
	}

	inline fn to_std(self: @This()) std_argon2.Params {
		return .{
			.t = self.t,
			.m = self.m,
			.p = @intCast(self.p),
			.secret = self.secret.to_slice(),
			.ad = self.ad.to_slice()
		};
	}
};

pub fn calc_size(params: Params) callconv(.c) usize {
	return std_argon2.calcSize(params.to_std());
}

comptime {
	const assert = @import("std").debug.assert;

	// smoke tests
	_ = Mode.from_std(Mode.argon2id.to_std());
	const params = Params { .t = 2, .m = 19 * 1024, .p = 1 };
	_ = Params.from_std(params.to_std());
	_ = calc_size(params);

	// size/align assertions
	assert(@sizeOf(Mode) == 1);
	assert(@alignOf(Mode) == 1);
	// 4 * size of u32 because of padding for alignment
	// 4 * size of usize because each ReprCSlice is 2 * usize
	assert(@sizeOf(Params) == (4 * @sizeOf(u32)) + (4 * @sizeOf(usize)));
	assert(@alignOf(Params) == @alignOf(usize));
}