-
Notifications
You must be signed in to change notification settings - Fork 10
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
feat: add Codec trait #5
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
//! This module contains traits to have a unified API across codecs. | ||
//! | ||
//! There are two traits defined, [`Codec`] and [`Links`]. Those are separate traits as the `Links` | ||
//! trait is not generic over a certain type. | ||
|
||
use cid::Cid; | ||
|
||
use std::io::{BufRead, Write}; | ||
|
||
/// Each IPLD codec implementation should implement this Codec trait. This way codecs can be more | ||
/// easily exchanged or combined. | ||
pub trait Codec<T>: Links { | ||
/// The multicodec code of the IPLD codec. | ||
const CODE: u64; | ||
/// The error that is returned if encoding or decoding fails. | ||
type Error; | ||
|
||
/// Decode a reader into the desired type. | ||
fn decode<R: BufRead>(reader: R) -> Result<T, Self::Error>; | ||
/// Encode a type into a writer. | ||
fn encode<W: Write>(writer: W, data: &T) -> Result<(), Self::Error>; | ||
|
||
/// Decode a slice into the desired type. | ||
fn decode_from_slice(bytes: &[u8]) -> Result<T, Self::Error> { | ||
Self::decode(bytes) | ||
} | ||
|
||
/// Encode a type into bytes. | ||
fn encode_to_vec(data: &T) -> Result<Vec<u8>, Self::Error> { | ||
let mut output = Vec::new(); | ||
Self::encode(&mut output, data)?; | ||
Ok(output) | ||
} | ||
} | ||
|
||
/// Trait for returning the links of a serialized IPLD data. | ||
pub trait Links { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I wonder if we want a relationship with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a separate trait, so it doesn't have to be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, makes sense. You don't care about T. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm.
|
||
/// The error that is returned if the link extraction fails. | ||
type LinksError; | ||
|
||
/// Return all links (CIDs) that the given encoded data contains. | ||
fn links(bytes: &[u8]) -> Result<impl Iterator<Item = Cid>, Self::LinksError>; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're going to want
NAME
eventually too, it's pretty helpful. This trait is almost the same as the interfaces we landed on in JS, although we ended up splitting encode and decode operations into two parts and combining them into a singleBlockCodec
: https://github.com/multiformats/js-multiformats/blob/master/src/codecs/interface.tsThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want the name. People should really use the constants as identifiers and not strings that might change.
Splitting encode and decode: I'd keep it simple for now, if the need of splitting ever occurs (which I currently doubt), we can do it then.