tiny.closure.schema.value
Defined in schema.
API (21)
Actions
Public operations.
Digest.eqlDigest.fromHexDigest.hexDigest.isKnownDigest.zeroFixedTextProfileRef.absentProfileRef.knownProfileSet.known
Types and contracts
Public types and contracts.
Values and defaults
Public values and defaults.
Source
Source: lib/closure/src/schema/root.zig:3
zig
pub const value = @import("value.zig");Source: lib/closure/src/schema/value.zig
zig
const std = @import("std");pub const name_bytes_max: usize = 64;pub const descriptor_bytes_max: usize = 192;pub const digest_bytes: usize = 32;pub const digest_hex_bytes: usize = digest_bytes * 2;pub const TextError = error{ EmptyText, TextTooLong, InvalidText,};pub const DigestParseError = error{ InvalidDigestLength, InvalidDigestByte,};pub const Name = FixedText(name_bytes_max);pub const Descriptor = FixedText(descriptor_bytes_max);pub fn FixedText(comptime bytes_max: usize) type { return extern struct { len: u16, bytes: [bytes_max]u8, const Self = @This(); pub const Error: type = TextError; pub fn init(input: []const u8) Error!Self { if (input.len == 0) return error.EmptyText; if (input.len > bytes_max) return error.TextTooLong; var value = Self{ .len = @intCast(input.len), .bytes = @splat(0), }; for (input, 0..) |byte, index| { if (byte < 0x20 or byte == 0x7f) { return error.InvalidText; } value.bytes[index] = byte; } return value; } pub fn empty() Self { return .{ .len = 0, .bytes = @splat(0), }; } pub fn slice(self: *const Self) []const u8 { return self.bytes[0..self.len]; } pub fn isEmpty(self: *const Self) bool { return self.len == 0; } pub fn eql(self: *const Self, other: *const Self) bool { return std.mem.eql(u8, self.slice(), other.slice()); } };}pub const Digest = extern struct { bytes: [digest_bytes]u8, pub const ParseError: type = DigestParseError; pub fn zero() Digest { return .{ .bytes = @splat(0) }; } pub fn fromHex(input: []const u8) ParseError!Digest { if (input.len != digest_hex_bytes) { return error.InvalidDigestLength; } var output = Digest.zero(); for (0..digest_bytes) |index| { const high = try nibble(input[index * 2]); const low = try nibble(input[index * 2 + 1]); output.bytes[index] = (high << 4) | low; } return output; } pub fn isKnown(self: *const Digest) bool { for (self.bytes) |byte| { if (byte != 0) return true; } return false; } pub fn eql(self: *const Digest, other: *const Digest) bool { return std.mem.eql(u8, &self.bytes, &other.bytes); } pub fn hex(self: *const Digest) [digest_hex_bytes]u8 { return std.fmt.bytesToHex(self.bytes, .lower); }};pub const ProfileRef = extern struct { required: bool, id: Name, source: Name, body_sha256: Digest, pub fn known(self: *const ProfileRef) bool { if (!self.required) return true; return !self.id.isEmpty() and !self.source.isEmpty() and self.body_sha256.isKnown(); } pub fn absent() ProfileRef { return .{ .required = false, .id = Name.empty(), .source = Name.empty(), .body_sha256 = Digest.zero(), }; }};pub const ProfileSet = extern struct { executable: ProfileRef, service_trust: ProfileRef, model_origin: ProfileRef, bootstrap: ProfileRef, pub fn known(self: *const ProfileSet) bool { return self.executable.known() and self.service_trust.known() and self.model_origin.known() and self.bootstrap.known(); }};fn nibble(byte: u8) Digest.ParseError!u8 { if (byte >= '0' and byte <= '9') return byte - '0'; if (byte >= 'a' and byte <= 'f') return byte - 'a' + 10; return error.InvalidDigestByte;}test "fixed text rejects empty oversized and control input" { try std.testing.expectError(error.EmptyText, Name.init("")); var oversized: [name_bytes_max + 1]u8 = @splat('a'); try std.testing.expectError( error.TextTooLong, Name.init(&oversized), ); try std.testing.expectError( error.InvalidText, Name.init("bad\nname"), );}test "digest round trips canonical lowercase hexadecimal" { const source = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; const digest = try Digest.fromHex(source); try std.testing.expect(digest.isKnown()); try std.testing.expectEqualStrings(source, &digest.hex()); try std.testing.expectError( error.InvalidDigestByte, Digest.fromHex( "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeg", ), );}Audit
| Definitions | 22 |
|---|---|
| Public names | 36 |
| Members | 14 |
| Version | 26.7.0 |
| Revision | daab053ee433 |