An open API service indexing awesome lists of open source software.

https://github.com/adinack/bundle

A multi-type container with a static size.
https://github.com/adinack/bundle

embedded-rust no-std static-types

Last synced: about 1 year ago
JSON representation

A multi-type container with a static size.

Awesome Lists containing this project

README

          

# bundle
A multi-type container with a static size.

## no_std

This crate is intended for use in `no_std` environments.

# Motivation

Trait objects require dynamic memory allocation since the concrete type being dispatched is not known until runtime.

For `no_std` environments, a global allocator may be limited, or not available at all. But dynamic dispatch may still be desired.

# Solution

This crate provides an attribute macro for generating an enum type that contains a finite set of concrete types.

Each variant of the enum corresponds to a type, in the form of a tuple variant.

Rust enums occupy as much space as the largest variant:

```rust
enum MultipleTypes {
A(A),
B(B),
C(C),
D(D)
}
```

Memory:

```
|# <- A
|### <- B
|## <- C
|##### <- D
##|##### < Total size
^
|
padding/tag
```

# Usage
## Basic

To create a bundle, simply mark an enum as a such:

```rust
trait Foo {
fn bar(&self) -> u8;
}

#[bundle]
enum MyBundle {
FirstType,
SecondType,
ThirdType
}
```

Now you can invoke methods defined by the shared trait:

```rust
impl Foo for FirstType {
fn bar(&self) -> u8 {
0
}
}

impl Foo for SecondType {
fn bar(&self) -> u8 {
1
}
}

impl Foo for ThirdType {
fn bar(&self) -> u8 {
2
}
}

let bundle: MyBundle = { /* fetch bundle from somewhere... */ }

let bar = use_my_bundle!(bundle, |inner| { inner.bar() }); // will be 0, 1, or 2 depending on what's in the bundle
```

## Other macros

Bundles can still be used with other macros as long as the bundle is the first one executed.

For example, use with `derive` where types `A`, `B` and `C` implement `Clone`:

```rust
#[bundle] // this goes first so derive sees the transformed enum
#[derive(Clone)]
enum MyBundle {
A,
B,
C,
}
```

## Generics

If generics are required for your bundle, you can add them like so:

```rust
#[bundle]
enum MyBundle {
A(A), // notice you must now create the tuple variant yourself
B,
C(C),
}
```

# Design Considerations

## Safety

The `#[bundle]` macro cannot generate unsafe code.