Maplike - Crate with traits for abstract containers and operations on them
โ Rust ๐ 2026-07-06 ๐ค surdeus ๐๏ธ 1Hello!
I would like to share my crate, maplike. Maplike provides traits for common operations, .get(), .set(), .insert(), .remove(), .push(), .pop(), .into_iter() etc., over container data structures, such as std's Vec, BTreeMap, BTreeSet, HashMap, HashSet and for multiple third-party types, e.g. stable_vec::StableVec, thunderdome::Arena, tinyvec::ArrayVec, tinyvec::TinyVec.
I developed this library for myself to make it possible to write code that is generic over different collection-like data types. These types all have considerable similarities between their interfaces, but I couldn't find a suitable library with traits to abstract the shared behavior that I needed, so I rolled my own.
Basically, this is Python's collections.abc, but in Rust, and with traits not only for different kinds of containers, but also for each operation.
I maintain this library and dogfood it in my other two crates:
- undoredo: Undo/Redo and non-linear history tree using sparse deltas (diffs), snapshots, or commands on arbitrary data structures.
- dcel: half-edge data structure that is generic over its containers.
Feedback is welcome!
Below are two code examples taken from the readme:
First example. Function that gets the second element of a collection that is generic over `Vec`, array, BTreeMap:
use std::collections::BTreeMap;
use maplike::Get;
// Generic over any collection implementing the `Get` trait.
fn get_second_element<C: Get<usize>>(collection: &C) -> Option<&C::Value> {
collection.get(&1)
}
// `get_second_element()` works for `Vec`s, arrays, and maps with the very
// same code.
assert_eq!(get_second_element(&vec![10, 20, 30]), Some(&20));
assert_eq!(get_second_element(&[10, 20, 30]), Some(&20));
assert_eq!(get_second_element(&BTreeMap::from([(0, 10), (1, 20)])), Some(&20));use std::collections::BTreeMap;
Second example. Code that is generic over `Vec`, `tinyvec::ArrayVec`, `tinyvec::TinyVec`:
use maplike::{Clear, Push, Veclike};
use tinyvec::{ArrayVec, TinyVec};
// This function is generic over any `Veclike` collection. The `Veclike` bound
// provides `.clear()`, `.push()` and many other methods at once.
fn replace_all<C: Veclike<usize, Value = i32>>(collection: &mut C, values: &[i32]) {
collection.clear();
for &value in values {
collection.push(value);
}
}
// `replace_all()` now works for any `Veclike` collection.
// Works on `Vec`,
let mut vec = Vec::new();
replace_all(&mut vec, &[1, 2, 3]);
assert_eq!(vec, [1, 2, 3]);
replace_all(&mut vec, &[4, 5, 6]);
assert_eq!(vec, [4, 5, 6]);
// Works on `tinyvec::ArrayVec`.
let mut array_vec: ArrayVec<[i32; 8]> = ArrayVec::new();
replace_all(&mut array_vec, &[7, 8, 9]);
assert_eq!(array_vec.as_slice(), [7, 8, 9]);
// Works on `tinyvec::TinyVec`.
let mut tiny_vec: TinyVec<[i32; 8]> = TinyVec::new();
replace_all(&mut tiny_vec, &[10, 11, 12]);
assert_eq!(tiny_vec.as_slice(), [10, 11, 12]);use maplike::{Clear, Push, Veclike};
2 posts - 2 participants
๐ท๏ธ Rust_feed