lnmp-core 0.5.1

Core type definitions for LNMP (LLM Native Minimal Protocol)
Documentation

lnmp-core

Core type definitions for LNMP (LLM Native Minimal Protocol) v0.4.

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 in v0.3)
  • LnmpField - A field ID and value pair
  • LnmpRecord - A collection of fields representing a complete record
  • SemanticChecksum - SC32 checksum computation for semantic fidelity (v0.3)
  • TypeHint - Type annotations for explicit typing (including nested types in v0.3)

Usage

Add to your Cargo.toml:

[dependencies]
lnmp-core = { path = "path/to/lnmp-core" }

Example

use lnmp_core::{LnmpField, LnmpRecord, LnmpValue};

// Create a new record
let mut record = LnmpRecord::new();

// Add fields with different value types
record.add_field(LnmpField {
    fid: 12,
    value: LnmpValue::Int(14532),
});

record.add_field(LnmpField {
    fid: 7,
    value: LnmpValue::Bool(true),
});

record.add_field(LnmpField {
    fid: 20,
    value: LnmpValue::String("Halil".to_string()),
});

record.add_field(LnmpField {
    fid: 23,
    value: LnmpValue::StringArray(vec![
        "admin".to_string(),
        "dev".to_string(),
    ]),
});

// Access fields
if let Some(field) = record.get_field(12) {
    println!("User ID: {:?}", field.value);
}

// Iterate over all fields
for field in record.fields() {
    println!("F{} = {:?}", field.fid, field.value);
}

// Get field count
println!("Total fields: {}", record.fields().len());

Types

LnmpValue

Represents all supported value types in LNMP v0.3:

pub enum LnmpValue {
    Int(i64),                      // Integer values
    Float(f64),                    // Floating-point values
    Bool(bool),                    // Boolean values (true/false)
    String(String),                // String values
    StringArray(Vec<String>),      // Arrays of strings
    NestedRecord(Box<LnmpRecord>), // Nested records (v0.3)
    NestedArray(Vec<LnmpRecord>),  // Arrays of records (v0.3)
}

v0.3 Nested Structure Support:

use lnmp_core::{LnmpField, LnmpRecord, LnmpValue};

// Create a nested record
let mut inner_record = LnmpRecord::new();
inner_record.add_field(LnmpField {
    fid: 10,
    value: LnmpValue::String("nested".to_string()),
});

let mut outer_record = LnmpRecord::new();
outer_record.add_field(LnmpField {
    fid: 50,
    value: LnmpValue::NestedRecord(Box::new(inner_record)),
});

// Create a nested array
let mut record1 = LnmpRecord::new();
record1.add_field(LnmpField { fid: 1, value: LnmpValue::Int(1) });

let mut record2 = LnmpRecord::new();
record2.add_field(LnmpField { fid: 1, value: LnmpValue::Int(2) });

let mut parent = LnmpRecord::new();
parent.add_field(LnmpField {
    fid: 60,
    value: LnmpValue::NestedArray(vec![record1, record2]),
});

LnmpField

A single field assignment consisting of a field ID and value:

pub struct LnmpField {
    pub fid: FieldId,      // Field identifier (0-65535)
    pub value: LnmpValue,  // Field value
}

LnmpRecord

A collection of fields representing a complete LNMP record:

impl LnmpRecord {
    pub fn new() -> Self;
    pub fn add_field(&mut self, field: LnmpField);
    pub fn get_field(&self, fid: FieldId) -> Option<&LnmpField>;
    pub fn fields(&self) -> &[LnmpField];
    pub fn into_fields(self) -> Vec<LnmpField>;
}

TypeHint

Type annotations for explicit typing (v0.2+):

pub enum TypeHint {
    Int,          // :i
    Float,        // :f
    Bool,         // :b
    String,       // :s
    StringArray,  // :sa
    Record,       // :r  (v0.3)
    RecordArray,  // :ra (v0.3)
}

SemanticChecksum (v0.3)

Compute and validate semantic checksums (SC32) for drift prevention:

use lnmp_core::{SemanticChecksum, TypeHint, LnmpValue};

// Compute checksum
let checksum = SemanticChecksum::compute(
    12,  // field ID
    TypeHint::Int,
    &LnmpValue::Int(14532)
);

// Validate checksum
let is_valid = SemanticChecksum::validate(
    12,
    TypeHint::Int,
    &LnmpValue::Int(14532),
    checksum
);

// Format as hex string
let hex = SemanticChecksum::format(checksum);  // "36AAE667"

v0.3 Features

Nested Structures

Support for hierarchical data modeling:

  • Nested Records: F50={F12=1;F7=1} - Records within records
  • Nested Arrays: F60=[{F1=1},{F1=2}] - Arrays of records
  • 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/01 or 0
  • Floats: -0.00.0, 3.1403.14
  • Strings: Configurable case normalization

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
  • 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 lnmp_codec::binary::{BinaryEncoder, BinaryDecoder};
use lnmp_core::{LnmpRecord, LnmpField, LnmpValue};

let mut record = LnmpRecord::new();
record.add_field(LnmpField {
    fid: 12,
    value: LnmpValue::Int(14532),
});

// Encode to binary
let encoder = BinaryEncoder::new();
let binary = encoder.encode(&record).unwrap();

// Decode from binary
let decoder = BinaryDecoder::new();
let decoded_record = decoder.decode(&binary).unwrap();

Migration from v0.2

v0.3 is backward compatible with v0.2. New features:

  • LnmpValue::NestedRecord and LnmpValue::NestedArray variants
  • TypeHint::Record and TypeHint::RecordArray variants
  • SemanticChecksum module for checksum computation
  • depth() and validate_structure() methods on LnmpValue

v0.4 adds binary protocol support (via lnmp-codec) with no changes to core types.

Existing v0.2 code continues to work without changes.

License

MIT OR Apache-2.0