The typed-index-collections
crate provides
typed index version of the Rust [slice
] and [std::vec::Vec
] types.
When dealing with slices and vectors it is not safe to index all arrays
with type-unsafe usizes as indices.
Using slice and vector indexing might be useful in Data Oriented Design,
when using Struct of Arrays, or when Rc
and Weak
usage is undesirable.
This crate provides typed index version of [slice
] and [std::vec::Vec
]
types with custom index type.
Containers only require the index to implement [Index
] trait.
If default feature impl-index-from
is enabled, this trait is automatically implemented
when [From<usize>
] and [Into<usize>
] are implemented.
And their implementation can be easily done
with [derive_more
] crate and #[derive(From, Into)]
.
The [TiSlice
] and [TiVec
] structs are only wrappers
around Rust [slice
] and [std::vec::Vec
] structs with custom index type
and exposed raw
property with original struct.
They can be easily converted to matched Rust containers using [From
] and [Into
] traits.
The structs mirrors the stable API of Rust [slice
] and [std::vec::Vec
]
and forwards to it as much as possible.
First, add the following to your Cargo.toml
:
toml
[dependencies]
typed-index-collections = "0.0.1"
This crate depends on the standard library by default that is useful
for debugging and for some extra functionality.
To use this crate in a #![no_std]
context, use default-features = false
in your Cargo.toml
as shown below:
toml
[dependencies.typed-index-collections]
version = "0.0.1"
default-features = false
features = ["alloc", "impl-index-from"]
If you want to use [derive_more
] for [From<usize>
] and [Into<usize>
] implementation
add it to your Cargo.toml
as shown below:
toml
[dependencies]
derive_more = "0.99"
typed-index-collections = "0.0.1"
Simple example with [derive_more
]:
```rust
use typedindexcollections::TiVec;
use derive_more::{From, Into};
struct FooId(usize);
let mut foos: TiVec
Another example with [derive_more
]:
```rust
use typedindexcollections::{TiSlice, TiVec};
use derive_more::{From, Into};
struct FooId(usize);
struct BarId(usize);
struct Foo { value: usize, }
let first = Foo { value: 1 }; let second = Foo { value: 2 };
let sliceref = &[first, second][..]; let vec = std::vec![first, second]; let boxedslice = std::vec![first, second].intoboxedslice();
let typedindexsliceref: &TiSlice
asserteq!(typedindexvec[FooId(1)], second); asserteq!(typedindexvec.raw[1], second); asserteq!(typedindexvec.last(), Some(&second)); asserteq!(typedindexvec.lastkeyvalue(), Some((FooId(1), &second))); asserteq!( typedindexvec.iterenumerated().next(), Some((FooId(0), &first)) ); // assert_eq!(vec[BarId(1)], second); // won't compile with incompable index
let sliceref: &[Foo] = typedindexsliceref.into();
let _vec: std::vec::Vec
[API Documentation]
impl-index-from
(enabled by default) — Enables automatic [FromIndex
] and [IntoIndex
]
trait implementation for types that implement [From<usize>
] and [Into<usize>
].alloc
(enabled by default) — Enables types and functions
which require memory allocation.std
(enabled by default) — Enables all std
features
such as memory allocations and std::error::Error
trait.serde
— Implements Serialize
and Deserialize
traits for slice type.serde-alloc
— Enable alloc
and serde/alloc
features.serde-std
— Enable std
and serde/std
features.typed_index_collection
] provides a Vec
wrapper with a very limited API.
Indices are u32 wrappers,
they are not customizable and can only index a specific type of container.indexed_vec
] is the closest copy of the IndexVec
struct from librustc_index
,
but API is also different from standard Rust [std::vec::Vec
]
and it has no typed index [slice
] alternative.index_vec
] have both [slice
] and [std::vec::Vec
] wrapper
and API closer to standard API.
But it implicitly allows you to use usize
for get methods and index expressions
that reduce type-safety,
and the macro define_index_type!
which is used to generate a newtyped index struct,
implicitly implements a lot of traits that would be better implemented
only when necessary using crates intended for this, such as [derive_more
].Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.