The typed-index-collections
crate provides [TiSlice
] and [TiVec
] structs
that are typed index versions 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 = "1.0"
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 = "1.0"
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 = "1.0"
Simple example with [derive_more
]:
```rust
use typedindexcollections::TiVec;
use derive_more::{From, Into};
struct FooId(usize);
let mut tivec: TiVec
If a wrong index type is used, compilation will fail: ```rust use typedindexcollections::TiVec; use derive_more::{From, Into};
struct FooId(usize);
struct BarId(usize);
let mut ti_vec: TiVec
tivec.insert(BarId(2), 12);
// ^^^^^^^^ expected struct FooId
, found struct BarId
asserteq!(ti_vec[BarId(2)], 12);
// ^^^^^^^^^^^^^^^^ the trait ... is not implemented for main::BarId
```
Another more detailed example with [derive_more
]:
```rust
use typedindexcollections::{TiSlice, TiVec};
use derive_more::{From, Into};
struct FooId(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 tisliceref: &TiSlice
asserteq!(tivec[FooId(1)], second); asserteq!(tivec.raw[1], second); asserteq!(tivec.last(), Some(&second)); asserteq!(tivec.lastkeyvalue(), Some((FooId(1), &second))); asserteq!(tivec.iter_enumerated().next(), Some((FooId(0), &first)));
let sliceref: &[Foo] = tisliceref.into();
let vec: std::vec::Vec
[API Documentation]
impl-index-from
(enabled by default) — Enables automatic [Index
]
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 in my opinion 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.