Skip to content

Commit

Permalink
feat: make it possible to define your own primitive types
Browse files Browse the repository at this point in the history
As issue #19 outlines, it might make sense to use a different internal
type for integer values. This commit makes all primitive types generic,
so that you can choose your own.

Though you're discouraged from doing so. Usually using the IPLD type
should be enough and leads to the best interoperability.

Thanks @Stebalien for the idea of this implementation.

Fixes #19.
  • Loading branch information
vmx committed Aug 12, 2024
1 parent 9f1f1a8 commit 4ef5d73
Showing 1 changed file with 46 additions and 11 deletions.
57 changes: 46 additions & 11 deletions src/ipld.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,64 @@ impl fmt::Display for IndexError {
#[cfg(feature = "std")]
impl std::error::Error for IndexError {}

/// Ipld
/// Define the primitive types used for the internal IPLD Data Model representation within Rust.
///
/// `Null` is missing as this is always represented as a unit variant. The container types are
/// derived from the primitives defined here.
pub trait Primitives {
/// Type for a boolean.
type Bool;
/// Type for an integer.
type Integer;
/// Type for a float.
type Float;
/// Type for a String.
type String;
/// Type for bytes.
type Bytes;
/// Type for a link.
type Link;
}

/// The default values for the primitive types.
#[derive(Clone)]
pub enum Ipld {
pub struct DefaultPrimitives;

impl Primitives for DefaultPrimitives {
type Bool = bool;
type Integer = i128;
type Float = f64;
type String = String;
type Bytes = Vec<u8>;
type Link = Cid;
}

/// The generic version of the core IPLD type that allows using custom primitive types.
#[derive(Clone)]
pub enum IpldGeneric<P: Primitives = DefaultPrimitives> {
/// Represents the absence of a value or the value undefined.
Null,
/// Represents a boolean value.
Bool(bool),
Bool(P::Bool),
/// Represents an integer.
Integer(i128),
Integer(P::Integer),
/// Represents a floating point value.
Float(f64),
Float(P::Float),
/// Represents an UTF-8 string.
String(String),
String(P::String),
/// Represents a sequence of bytes.
Bytes(Vec<u8>),
Bytes(P::Bytes),
/// Represents a list.
List(Vec<Ipld>),
List(Vec<Self>),
/// Represents a map of strings.
Map(BTreeMap<String, Ipld>),
/// Represents a map of integers.
Link(Cid),
Map(BTreeMap<P::String, Self>),
/// Represents a link, usually a CID.
Link(P::Link),
}

/// The core IPLD type.
pub type Ipld = IpldGeneric<DefaultPrimitives>;

impl fmt::Debug for Ipld {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if f.alternate() {
Expand Down

0 comments on commit 4ef5d73

Please sign in to comment.