serde-mappable-seq 0.1.0

Unnoficial third-party serde (de)serializers for mappable sequences
Documentation
//! [![license-badge][]][license] [![docs-badge][]][docs] [![rust badge]][rust link]
//!
//! # serde-mappable-seq
//!
//! An unofficial third-party crate to deserialize sequences of keyed structs
//! into HashMaps or BTreeMaps and vice versa.
//!
//! Sometimes APIs will provide a list of instances of a resource in a sequence,
//! such as a list of users. Imagine this JSON payload:
//!
//! ```json
//! {
//!   "data": {
//!     "users": [
//!       {
//!         "id": 1,
//!         "name": "foo"
//!       }
//!     ]
//!   },
//!   "links": {}
//! }
//! ```
//!
//! If you want to get something by ID, you're going to either need to
//! post-process it manually (slightly annoying) or loop through to find the user
//! with the ID (slightly costly).
//!
//! `serde-mappable-seq` makes turning a sequence of a resource into a keyed
//! map easy.
//!
//! ### Installation
//!
//! This library requires at least Rust 1.31.0.
//!
//! Add this to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! serde-mappable-seq = "0.1"
//! ```
//!
//! ### Examples
//!
//! Deserialize a struct containing a sequence of 2 users into a HashMap, keyed
//! by their IDs:
//!
//! ```
//! use serde_derive::{Deserialize, Serialize};
//! use serde_mappable_seq::Key;
//! use std::collections::HashMap;
//!
//! #[derive(Deserialize, Serialize)]
//! struct User {
//!     id: u64,
//!     name: String,
//! }
//!
//! impl Key<'_, u64> for User {
//!     fn key(&self) -> u64 {
//!         self.id
//!     }
//! }
//!
//! #[derive(Deserialize, Serialize)]
//! struct Response {
//!     #[serde(with = "serde_mappable_seq")]
//!     users: HashMap<u64, User>,
//! }
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let input = r#"{
//!   "users": [
//!     {
//!       "id": 1,
//!       "name": "foo"
//!     }
//!   ]
//! }"#;
//!
//! let response = serde_json::from_str::<Response>(input)?;
//! assert_eq!("foo", response.users.get(&1).unwrap().name);
//!
//! // Now serialize it back and make sure it's the same as the original input.
//! assert_eq!(input, serde_json::to_string_pretty(&response)?);
//! # Ok(()) }
//! ```
//!
//! Serializing the instance of the response struct in the above example will
//! net back the original input.
//!
//! ### License
//!
//! ISC.
//!
//! [docs]: https://docs.rs/serde-mappable-seq
//! [docs-badge]: https://img.shields.io/badge/docs-online-5023dd.svg?style=flat-square
//! [license]: https://opensource.org/licenses/ISC
//! [license-badge]: https://img.shields.io/badge/license-ISC-blue.svg?style=flat-square
//! [rust badge]: https://img.shields.io/badge/rust-1.31+-93450a.svg?style=flat-square
//! [rust link]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html

pub mod btreemap;
pub mod hashmap;

pub use self::hashmap::{deserialize, serialize};

use serde::{Deserialize, Serialize};
use std::hash::Hash;

/// The key to a keyed resource.
///
/// Implement this on the type of the value of a map to extract the key from it.
///
/// # Examples
///
/// If you have a User resource, then it'll have an ID of some sort. For
/// example, return the integer ID of a User struct:
///
/// ```
/// use serde_derive::{Deserialize, Serialize};
/// use serde_mappable_seq::Key;
///
/// struct User {
///     id: u64,
///     email: String,
///     name: String,
/// }
///
/// impl Key<'_, u64> for User {
///     fn key(&self) -> u64 {
///         self.id
///     }
/// }
/// ```
pub trait Key<'a, T: Deserialize<'a> + Eq + Hash + Serialize> {
    /// The method to extract an owned key from the type.
    fn key(&self) -> T;
}