All Projects → LNP-BP → rust-amplify

LNP-BP / rust-amplify

Licence: MIT license
Amplifying Rust language capabilities: multiple generic trait implementations, type wrappers, bit-precise numerics, derive macros

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to rust-amplify

Staticvec
Implements a fixed-capacity stack-allocated Vec alternative backed by an array, using const generics.
Stars: ✭ 236 (+521.05%)
Mutual labels:  generics, no-std
go-generics
Go的泛型文档、代码、讨论
Stars: ✭ 43 (+13.16%)
Mutual labels:  generics
Goreuse
Generic Code for Go
Stars: ✭ 93 (+144.74%)
Mutual labels:  generics
Auth Adt
Authenticated Data Structures Generically
Stars: ✭ 150 (+294.74%)
Mutual labels:  generics
Promis
The easiest Future and Promises framework in Swift. No magic. No boilerplate.
Stars: ✭ 110 (+189.47%)
Mutual labels:  generics
Syncmap
A typed implementation of the Go sync.Map using code generation
Stars: ✭ 200 (+426.32%)
Mutual labels:  generics
Swift Complex
Complex numbers in Swift
Stars: ✭ 66 (+73.68%)
Mutual labels:  generics
stm32f103xx
DEPRECATED
Stars: ✭ 31 (-18.42%)
Mutual labels:  no-std
Gengen
A Go source transformation tool for generics
Stars: ✭ 253 (+565.79%)
Mutual labels:  generics
Go generics
Templates, generics engine for Go
Stars: ✭ 141 (+271.05%)
Mutual labels:  generics
Gomacro
Interactive Go interpreter and debugger with REPL, Eval, generics and Lisp-like macros
Stars: ✭ 1,784 (+4594.74%)
Mutual labels:  generics
Ply
Painless polymorphism
Stars: ✭ 117 (+207.89%)
Mutual labels:  generics
Envy
😠 Environmentally friendly environment variables
Stars: ✭ 132 (+247.37%)
Mutual labels:  generics
Miniboxing Plugin
Miniboxing is a program transformation that improves the performance of Scala generics when used with primitive types. It can speed up generic collections by factors between 1.5x and 22x, while maintaining bytecode duplication to a minimum. You can easily add miniboxing to your sbt project:
Stars: ✭ 106 (+178.95%)
Mutual labels:  generics
lancet
A comprehensive, efficient, and reusable util function library of go.
Stars: ✭ 2,228 (+5763.16%)
Mutual labels:  generics
Gen
Type-driven code generation for Go
Stars: ✭ 1,246 (+3178.95%)
Mutual labels:  generics
Higgledy
Higher-kinded data via generics
Stars: ✭ 153 (+302.63%)
Mutual labels:  generics
go-ringbuf
Lock-free MPMC Ring Buffer (Generic) for SMP, in golang. Some posts in chinese:
Stars: ✭ 43 (+13.16%)
Mutual labels:  generics
mfrc522
A platform agnostic driver to interface the MFRC522 (RFID reader/writer)
Stars: ✭ 27 (-28.95%)
Mutual labels:  no-std
Arrow Meta
Functional companion to Kotlin's Compiler
Stars: ✭ 246 (+547.37%)
Mutual labels:  generics

Rust Amplify Library

Build Tests Lints codecov

crates.io Docs unsafe forbidden MIT licensed

Amplifying Rust language capabilities: multiple generic trait implementations, type wrappers, derive macros. Tiny library with zero non-optional dependencies. Able to work as no_std.

Minimum supported rust compiler version (MSRV): 1.60.0; rust edition 2021.

Main features

Generics

Library proposes generic implementation strategies, which allow multiple generic trait implementations.

Implementing trait for a generic type ("blanket implementation") more than once (applies both for local and foreign traits) - or implement foreign trait for a concrete type where there is some blanket implementation in the upstream. The solution is to use special pattern by @Kixunil. I use it widely and have a special helper type in src/strategy.rssrc/strategy.rs module.

With that helper type you can write the following code, which will provide you with efficiently multiple blanket implementations of some trait SampleTrait:

pub trait SampleTrait {
    fn sample_trait_method(&self);
}

// Define strategies, one per specific implementation that you need,
// either blanket or concrete
pub struct StrategyA;
pub struct StrategyB;
pub struct StrategyC;

// Define a single marker type
pub trait Strategy {
    type Strategy;
}

// Do a single blanket implementation using Holder and Strategy marker trait
impl<T> SampleTrait for T
where
    T: Strategy + Clone,
    amplify::Holder<T, <T as Strategy>::Strategy>: SampleTrait,
{
    // Do this for each of sample trait methods:
    fn sample_trait_method(&self) {
        amplify::Holder::new(self.clone()).sample_trait_method()
    }
}

// Do this type of implementation for each of the strategies
impl<T> SampleTrait for amplify::Holder<T, StrategyA>
where
    T: Strategy,
{
    fn sample_trait_method(&self) {
        /* ... write your implementation-specific code here */
    }
}

# pub struct ConcreteTypeA;
// Finally, apply specific implementation strategy to a concrete type
// (or do it in a blanket generic way) as a marker:
impl Strategy for ConcreteTypeA {
    type Strategy = StrategyA;
}

Derive macros

  • Display
  • From
  • Error
  • Getters
  • AsAny
  • Wrapper

A sample of what can be done with the macros:

#[derive(From, Error, Display, Debug)]
#[display(doc_comments)]
pub enum Error {
    // You can specify multiple conversions with separate attributes
    #[from(::std::io::Error)]
    #[from(IoError)]
    /// Generic I/O error
    Io,

    #[from]
    // This produces error description referencing debug representation
    // of the internal error type
    /// Formatting error: {_0:}
    Format(::std::fmt::Error),

    #[from]
    /// Some complex error, here are details: {details}
    WithFields { details: ::std::str::Utf8Error },

    #[display(LowerHex)]
    MultipleFields {
        // ...and you can also covert error type
        #[from(IoErrorUnit)]
        // rest of parameters must implement `Default`
        io: IoError,

        #[display(ToHex::to_hex)]
        details: String,
    },
}

More information is given in amplify_derive crate README.

Macros

  • none! as an alias for Default::default() on collection types and types for which semantics makes it sensible to emphasize that the operation initializes empty structure.
  • s! for fast &str -> String conversions
  • Collection-generating macros:
    • map! & bmap! for a rappid HashMap and BTreeMap creation
    • set! & bset! for a rappid HashSet and BTreeSet creation
    • list! for LinkedList

Wapper type

Wrapper trait helps in creating wrapped rust newtypes, Wrapped types are used for allowing implemeting foreign traits to foreign types: https://doc.rust-lang.org/stable/rust-by-example/generics/new_types.html

Trait defines convenient methods for accessing inner data, construct and deconstruct newtype. It also serves as a marker trait for newtypes.

The trait works well with #[derive(Wrapper)] from amplify_derive crate

Build

cargo build --all
cargo test

As a reminder, minimum supported rust compiler version (MSRV) is 1.36.0, so it can be build with either nightly, dev, stable or 1.36+ version of the rust compiler. Use rustup for getting the proper version, or add +toolchain parameter to both cargo build and cargo test commands.

Benchmark

RUSTFLAGS="--cfg bench" cargo bench
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].