tiny.preserves.domain
Defined in tiny.preserves.
The rules for a type whose values a host program embeds inside data values, and one such type that carries nothing.
API (2)
Actions
Public operations.
assertIsDomain: Stops compilation unlessDdeclares public functions namedeql,order,deinitandclone.
Types and contracts
Public types and contracts.
NoEmbedded: A type of embedded values whose one value carries no data, for programs that embed nothing.
Source
Source: lib/preserves/src/domain.zig
zig
//! The rules for a type whose values a host program embeds inside data values, and one such type//! that carries nothing. A value tree compares, orders, frees and copies the things embedded in it//! along with everything else, so the type of the embedded values has to supply those four//! operations. A generic in Zig checks a type's functions only at the line that calls them, so a//! type missing one fails deep inside the value code with an error that names no rule. Many//! programs embed nothing, and they still need a type for the embedded values. The//! [Preserves](https://preserves.dev/) data language lets a host program place its own values//! inside Preserves data as embedded values, and the package keeps them.//!//! The package has one generic value type (`Value`). That value type takes the type of its embedded//! values (*domain*) as a compile-time parameter, so each program chooses what it embeds and the//! compiler checks it. A compile-time check (`assertIsDomain`) runs first in every generic of the//! package and stops compilation when the type lacks `eql`, `order`, `deinit` or `clone`, with a//! message that names the missing function and the signature the package calls. The check looks for//! the four names only, and the compiler checks their signatures later, where the value code calls//! them. A `hash` function is optional: `Value.hash` mixes in the embedded value's hash only when//! the type declares one, so without it every embedded value adds the same bytes. `NoEmbedded`//! fills the parameter for programs that embed nothing: its one value carries no data, every two//! are equal, and freeing and copying do nothing. `AnyEmbedded`, which the package root re-exports//! from its `embedded_mod` namespace, is the other type the package ships, for payloads of the host//! program.const std = @import("std");const Allocator = std.mem.Allocator;/// Stops compilation unless `D` declares public functions named `eql`, `order`, `deinit` and/// `clone`. Code that writes a generic over `Value` calls it first, as `Value` and every generic of/// the package do, so a type of embedded values that breaks the rules fails. The check tests that/// the names exist and reads no signature. The error names the missing function and the signature/// the package calls: `eql(a: Self, b: Self) bool`, `order(a: Self, b: Self) std.math.Order`,/// `deinit(self: *Self, allocator: Allocator) void` and/// `clone(self: Self, allocator: Allocator) !Self`.pub fn assertIsDomain(comptime D: type) void { if (!@hasDecl(D, "eql")) { @compileError("Domain " ++ @typeName(D) ++ " is missing `pub fn eql(a: Self, b: Self) bool`"); } if (!@hasDecl(D, "order")) { @compileError("Domain " ++ @typeName(D) ++ " is missing `pub fn order(a: Self, b: Self) std.math.Order`"); } if (!@hasDecl(D, "deinit")) { @compileError("Domain " ++ @typeName(D) ++ " is missing `pub fn deinit(self: *Self, allocator: Allocator) void`"); } if (!@hasDecl(D, "clone")) { @compileError("Domain " ++ @typeName(D) ++ " is missing `pub fn clone(self: Self, allocator: Allocator) !Self`"); }}/// A type of embedded values whose one value carries no data, for programs that embed nothing. Code/// with nothing to embed passes it to `Value`, as the binary reader's tests do. Every two of its/// values are equal.pub const NoEmbedded = struct { /// Returns `true` for any two values. `Value.eql` calls it for two embedded values of this /// type. pub fn eql(a: NoEmbedded, b: NoEmbedded) bool { _ = a; _ = b; return true; } /// Returns `.eq` for any two values. `Value.compare` calls it for two embedded values of this /// type. pub fn order(a: NoEmbedded, b: NoEmbedded) std.math.Order { _ = a; _ = b; return .eq; } /// Does nothing, since the value owns nothing. `Value.deinit` calls it for an embedded value of /// this type. pub fn deinit(self: *NoEmbedded, allocator: Allocator) void { _ = self; _ = allocator; } /// Returns the value itself and allocates nothing. `cloneValueDeep` calls it for an embedded /// value of this type. The call never fails, though its type carries an error union for the /// rule's signature. pub fn clone(self: NoEmbedded, allocator: Allocator) !NoEmbedded { _ = allocator; return self; }};test "NoEmbedded satisfies the Domain contract" { comptime assertIsDomain(NoEmbedded);}Source: lib/preserves/src/root.zig:107
zig
pub const domain = @import("domain.zig");Audit
| Definitions | 1 |
|---|---|
| Public names | 1 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |