1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! [![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 use ;
use ;
use 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
/// }
/// }
/// ```