zig-std 0.1.0

Bindings to Zig `std`, with optional Rust `std` features
const std = @import("std");

pub fn export_fn(comptime f: *const anyopaque, comptime name: []const u8) void {
	comptime @export(f, .{
		.name = name,
		.linkage = .strong
	});
}

pub fn ReprCSlice(comptime T: type) type {
	return extern struct {
		ptr: ?[*]T,
		len: usize,

		pub inline fn from_slice(slice: ?[]const T) @This() {
			if (slice) |s| {
				return .{ .ptr = @constCast(s.ptr), .len = s.len };
			} else {
				return .{ .ptr = null, .len = 0 };
			}
		}

		pub inline fn from_ptr_len(ptr: ?[*]const T, len: usize) @This() {
			if (ptr) |p| {
				return @This().from_slice(p[0..len]);
			} else {
				return @This().from_slice(null);
			}
		}

		pub inline fn to_slice(self: @This()) ?[]T {
			if (self.ptr) |ptr| {
				return ptr[0..self.len];
			} else {
				return null;
			}
		}
	};
}

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

	// smoke tests
	_ = ReprCSlice(u8).from_slice("awawawawawwawa").to_slice();

	// size/align assertions
	assert(@sizeOf(ReprCSlice(u8)) == 2 * @sizeOf(usize));
	assert(@alignOf(ReprCSlice(u8)) == @alignOf(usize));
	assert(@sizeOf(ReprCSlice(u128)) == 2 * @sizeOf(usize));
	assert(@alignOf(ReprCSlice(u128)) == @alignOf(usize));
}