Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
lnmp-core
Core type definitions for LNMP (LLM Native Minimal Protocol) v0.5.13.
FID Registry: All examples use official Field IDs from
registry/fids.yaml.
Overview
This crate provides the fundamental data structures for representing LNMP data:
FieldId- Type alias for field identifiers (u16, range 0-65535)LnmpValue- Enum representing all supported value types (including nested structures and generic arrays)RecordBuilder- Fluent API for constructing canonical records with automatic field sortingLnmpField- A field ID and value pairLnmpRecord- A collection of fields representing a complete recordSemanticChecksum- SC32 checksum computation for semantic fidelity (v0.3)TypeHint- Type annotations for explicit typing (including nested types and generic arrays)LnmpProfile- Strictness profiles (Loose, Standard, Strict) for validation and canonical enforcementStrictDeterministicConfig- Fine-grained control over determinism requirements
Usage
Add to your Cargo.toml:
[]
= { = "path/to/lnmp-core" }
Examples
This crate includes several examples in the examples/ directory:
- basic_record: Creating and using simple records
- nested_structures: Working with nested records and arrays
Run examples with:
Quick Start
use ;
// Create a new record
let mut record = new;
// Add fields with different value types
record.add_field;
record.add_field;
record.add_field;
record.add_field;
// Access fields
if let Some = record.get_field
// Iterate over all fields
for field in record.fields
// Get field count
println!;
Types
LnmpValue
Represents all supported value types in LNMP v0.3:
| Type Code | Description | Example |
|---|---|---|
:sa |
String Array | StringArray(["a", "b"]) |
:ia |
Int Array | IntArray([1, 2, 3]) |
:fa |
Float Array | FloatArray([1.1, 2.2]) |
:ba |
Bool Array | BoolArray([true, false]) |
:r |
Nested Record | NestedRecord(...) |
v0.3 Nested Structure Support:
use ;
// Create a nested record (F70=nested_data from registry)
let mut inner_record = new;
inner_record.add_field;
let mut outer_record = new;
outer_record.add_field;
// Create a record array (F71=record_list from registry)
let mut record1 = new;
record1.add_field; // F12=user_id
let mut record2 = new;
record2.add_field; // F12=user_id
let mut parent = new;
parent.add_field;
LnmpField
A single field assignment consisting of a field ID and value:
LnmpRecord
A collection of fields representing a complete LNMP record:
RecordBuilder (v0.5.4)
Fluent API for constructing records with automatic canonical ordering:
use ;
// Builder automatically sorts fields by FID
let record = new
.add_field
.add_field
.add_field
.build;
// Fields are stored in canonical order: 7, 12, 23
assert_eq!;
// Alternative: construct from unsorted fields
let fields = vec!;
let record = from_fields;
TypeHint
Type annotations for explicit typing (v0.2+):
SemanticChecksum (v0.3)
Compute and validate semantic checksums (SC32) for drift prevention:
use ;
// Compute checksum
let checksum = compute;
// Validate checksum
let is_valid = validate;
// Format as hex string
let hex = format; // "36AAE667"
v0.3 Features
Nested Structures
Support for hierarchical data modeling:
- Nested Records:
F70={F12=1;F7=1}- Records within records (F70=nested_data) - Record Arrays:
F71=[{F12=1},{F12=2}]- Arrays of records (F71=record_list) - Arbitrary Depth: Limited only by available memory
- Structural Validation:
value.validate_structure()ensures integrity
Semantic Checksums (SC32)
32-bit checksums for preventing LLM input drift:
- Deterministic: Same value always produces same checksum
- Semantic: Based on FID + type hint + normalized value
- Optional: Can be enabled/disabled via configuration
- Fast: CRC32-based algorithm (<1μs per field)
Value Normalization
Canonical transformations for semantic equivalence:
- Booleans:
true/false/yes/no/1/0→1or0 - Floats:
-0.0→0.0,3.140→3.14 - Strings: Configurable case normalization
Deterministic Guarantees
LNMP-Core provides strong deterministic guarantees to prevent LLM drift and ensure semantic consistency:
Canonical Field Ordering
The sorted_fields() method provides canonical representation where fields are sorted by FID (Field ID):
let mut record = new;
record.add_field;
record.add_field;
record.add_field;
// Insertion order: 23, 7, 12
assert_eq!;
assert_eq!;
// Canonical order (sorted by FID): 7, 12, 23
let sorted = record.sorted_fields;
assert_eq!;
assert_eq!;
assert_eq!;
Key Points:
fields()returns fields in insertion ordersorted_fields()returns fields in canonical order (sorted by FID)- All encoders (
lnmp-codec) usesorted_fields()for output SemanticChecksumusessorted_fields()for deterministic hashing
Deterministic SemanticChecksum (SC32)
The SemanticChecksum system ensures the same semantic data always produces the same checksum, regardless of field insertion order:
use ;
use SemanticChecksum;
// Record 1: fields added in order 12, 7
let mut rec1 = new;
rec1.add_field;
rec1.add_field;
// Record 2: fields added in order 7, 12 (different!)
let mut rec2 = new;
rec2.add_field;
rec2.add_field;
// When serialized for checksum, both use sorted_fields internally
// So nested records with different insertion order produce SAME checksum
let val1 = NestedRecord;
let val2 = NestedRecord;
let cs1 = compute; // F70=nested_data
let cs2 = compute;
assert_eq!; // ✅ Same checksum despite different insertion order!
Normalization Rules:
- Booleans: Always serialized as
1(true) or0(false) - Floats:
-0.0normalized to0.0, trailing zeros removed (e.g.,3.140→3.14) - Nested Records: Fields sorted by FID before serialization
- Arrays: Order preserved (array element order is semantic)
Canonical Encoding
All encoders in lnmp-codec produce canonical output:
use Encoder;
// Fields added in non-canonical order
let mut record = new;
record.add_field;
record.add_field;
let encoder = new;
let output = encoder.encode;
// Output is ALWAYS sorted by FID (canonical):
// F7=1
// F23=3
Binary Encoding:
- Binary encoders also use
sorted_fields() - Binary format can optionally validate canonical field ordering
- Round-trip (text → binary → text) produces canonical sorted output
Best Practices
For Deterministic Behavior:
- Use
sorted_fields()when comparing records semantically - Use
SemanticChecksumto detect drift - Rely on encoder output (always canonical)
When Order Matters:
- Use
fields()to preserve insertion order - Note:
PartialEqcompares in insertion order (structural equality)
Canonical Equality (v0.5.4)
For semantic comparison that ignores field order:
use ;
let mut rec1 = new
.add_field
.add_field
.build;
let mut rec2 = new
.add_field
.add_field
.build;
// Structural equality: false (different field order)
assert_ne!;
// Canonical equality: true (same fields, semantically)
assert!;
Features
- Zero dependencies - Pure Rust implementation (except CRC32 for checksums)
- Type safety - Strong typing for all value types
- Efficient storage - Fields stored in a Vec for cache-friendly access
- Flexible access - Get fields by ID or iterate over all fields
- Deterministic checksums - Field-order-independent SC32 for drift prevention
- Canonical encoding - Encoders always produce sorted output
- Nested structures - Support for hierarchical data in text format (v0.3)
- Semantic checksums - Drift prevention with SC32 (v0.3)
- Binary format support - Compatible with v0.4 binary protocol (via lnmp-codec)
Binary Format Support (v0.4)
The core types are fully compatible with the v0.4 binary protocol format:
- All primitive types (Int, Float, Bool, String, StringArray) can be encoded to binary
- Binary encoding provides 30-50% size reduction compared to text format
- Round-trip conversion (text ↔ binary) maintains data integrity
- Note: Nested structures (NestedRecord, NestedArray) are not yet supported in v0.4 binary format
- Nested structures remain fully supported in text format
- Binary support for nested structures is planned for v0.5
For binary encoding/decoding, use the lnmp-codec crate:
use ;
use ;
let mut record = new;
record.add_field;
// Encode to binary
let encoder = new;
let binary = encoder.encode.unwrap;
// Decode from binary
let decoder = new;
let decoded_record = decoder.decode.unwrap;
v0.5.14 Features
FID Registry Runtime Validation
Validate fields against the official FID registry at runtime:
use ;
// Load embedded registry
let registry = embedded_registry;
// Validate a field
let result = registry.validate_field;
match result
Registry Sync
Manage FID registry versions across multiple peers:
use RegistrySync;
let mut sync = with_embedded;
// Track peer registry versions
sync.register_peer;
sync.register_peer;
// Check version comparison
if sync.is_ahead_of
if sync.is_behind
Migration from v0.2
v0.3 is backward compatible with v0.2. New features:
LnmpValue::NestedRecordandLnmpValue::NestedArrayvariantsTypeHint::RecordandTypeHint::RecordArrayvariantsSemanticChecksummodule for checksum computationdepth()andvalidate_structure()methods onLnmpValue
v0.4 adds binary protocol support (via lnmp-codec) with no changes to core types.
v0.5.14 adds:
FidRegistrywith runtime validationRegistrySyncfor multi-peer version trackingembedded_registry()for compile-time embedded FIDs
Existing v0.2 code continues to work without changes.
License
MIT OR Apache-2.0