LnmpRecord

Struct LnmpRecord 

Source
pub struct LnmpRecord { /* private fields */ }
Expand description

A complete LNMP record (collection of fields)

Implementations§

Source§

impl LnmpRecord

Source

pub fn new() -> Self

Creates a new empty record

Source

pub fn add_field(&mut self, field: LnmpField)

Adds a field to the record

Source

pub fn get_field(&self, fid: FieldId) -> Option<&LnmpField>

Gets a field by field ID (returns the first match if duplicates exist)

Source

pub fn remove_field(&mut self, fid: FieldId)

Removes all fields with the given field ID

Source

pub fn fields(&self) -> &[LnmpField]

Returns a slice of all fields in the record

Source

pub fn into_fields(self) -> Vec<LnmpField>

Consumes the record and returns the fields vector

Source

pub fn sorted_fields(&self) -> Vec<LnmpField>

Returns fields sorted by field ID (stable sort preserves insertion order for duplicates)

Source

pub fn from_sorted_fields(fields: Vec<LnmpField>) -> Self

Creates a record from a vector of fields (typically already sorted)

Source

pub fn from_fields(fields: Vec<LnmpField>) -> Self

Creates a record from fields, automatically sorting by FID

This ensures canonical field ordering regardless of input order. Use this constructor when building records from unsorted field collections.

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

let fields = vec![
    LnmpField { fid: 23, value: LnmpValue::Int(3) },
    LnmpField { fid: 7, value: LnmpValue::Int(1) },
    LnmpField { fid: 12, value: LnmpValue::Int(2) },
];

let record = LnmpRecord::from_fields(fields);

// Fields are automatically sorted by FID
assert_eq!(record.fields()[0].fid, 7);
assert_eq!(record.fields()[1].fid, 12);
assert_eq!(record.fields()[2].fid, 23);
Source

pub fn validate_with_limits( &self, limits: &StructuralLimits, ) -> Result<(), StructuralError>

Validates this record against structural limits (depth, field counts, lengths).

Source

pub fn canonical_eq(&self, other: &Self) -> bool

Compares two records based on canonical form (field order independent).

This method compares records semantically by comparing their sorted fields. Two records are canonically equal if they have the same fields (same FID and value), regardless of the order in which fields were added.

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

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

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

// Structural equality: order matters
assert_ne!(rec1, rec2);

// Canonical equality: order doesn't matter
assert!(rec1.canonical_eq(&rec2));
Source

pub fn canonical_hash<H: Hasher>(&self, state: &mut H)

Computes a hash based on canonical field ordering.

This method computes a hash using sorted fields, ensuring that the hash is independent of field insertion order. This is useful for using LnmpRecord in HashMap or HashSet with semantic equality.

§Example
use lnmp_core::{LnmpRecord, LnmpField, LnmpValue};
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;

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

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

let mut hasher1 = DefaultHasher::new();
rec1.canonical_hash(&mut hasher1);
let hash1 = hasher1.finish();

let mut hasher2 = DefaultHasher::new();
rec2.canonical_hash(&mut hasher2);
let hash2 = hasher2.finish();

// Same canonical hash despite different insertion order
assert_eq!(hash1, hash2);
Source

pub fn validate_field_ordering(&self) -> Result<(), FieldOrderingError>

Validates that fields are in canonical order (sorted by FID).

Returns Ok(()) if fields are sorted, or an error with details about the first out-of-order field.

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

// Sorted record
let record = LnmpRecord::from_fields(vec![
    LnmpField { fid: 7, value: LnmpValue::Int(1) },
    LnmpField { fid: 12, value: LnmpValue::Int(2) },
]);
assert!(record.validate_field_ordering().is_ok());

// Unsorted record
let mut record = LnmpRecord::new();
record.add_field(LnmpField { fid: 12, value: LnmpValue::Int(2) });
record.add_field(LnmpField { fid: 7, value: LnmpValue::Int(1) });
assert!(record.validate_field_ordering().is_err());
Source

pub fn is_canonical_order(&self) -> bool

Returns whether fields are in canonical order (sorted by FID).

This is a convenience method that returns a boolean instead of a Result.

§Example
use lnmp_core::{RecordBuilder, LnmpField, LnmpValue};

let record = RecordBuilder::new()
    .add_field(LnmpField { fid: 7, value: LnmpValue::Int(1) })
    .build();

assert!(record.is_canonical_order());
Source

pub fn count_ordering_violations(&self) -> usize

Returns the number of out-of-order field pairs.

A count of 0 means the record is in canonical order. Higher counts indicate more disorder.

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

let mut record = LnmpRecord::new();
record.add_field(LnmpField { fid: 23, value: LnmpValue::Int(3) });
record.add_field(LnmpField { fid: 7, value: LnmpValue::Int(1) });
record.add_field(LnmpField { fid: 12, value: LnmpValue::Int(2) });

// 23 > 7 (disorder), 7 < 12 (ok), so 1 disorder
assert_eq!(record.count_ordering_violations(), 1);

Trait Implementations§

Source§

impl Clone for LnmpRecord

Source§

fn clone(&self) -> LnmpRecord

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for LnmpRecord

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for LnmpRecord

Source§

fn default() -> LnmpRecord

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for LnmpRecord

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for LnmpRecord

Source§

fn eq(&self, other: &LnmpRecord) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for LnmpRecord

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for LnmpRecord

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,