๐ŸŽ‰ Announcing **anymap-serde** โ€” a serde-friendly heterogeneous container for Rust

โš“ Rust    ๐Ÿ“… 2025-11-28    ๐Ÿ‘ค surdeus    ๐Ÿ‘๏ธ 2      

surdeus

Hello Rustaceans,

Iโ€™m excited to share a new crate Iโ€™ve been working on: anymap-serde! Itโ€™s now available on GitHub (and crates.io: Rust Package Registry), and provides a serde-powered alternative to classic type-indexed โ€œanymapโ€ containers.

:light_bulb: What it is

  • Type-indexed heterogeneous map โ€” you can store exactly one value per type, and retrieve it by its type.
  • Serde-compatible โ€” an anymap-serde container can be serialized and deserialzed under the hood using serde. That enables you to serialize / deserialize the entire map of heterogenous values to/from JSON, TOML, or other formats supported by Serde.
  • Ergonomic API โ€” almost identical mental model to the โ€œanymapโ€ crate, but exposes deserialization errors where it makes sense.

:white_check_mark: Typical usage

use anymap_serde::SerializableAnyMap;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct Config { /* โ€ฆ */ }

#[derive(Serialize, Deserialize, Debug)]
struct Stats { /* โ€ฆ */ }

let mut bag = SerializableAnyMap::new();
bag.insert(Config { /* โ€ฆ */ });
bag.insert(Stats { /* โ€ฆ */ });

// You can serialize the bag:
let s = serde_json::to_string(&bag)?;
// Later deserialize:
let bag2: SerializableAnyMap = serde_json::from_str(&s)?;

// And retrieve typed data:
let cfg = bag2.get::<Config>().unwrap();
let stats = bag2.get::<Stats>().unwrap();

This makes anymap-serde ideal for use-cases like: configuration stores, plugin-state bags, context/extension objects, or any scenario where you want a type-safe, heterogenous โ€œbagโ€ of data โ€” and want to persist or transmit it.

:information_source: Caveats / What to watch out for

  • Stored types must implement Serialize + Deserialize + 'static.
  • Because data is serialized internally, renaming types or changing their structure may break deserialization.
  • At deserialization time, you need to know what types you expect to extract; missing types will simply return None.
  • Serialization happens on insert, and all modifications of values using .get_mut(). This is a significant case that is not fit for hot-paths.
  • Deserialization of values is lazy (and cannot be made eager) - it happens on first access of the values where type information of T is available.

:rocket: Status & how to try it out

If you've ever needed an โ€œanymap + serdeโ€ without wrestling with manual serialization, or a flexible context store with type safety and persistability โ€” please give anymap-serde a spin and let me know what you think! Iโ€™m especially curious about real-world use cases, edge-cases with nested data, and any feedback about ergonomics.

Thanks for reading, and happy Rusting! :crab:

2 posts - 2 participants

Read full topic

๐Ÿท๏ธ Rust_feed