Skip to documentation
SLOP

tiny.preserves.domain

Reference 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.

Types and contracts

Public types and contracts.

No direct callersNo direct callstiny.preservesdomain
Static calls · unresolved targets: unknown · external targets: unknown.

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

Definitions1
Public names1
Members0
Version26.7.0
Revisiondaab053ee433