[−][src]Crate typed_index_collections
The typed-index-collections
crate provides TiSlice
and TiVec
structs
that are typed index versions of the Rust slice
and std::vec::Vec
types.
Introduction
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.
About
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.
Usage
First, add the following to your Cargo.toml
:
[dependencies]
typed-index-collections = "0.1.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:
[dependencies.typed-index-collections]
version = "0.1.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:
[dependencies]
derive_more = "0.99"
typed-index-collections = "0.1.1"
Examples
Simple example with derive_more
:
use typed_index_collections::TiVec; use derive_more::{From, Into}; #[derive(From, Into)] struct FooId(usize); let mut foos: TiVec<FooId, usize> = std::vec![10, 11, 13].into(); foos.insert(FooId(2), 12); assert_eq!(foos[FooId(2)], 12);
Another example with derive_more
:
use typed_index_collections::{TiSlice, TiVec}; use derive_more::{From, Into}; #[derive(Clone, Copy, Debug, From, Into, Eq, PartialEq)] struct FooId(usize); #[derive(Clone, Copy, Debug, From, Into, Eq, PartialEq)] struct BarId(usize); #[derive(Clone, Copy, Debug, Eq, PartialEq)] struct Foo { value: usize, } let first = Foo { value: 1 }; let second = Foo { value: 2 }; let slice_ref = &[first, second][..]; let vec = std::vec![first, second]; let boxed_slice = std::vec![first, second].into_boxed_slice(); let typed_index_slice_ref: &TiSlice<FooId, Foo> = slice_ref.into(); let typed_index_vec: TiVec<FooId, Foo> = vec.into(); let typed_index_boxed_slice: std::boxed::Box<TiSlice<FooId, Foo>> = boxed_slice.into(); assert_eq!(typed_index_vec[FooId(1)], second); assert_eq!(typed_index_vec.raw[1], second); assert_eq!(typed_index_vec.last(), Some(&second)); assert_eq!(typed_index_vec.last_key_value(), Some((FooId(1), &second))); assert_eq!( typed_index_vec.iter_enumerated().next(), Some((FooId(0), &first)) ); // assert_eq!(vec[BarId(1)], second); // won't compile with incompable index let _slice_ref: &[Foo] = typed_index_slice_ref.into(); let _vec: std::vec::Vec<Foo> = typed_index_vec.into(); let _boxed_slice: std::boxed::Box<[Foo]> = typed_index_boxed_slice.into();
Feature Flags
impl-index-from
(enabled by default) — Enables automaticIndex
trait implementation for types that implementFrom<usize>
andInto<usize>
.alloc
(enabled by default) — Enables types and functions which require memory allocation.std
(enabled by default) — Enables allstd
features such as memory allocations andstd::error::Error
trait.serde
— ImplementsSerialize
andDeserialize
traits for slice type.serde-alloc
— Enablealloc
andserde/alloc
features.serde-std
— Enablestd
andserde/std
features.
Similar crates
typed_index_collection
provides aVec
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 theIndexVec
struct fromlibrustc_index
, but API is also different from standard Ruststd::vec::Vec
and it has no typed indexslice
alternative.index_vec
have bothslice
andstd::vec::Vec
wrapper and API closer to standard API. But it implicitly allows you to useusize
for get methods and index expressions that reduce type-safety, and the macrodefine_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 asderive_more
.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Contribution
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.
Structs
TiSlice | A dynamically-sized view into a contiguous sequence of |
TiVec | A contiguous growable array type
that only accepts keys of the type |
Traits
Index | |
TiRangeBounds | A helper trait used to convert typed index ranges to |
TiSliceIndex | A helper trait used for indexing operations. |
Type Definitions
TiEnumerated | An iterator over all key-value pairs. |
TiSliceKeys | An iterator over all keys. |
TiSliceMutMap | An iterator wrapper for iterators that yields |
TiSliceRefMap | An iterator wrapper for iterators that yields |