Skip to main content

Module value

Module value 

Source
Expand description

Value types, schemas, and conversion traits. Value type and conversion traits for schema types. For a deeper look at portability goals, common formats, and schema design, refer to the “Portability & Common Formats” chapter in the project book.

§Example

use triblespace_core::value::{Value, ValueSchema, ToValue, TryFromValue};
use triblespace_core::metadata::ConstId;
use triblespace_core::id::Id;
use triblespace_core::macros::id_hex;
use std::convert::{TryInto, Infallible};

// Define a new schema type.
// We're going to define an unsigned integer type that is stored as a little-endian 32-byte array.
// Note that makes our example easier, as we don't have to worry about sign-extension or padding bytes.
pub struct MyNumber;

// Implement the ValueSchema trait for the schema type.
impl ConstId for MyNumber {
   const ID: Id = id_hex!("345EAC0C5B5D7D034C87777280B88AE2");
}
impl ValueSchema for MyNumber {
   type ValidationError = ();
   // Every bit pattern is valid for this schema.
}

// Implement conversion functions for the schema type.
// Use `Error = Infallible` when the conversion cannot fail.
impl TryFromValue<'_, MyNumber> for u32 {
   type Error = Infallible;
   fn try_from_value(v: &Value<MyNumber>) -> Result<Self, Infallible> {
     Ok(u32::from_le_bytes(v.raw[0..4].try_into().unwrap()))
   }
}

impl ToValue<MyNumber> for u32 {
  fn to_value(self) -> Value<MyNumber> {
     // Convert the Rust type to the schema type, i.e. a 32-byte array.
     let mut bytes = [0; 32];
     bytes[0..4].copy_from_slice(&self.to_le_bytes());
     Value::new(bytes)
  }
}

// Use the schema type to store and retrieve a Rust type.
let value: Value<MyNumber> = MyNumber::value_from(42u32);
let i: u32 = value.from_value();
assert_eq!(i, 42);

// You can also implement conversion functions for other Rust types.
impl TryFromValue<'_, MyNumber> for u64 {
  type Error = Infallible;
  fn try_from_value(v: &Value<MyNumber>) -> Result<Self, Infallible> {
   Ok(u64::from_le_bytes(v.raw[0..8].try_into().unwrap()))
  }
}

impl ToValue<MyNumber> for u64 {
 fn to_value(self) -> Value<MyNumber> {
  let mut bytes = [0; 32];
  bytes[0..8].copy_from_slice(&self.to_le_bytes());
  Value::new(bytes)
  }
}

let value: Value<MyNumber> = MyNumber::value_from(42u64);
let i: u64 = value.from_value();
assert_eq!(i, 42);

// And use a value round-trip to convert between Rust types.
let value: Value<MyNumber> = MyNumber::value_from(42u32);
let i: u64 = value.from_value();
assert_eq!(i, 42);

Modules§

schemas
Built-in value schema types and their conversion implementations. This is a collection of Rust types that can be (de)serialized as crate::prelude::Values.

Structs§

Value
A value is a 32-byte array that can be (de)serialized as a Rust type. The schema type parameter is an abstract type that represents the meaning and valid bit patterns of the bytes.

Constants§

VALUE_LEN
The length of a value in bytes.

Traits§

ToValue
A trait for converting a Rust type to a Value with a specific schema type. This trait is implemented on the concrete Rust type.
TryFromValue
A trait for converting a Value with a specific schema type to a Rust type. This trait is implemented on the concrete Rust type.
TryToValue
A trait for converting a Rust type to a Value with a specific schema type. This trait is implemented on the concrete Rust type.
ValueSchema
A trait that represents an abstract schema type that can be (de)serialized as a Value.

Type Aliases§

RawValue
A raw value is simply a 32-byte array.