The crate is a collection of typed data structures, trait operators and useful type aliases for Rust. It was introduced to support tch-typed-tensor project, which provides compile-time checked tensor type.
It reduces runtime computation to minimum by design. The DSTs are manipulated by trait operators. That is, with Rust's associated types and generics, we can build non-trivial types like lists and key-value map.
So far, the crate ships following features. It's still in alpha stage and I'm glad for contributions!
std::optoin::Option
.If
, used to build compile-time guards.It's not published on crates.io yet. To give it a try, put this on your Cargo.toml
.
toml
type-freak = { git = "https://github.com/jerry73204/rust-type-freak.git", branch = "master" }
To assert one typed integer is less than the other typed integer:
```rust use typenum::consts::*; use type_freak::control::IfLessOutput;
type Out1 = IfLessOutput
fn assert() { let _: Out1 = 0; // Goes fine here. let _: Out2 = 0; // Compile error!!! } ```
We can make sure two generic parameters are of the same type by IfSame
trait bound.
```rust use type_freak::control::IfSame;
fn guardedfunction
fn comileme() {
let _ = guardedfunction::
The TList
type represents a list of arbitrary types. It can be constructed
by TListType!
macro. The crate ships a variety of traits as type operators to
manipuate the list structure.
```rust use type_freak::{TListType, list::*};
type List1 = TListType! {u8, u16, u32};
type List2 = LPrependOutput
type List3
type List4
type List5
Option
The Maybe
is analogous to std's Option
.
```rust use typenum::consts::*; use type_freak::maybe::{Maybe, Just, Nothing, UnwrapOutput, UnwrapOrOutput};
type Opt1 = Just
type Val1 = UnwrapOutput
The Counter
traits along with Next
and Current
types are handly
tools to build recursive type operators. The following demo implements
an trait that removes a specific type from TList
.
The example works by a termination step and recursive step, corresponding
to to impl blocks. Note that the Index
argument is necessary to let compiler
distinguish the signatures of two impl blocks. Otherwise, the compiler will
complain about conflicting implementations.
```rust use type_freak::{ list::{TList, LCons, LNil}, counter::{Counter, Current, Next}, };
/* Definition */
pub trait LRemoveAt
// termination step
impl
// recursion step
impl
/* Auto-inference example */
// Here SomeList is equivalent to TListType! {u8, u32}
type SomeList
// The Index argument can be inferred by compiler fn auto_inference() { let _ = SomeList::<_>::new(); } ```
The project licensed under MIT or Apache 2.0. Pick the one that suits you.