Maplike - Crate with traits for abstract containers and operations on them

โš“ Rust    ๐Ÿ“… 2026-07-06    ๐Ÿ‘ค surdeus    ๐Ÿ‘๏ธ 1      

surdeus

Hello!

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.

Link: GitHub - mikwielgus/maplike: Traits for abstract containers and operations over them for std and external crates. ยท GitHub

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

Read full topic

๐Ÿท๏ธ Rust_feed