Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encoding relations API #51

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 58 additions & 10 deletions encoding/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ use std::future::Future;
use crate::error::DecodeError;
use ufotofu::local_nb::{BulkConsumer, BulkProducer};

/// A type that can be encoded to a bytestring, ensuring that any value of `Self` maps to exactly one bytestring.
/// A type which can be asynchronously encoded to bytes consumed by a [`ufotofu::local_nb::BulkConsumer`]
///
/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what)
pub trait Encodable {
/// Encode a value to a bytestring in a specific way that is best described over at [willowprotocol.org](https://willowprotocol.org/specs/encodings/index.html#encodings_what).
/// Encode the value with an [encoding function](https://macromania--channelclosing.deno.dev/specs/encodings/index.html#encoding_function) for the set of `Self`, ensuring that any value of `Self` maps to exactly one bytestring, such that there exists a _decoding_ function such that:
sgwilym marked this conversation as resolved.
Show resolved Hide resolved
///
/// - for every value `s` in `Self` and every bytestring `b` that starts with `encode_s(s)`, we have `decode_s(b)=s`, and
/// - for every `s` in `Self` and every bytestring b that does not start with `encode_s(s)`, we have `decode_s(b) ≠ s`.
///
/// The encoded bytestring will be consumed to the provided [`ufotofu::local_nb::BulkConsumer`].
/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encode_s)
fn encode<Consumer>(
&self,
Expand All @@ -18,11 +22,16 @@ pub trait Encodable {
Consumer: BulkConsumer<Item = u8>;
}

/// A type that can be decoded from a bytestring, ensuring that every valid encoding maps to exactly one member of `Self`.
/// A type which can be asynchronously decoded from bytes produced by a [`ufotofu::local_nb::BulkProducer`]
///
/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what)
pub trait Decodable {
/// Decade a value to a bytestring in a specific way that is best described over at [willowprotocol.org](https://willowprotocol.org/specs/encodings/index.html#encodings_what).
/// Decode a bytestring created with an [encoding function](https://macromania--channelclosing.deno.dev/specs/encodings/index.html#encoding_function) for the set of `Self`, ensuring that any value of `Self` maps to exactly one bytestring, such that there exists a _decoding_ function (provided by this trait!) such that:
///
/// - for every value `s` in `Self` and every bytestring `b` that starts with `encode_s(s)`, we have `decode_s(b)=s`, and
/// - for every `s` in `Self` and every bytestring `b` that does not start with `encode_s(s)`, we have `decode_s(b) ≠ s`.
///
/// Will return an error if the encoding correlates to the **encoding relation** and not the result of the aforementioned encoding function.
sgwilym marked this conversation as resolved.
Show resolved Hide resolved
///
/// [Definition](https://willowprotocol.org/specs/encodings/index.html#decode_s)
fn decode<Producer>(
sgwilym marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -31,12 +40,31 @@ pub trait Decodable {
where
Producer: BulkProducer<Item = u8>,
Self: Sized;

/// Decode a bytestring belonging to the **encoding relation** on the set of `Self` and the set of bytestrings, such that:
///
/// - for every `s` in `Self`, there is at least one bytestring in relation with `s`, and
/// - no bytestring in the relation is a prefix of another bytestring in the relation.
///
/// [Definition](https://willowprotocol.org/specs/encodings/index.html#decode_s)
fn decode_relation<Producer>(
producer: &mut Producer,
) -> impl Future<Output = Result<Self, DecodeError<Producer::Error>>>
where
Producer: BulkProducer<Item = u8>,
Self: Sized;
}

/// A type that can be used to encode `T` to a bytestring *encoded relative to `R`*.
/// This can be used to create more compact encodings from which `T` can be derived by anyone with `R`.
/// A type relative to a reference value of type `R` which can be asynchronously encoded to bytes consumed by a [`ufotofu::local_nb::BulkConsumer`]
///
/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what)
///
/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what)
pub trait RelativeEncodable<R> {
/// Encode a value (relative to a reference value) to a bytestring in a specific way that is best described over at [willowprotocol.org](https://willowprotocol.org/specs/encodings/index.html#encodings_what).
/// Encode a pair of `Self` and `R` with the [encoding function](https://macromania--channelclosing.deno.dev/specs/encodings/index.html#encoding_function) for the set of `Self` relative to a value of the set of `R`, ensuring that any pair of `Self` and `R` maps to exactly one bytestring, such that there exists a _decoding_ function such that:
///
/// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that starts with `encode_s(s, r)`, we have `decode_s(b, r)=s`, and
/// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that does not start with `encode_s(s, r)`, we have `decode_s(b, r) ≠ s`.
fn relative_encode<Consumer>(
&self,
reference: &R,
Expand All @@ -46,15 +74,35 @@ pub trait RelativeEncodable<R> {
Consumer: BulkConsumer<Item = u8>;
}

/// A type that can be used to decode `T` from a bytestring *encoded relative to `Self`*.
/// This can be used to decode a compact encoding frow which `T` can be derived by anyone with `R`.
/// A type relative to a value of type `R` which can be asynchronously decoded from bytes produced by a [`ufotofu::local_nb::BulkProducer`]
///
/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what)
pub trait RelativeDecodable<R> {
/// Decode a value (relative to a reference value) to a bytestring in a specific way that is best described over at [willowprotocol.org](https://willowprotocol.org/specs/encodings/index.html#encodings_what).
///
/// Decode a bytestring created with an [encoding function](https://macromania--channelclosing.deno.dev/specs/encodings/index.html#encoding_function) for the set of `Self` relative to a value of the set of `R`, ensuring that any pair of `Self` and `R` maps to exactly one bytestring, such that there exists a _decoding_ function (provided by this trait!) such that:
///
/// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that starts with `encode_s(s, r)`, we have `decode_s(b, r)=s`, and
/// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that does not start with `encode_s(s, r)`, we have `decode_s(b, r) ≠ s`.
///
/// Will return an error if the encoding correlates to the **encoding relation** and not the result of the aforementioned encoding function.
sgwilym marked this conversation as resolved.
Show resolved Hide resolved
///
/// [Definition](https://willowprotocol.org/specs/encodings/index.html#decode_s)
fn relative_decode<Producer>(
reference: &R,
producer: &mut Producer,
) -> impl Future<Output = Result<Self, DecodeError<Producer::Error>>>
where
Producer: BulkProducer<Item = u8>,
Self: Sized;

/// Decode a bytestring belonging to the **encoding relation** on the set of `Self` relative to a value of the set of `R`, and the set of bytestrings, such that:
///
/// - for every pair of `s` in `Self` and `r` in `R`, there is at least one bytestring in relation with the pair of `s` and `r`, and
/// - no bytestring in the relation is a prefix of another bytestring in the relation.
fn relative_decode_relation<Producer>(
producer: &mut Producer,
) -> impl Future<Output = Result<Self, DecodeError<Producer::Error>>>
where
Producer: BulkProducer<Item = u8>,
Self: Sized;
}
Loading