Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

A marker to allow compile-type checks for when the uniquely serializable representation in required #50

@MOZGIII

Description

@MOZGIII

Sometimes you want to build a data structure that, when serialized, in guaranteed to have the same representation for the same data.

An example of this would be a BitTorrent protocol: there's an info dictionary that's serialized via bencode (this lives in .torrent files and describes the contents of a torrent file), and an info_hash field that's used by trackers - a SHA1 hashsum of the serialized info struct.

info is an example of a well-defined struct, that only includes fields that have trivially understood serialization representations: scalars, arrays but no maps of any kind for instance.

It would be great to have a system that would allow validating at compile-time that a particular data structure only consists of fields that are guaranteed to be represented in a single way possible.

Consider this example:

// This sets up the basics.

trait UniqueRepr {}

impl UniqueRepr for u64 {}
impl<T: UniqueRepr> UniqueRepr for &[T] {}

// no impl for `f*` types, like f64
impl UniqueRepr for NormalF64 {} // an abstract newtype for f64 that ensures `is_normal() == true`

// This is how it helps to check our types.

// Works.
#[derive(UniqueRepr)]
struct MyStruct {
    a: u64,
}

// Doesn't work: f64 doesn't implement `UniqueRepr`
#[derive(UniqueRepr)]
struct MyBadStruct {
    b: f64,
}

// This works, because `NormalF64` implements `UniqueRepr`
#[derive(UniqueRepr)]
struct MyFixedStruct {
    b: NormalF64,
}

fn my_hash_exchange_system<T: UniqueRepr>(val: T) { ... }

my_hash_exchange_system(0u64); // works
my_hash_exchange_system(MyStruct{a: 123}) // works
my_hash_exchange_system(0f64) // nope
my_hash_exchange_system(NormalF64::try_from(0f64).unwrap()) // works

This is useful for all kinds of applications where you need to produce a type for which the serialization has to reliably hashed. Maybe for something else too, generically speaking - for reliably producing the reproducible representations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions