[][src]Crate serialize_deserialize_u8_i32

Serializing high-level data types

The following section documents the process of serializing complex high-level data types to i32.

Using the following method, you can serialize your own custom data structures to i32. For example, want to serialize and deserialize a custom PhotonImage struct? Here's how ... Add serialize_deserialize_u8_i32 dependency in your Cargo.toml file (please note that we have also added serde and bincode for this usage example)

This example is not tested
[dependencies]
serialize_deserialize_u8_i32 = "^0.1"
serde = { version = "1.0.104", features = ["derive"] }
bincode = "1.2.1"

Add the following code to your application

This example is not tested
use serde::{Deserialize, Serialize};
use serialize_deserialize_u8_i32::s_d_u8_i32;
use bincode;

Create a high level data type and then serialize and deserialize...

This example is not tested
// Create a high level custom struct
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct PhotonImage {
    raw_pixels: Vec<u8>,
    width: u32,
    height: u32,
}

// Serialize and deserialize
```rust, ignore
fn main() {
    // Imlement the struct with data
    let photon_image = PhotonImage {
        raw_pixels: vec![
            134, 122, 131, 255, 131, 131, 139, 255, 135, 134, 137, 255, 138, 134, 130, 255, 126,
            125, 119, 255, 131, 134, 129, 255, 137, 134, 132, 255, 130, 126, 130, 255, 132, 125,
            132, 255, 122, 142, 129, 255, 134, 135, 128, 255, 138, 120, 125, 255, 125, 134, 110,
            255, 121, 122, 137, 255, 141, 140, 141, 255, 125, 144, 120, 255,
        ],
        width: 4,
        height: 4,
    };
    println!("PhotonImage: {:?}", photon_image);
    /*
    PhotonImage: PhotonImage { raw_pixels: [134, 122, 131, 255, 131, 131, 139, 255, 135, 134, 137, 255, 138, 134, 130, 255, 126, 125, 119, 255, 131, 134, 129, 255, 137, 134, 132, 255, 130, 126, 130, 255, 132, 125, 132, 255, 122, 142, 129, 255, 134, 135, 128, 255, 138, 120, 125, 255, 125, 134, 110, 255, 121, 122, 137, 255, 141, 140, 141, 255, 125, 144, 120, 255], width: 4, height: 4 }
    */

    // Serialize that to standard u8
    let encoded_u8: Vec<u8> = bincode::serialize(&photon_image).unwrap();
    println!("As u8: {:?}", encoded_u8);
    /*
    As u8: [64, 0, 0, 0, 0, 0, 0, 0, 134, 122, 131, 255, 131, 131, 139, 255, 135, 134, 137, 255, 138, 134, 130, 255, 126, 125, 119, 255, 131, 134, 129, 255, 137, 134, 132, 255, 130, 126, 130, 255, 132, 125, 132, 255, 122, 142, 129, 255, 134, 135, 128, 255, 138, 120, 125, 255, 125, 134, 110, 255, 121, 122, 137, 255, 141, 140, 141, 255, 125, 144, 120, 255, 4, 0, 0, 0, 4, 0, 0, 0]
    */

    // Serialize that to i32
    let encoded_i32: Vec<i32> = s_d_u8_i32::serialize_u8_to_i32(encoded_u8);
    println!("As i32: {:?}", encoded_i32);
    /*
    As i32: [1064000000, 1000000000, 1000000134, 1122131255, 1131131139, 1255135134, 1137255138, 1134130255, 1126125119, 1255131134, 1129255137, 1134132255, 1130126130, 1255132125, 1132255122, 1142129255, 1134135128, 1255138120, 1125255125, 1134110255, 1121122137, 1255141140, 1141255125, 1144120255, 1004000000, 1000004000, 2000000000]
    */

    // Deserialize back to u8
    let encoded_u8_again: Vec<u8> = s_d_u8_i32::deserialize_i32_to_u8(encoded_i32);
    println!("As u8 again: {:?}", encoded_u8_again);
    /*
    As u8 again: [64, 0, 0, 0, 0, 0, 0, 0, 134, 122, 131, 255, 131, 131, 139, 255, 135, 134, 137, 255, 138, 134, 130, 255, 126, 125, 119, 255, 131, 134, 129, 255, 137, 134, 132, 255, 130, 126, 130, 255, 132, 125, 132, 255, 122, 142, 129, 255, 134, 135, 128, 255, 138, 120, 125, 255, 125, 134, 110, 255, 121, 122, 137, 255, 141, 140, 141, 255, 125, 144, 120, 255, 4, 0, 0, 0, 4, 0, 0, 0]
    */

    // Deserialize back to Rust
    let decoded: PhotonImage = bincode::deserialize(&encoded_u8_again[..]).unwrap();
    println!("As PhotonImage again: {:?}", decoded);
    /*
    As PhotonImage again: PhotonImage { raw_pixels: [134, 122, 131, 255, 131, 131, 139, 255, 135, 134, 137, 255, 138, 134, 130, 255, 126, 125, 119, 255, 131, 134, 129, 255, 137, 134, 132, 255, 130, 126, 130, 255, 132, 125, 132, 255, 122, 142, 129, 255, 134, 135, 128, 255, 138, 120, 125, 255, 125, 134, 110, 255, 121, 122, 137, 255, 141, 140, 141, 255, 125, 144, 120, 255], width: 4, height: 4 }
    */

Serializing u8 to i32 explicitly

If you are interested in using a highly performant data model with a minimum of dependencies, please consider the following. As you can see from the examples above, this library can facilitate the storage and retrieval of high-level complex data types in a generic way. Naturally, this is very simple and easy to use. You can, however, go a step further and explicitly encode your data to i32 yourself, ahead of time. Essentially what this means is, instead of creating a generic representation of your data, you can crack your PhotonImage object open (ahead of time) to serialize and store each internal part separately.

Why would you want to do this?

So that you can build your intense computation to be more effieicnt. Let me explain. If you store your data as a high-leve data type, the application that uses it will have to unpack it. The unpacking is an overhead that your execution may not want. In addition, the inpacking requires dependencies like serde and bincode. You can still store and load the high level object. Just do that in a different Rust/Wasm executable. If you want maximum efficiency and you have data that qualifies i.e. an array of pixels ([u8]) you can store these in such a way that the Wasm VM can natively process them (without any serde & bincode overhead) Here is an example of the discrete application which would just perform pixel processing, with minimal overheads Cargo.toml

This example is not tested
[dependencies]
serialize_deserialize_u8_i32 = "^0.1"
rust_storage_interface_library = "^0.1"

Rust/Wasm pixel processing function

This example is not tested
use serialize_deserialize_u8_i32::s_d_u8_i32;
use rust_storage_interface_library::ssvm_storage;
// Takes the i32 storage key for a specific image, converts the image and returns a new storage key to the newly generated (solarized) image
#[no_mangle]
pub extern fn solarize_the_pixels(_orig_image_location: i32) -> i32 {
    // Load your data from the storage layer (u8 pixels are stored at a compression rate of 3:1)
    let i32_vec: Vec<i32> = ssvm_storage::load::load_as_i32_vector(storage_key);
    // Quickly convert it to pixel data
    let mut individual_pixels: Vec<u8> = s_d_u8_i32::deserialize_i32_to_u8(i32_vec);
    // Process each pixel directly inside the VM
    for pixel in individual_pixels.iter_mut() {
        if 200 as i32 - *pixel as i32 > 0 {
            *pixel = 200 - *pixel;
        }
    }
    // Pack the u8 pixels back into i32s (compressing 3:1)
    let new_encoded_image: Vec<i32> = s_d_u8_i32::serialize_u8_to_i32(individual_pixels);
    // Save the solarized image to the storage location and retrieve its storage key
    let new_image_storage_key: i32 = ssvm_storage::store::store_as_i32_vector(new_encoded_image);
    // Pass the storage key of the solarized image back to the calling code
    new_image_storage_key
}

Modules

s_d_u8_i32