summaryrefslogtreecommitdiff
path: root/vendor/multimap
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
committermo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
commit8cdfa445d6629ffef4cb84967ff7017654045bc2 (patch)
tree22f0b0907c024c78d26a731e2e1f5219407d8102 /vendor/multimap
parent4351c74c7c5f97156bc94d3a8549b9940ac80e3f (diff)
chore: add vendor directory
Diffstat (limited to 'vendor/multimap')
-rw-r--r--vendor/multimap/.cargo-checksum.json1
-rw-r--r--vendor/multimap/Cargo.lock75
-rw-r--r--vendor/multimap/Cargo.toml46
-rw-r--r--vendor/multimap/LICENSE-APACHE201
-rw-r--r--vendor/multimap/LICENSE-MIT25
-rw-r--r--vendor/multimap/README.md86
-rw-r--r--vendor/multimap/src/entry.rs127
-rw-r--r--vendor/multimap/src/lib.rs1650
-rw-r--r--vendor/multimap/src/serde.rs149
9 files changed, 2360 insertions, 0 deletions
diff --git a/vendor/multimap/.cargo-checksum.json b/vendor/multimap/.cargo-checksum.json
new file mode 100644
index 00000000..49d9944c
--- /dev/null
+++ b/vendor/multimap/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.lock":"2a77ea1e9eb835d7bcb2fbc623ebb8e3007636924f0c0294fb86b4c39232e019","Cargo.toml":"0c3f4c3736c04ab1426d0bd64cc5de8bd895cf554e19497ed9072bae73b0be7a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23ce717d2face34a1ae9af6a8c8fbbf488875afee16374d7a10ce79d41e22f37","README.md":"e389f7a05574cf84bcab6080ce1e056be3d50e48b8388594d3d91c88a0975754","src/entry.rs":"f90f875b6a8e81bcdc42c68dec3b1ec375e79cdf5f4149254635597a5756dc31","src/lib.rs":"7d1c3417d7ebe2ecd85bf5a7870224890d497907c2f65913f35cb0601622d14a","src/serde.rs":"53f54bada221fdbfb038a3c49f004514258cb709a38c7e0b51eb3abaee8ba9eb"},"package":"1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"} \ No newline at end of file
diff --git a/vendor/multimap/Cargo.lock b/vendor/multimap/Cargo.lock
new file mode 100644
index 00000000..f848f605
--- /dev/null
+++ b/vendor/multimap/Cargo.lock
@@ -0,0 +1,75 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "multimap"
+version = "0.10.1"
+dependencies = [
+ "serde",
+ "serde_test",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.219"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.219"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_test"
+version = "1.0.177"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f901ee573cab6b3060453d2d5f0bae4e6d628c23c0a962ff9b5f1d7c8d4f1ed"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
diff --git a/vendor/multimap/Cargo.toml b/vendor/multimap/Cargo.toml
new file mode 100644
index 00000000..b4b8b906
--- /dev/null
+++ b/vendor/multimap/Cargo.toml
@@ -0,0 +1,46 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2015"
+name = "multimap"
+version = "0.10.1"
+authors = ["Håvar Nøvik <havar.novik@gmail.com>"]
+build = false
+exclude = [
+ ".github/**",
+ ".gitignore",
+]
+autolib = false
+autobins = false
+autoexamples = false
+autotests = false
+autobenches = false
+description = "A multimap implementation."
+documentation = "https://docs.rs/multimap"
+readme = "README.md"
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/havarnov/multimap"
+
+[features]
+default = ["serde_impl"]
+serde_impl = ["serde"]
+
+[lib]
+name = "multimap"
+path = "src/lib.rs"
+
+[dependencies.serde]
+version = "1.0"
+optional = true
+
+[dev-dependencies.serde_test]
+version = "1.0"
diff --git a/vendor/multimap/LICENSE-APACHE b/vendor/multimap/LICENSE-APACHE
new file mode 100644
index 00000000..16fe87b0
--- /dev/null
+++ b/vendor/multimap/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/vendor/multimap/LICENSE-MIT b/vendor/multimap/LICENSE-MIT
new file mode 100644
index 00000000..8b2dbea9
--- /dev/null
+++ b/vendor/multimap/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2016 multimap developers
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/vendor/multimap/README.md b/vendor/multimap/README.md
new file mode 100644
index 00000000..93e745c1
--- /dev/null
+++ b/vendor/multimap/README.md
@@ -0,0 +1,86 @@
+[![crates.io](https://img.shields.io/crates/v/multimap.svg)](https://crates.io/crates/multimap)
+[![docs.rs](https://docs.rs/multimap/badge.svg)](https://docs.rs/multimap)
+
+# Multimap implementation for Rust
+
+This is a multimap implementation for Rust. Implemented as a thin wrapper around
+`std::collections::HashMap`.
+
+## Example
+
+````rust
+extern crate multimap;
+
+use multimap::MultiMap;
+
+fn main () {
+ let mut map = MultiMap::new();
+
+ map.insert("key1", 42);
+ map.insert("key1", 1337);
+ map.insert("key2", 2332);
+
+ assert_eq!(map["key1"], 42);
+ assert_eq!(map.get("key1"), Some(&42));
+ assert_eq!(map.get_vec("key1"), Some(&vec![42, 1337]));
+}
+````
+
+## Changelog
+
+### 0.10.1
+
+* Fix docs for flat_iter #45
+* Clippy warnings
+
+### 0.10.0
+
+* Added `FromIterator<(K, Vec<V>)>` [#48](https://github.com/havarnov/multimap/pull/48).
+
+### 0.9.1
+
+* Fixes a bug where iteration would panic on empty (inner) vectors [#46](https://github.com/havarnov/multimap/issues/46).
+
+### 0.9.0
+
+* Added ```flat_iter``` and ```flat_iter_mut```
+* Fixed bug where ```get``` and ```get_mut``` could panic.
+
+### 0.8.3
+
+* `multimap!` macro fixes; allow trailing comma, naming hygiene and create with
+ enough capacity for all elements.
+
+### 0.8.2
+
+* Added ```#![forbid(unsafe_code)]```.
+
+### 0.8.1
+
+* Fixed wrong link to documentation in `Cargo.toml`.
+
+### 0.8.0
+
+* Added ```MultiMap::insert_many```.
+* Added ```MultiMap::insert_many_from_slice```.
+
+### 0.7.0
+
+* Added possibility to replace the default hasher for the underlying
+ ```HashMap```.
+* Fix build warning by removing an unnecessary ```mut```.
+
+## License
+
+Licensed under either of
+ * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
+ https://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license ([LICENSE-MIT](LICENSE-MIT) or
+ https://opensource.org/licenses/MIT)
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
diff --git a/vendor/multimap/src/entry.rs b/vendor/multimap/src/entry.rs
new file mode 100644
index 00000000..f5420491
--- /dev/null
+++ b/vendor/multimap/src/entry.rs
@@ -0,0 +1,127 @@
+// Copyright (c) 2016 multimap developers
+//
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. All files in the project carrying such notice may not be copied,
+// modified, or distributed except according to those terms.
+
+use std::collections::hash_map::OccupiedEntry as HashMapOccupiedEntry;
+use std::collections::hash_map::VacantEntry as HashMapVacantEntry;
+
+/// A view into a single occupied location in a MultiMap.
+pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
+ #[doc(hidden)]
+ pub inner: HashMapOccupiedEntry<'a, K, Vec<V>>,
+}
+
+/// A view into a single empty location in a MultiMap.
+pub struct VacantEntry<'a, K: 'a, V: 'a> {
+ #[doc(hidden)]
+ pub inner: HashMapVacantEntry<'a, K, Vec<V>>,
+}
+
+/// A view into a single location in a map, which may be vacant or occupied.
+pub enum Entry<'a, K: 'a, V: 'a> {
+ /// An occupied Entry.
+ Occupied(OccupiedEntry<'a, K, V>),
+
+ /// A vacant Entry.
+ Vacant(VacantEntry<'a, K, V>),
+}
+
+impl<'a, K: 'a, V: 'a> OccupiedEntry<'a, K, V> {
+ /// Gets a reference to the first item in value in the vector corresponding to entry.
+ ///
+ /// # Panics
+ ///
+ /// This method will panic if the key has zero values.
+ pub fn get(&self) -> &V {
+ self.inner.get().first().expect("no values in entry")
+ }
+
+ /// Gets a reference to the values (vector) corresponding to entry.
+ pub fn get_vec(&self) -> &Vec<V> {
+ self.inner.get()
+ }
+
+ /// Gets a mut reference to the first item in value in the vector corresponding to entry.
+ ///
+ /// # Panics
+ ///
+ /// This method will panic if the key has zero values.
+ pub fn get_mut(&mut self) -> &mut V {
+ self.inner
+ .get_mut()
+ .first_mut()
+ .expect("no values in entry")
+ }
+
+ /// Gets a mut reference to the values (vector) corresponding to entry.
+ pub fn get_vec_mut(&mut self) -> &mut Vec<V> {
+ self.inner.get_mut()
+ }
+
+ /// Converts the OccupiedEntry into a mutable reference to the first item in value in the entry
+ /// with a lifetime bound to the map itself
+ pub fn into_mut(self) -> &'a mut V {
+ &mut self.inner.into_mut()[0]
+ }
+
+ /// Converts the OccupiedEntry into a mutable reference to the values (vector) in the entry
+ /// with a lifetime bound to the map itself
+ pub fn into_vec_mut(self) -> &'a mut Vec<V> {
+ self.inner.into_mut()
+ }
+
+ /// Inserts a new value onto the vector of the entry.
+ pub fn insert(&mut self, value: V) {
+ self.get_vec_mut().push(value);
+ }
+
+ /// Extends the existing vector with the specified values.
+ pub fn insert_vec(&mut self, values: Vec<V>) {
+ self.get_vec_mut().extend(values);
+ }
+
+ /// Takes the values (vector) out of the entry, and returns it
+ pub fn remove(self) -> Vec<V> {
+ self.inner.remove()
+ }
+}
+
+impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
+ /// Sets the first value in the vector of the entry with the VacantEntry's key,
+ /// and returns a mutable reference to it.
+ pub fn insert(self, value: V) -> &'a mut V {
+ &mut self.inner.insert(vec![value])[0]
+ }
+
+ /// Sets values in the entry with the VacantEntry's key,
+ /// and returns a mutable reference to it.
+ pub fn insert_vec(self, values: Vec<V>) -> &'a mut Vec<V> {
+ self.inner.insert(values)
+ }
+}
+
+impl<'a, K: 'a, V: 'a> Entry<'a, K, V> {
+ /// Ensures a value is in the entry by inserting the default if empty, and returns
+ /// a mutable reference to the value in the entry. This will return a mutable reference to the
+ /// first value in the vector corresponding to the specified key.
+ pub fn or_insert(self, default: V) -> &'a mut V {
+ match self {
+ Entry::Occupied(entry) => entry.into_mut(),
+ Entry::Vacant(entry) => entry.insert(default),
+ }
+ }
+
+ /// Ensures a value is in the entry by inserting the default values if empty, and returns
+ /// a mutable reference to the values (the corresponding vector to the specified key) in
+ /// the entry.
+ pub fn or_insert_vec(self, defaults: Vec<V>) -> &'a mut Vec<V> {
+ match self {
+ Entry::Occupied(entry) => entry.into_vec_mut(),
+ Entry::Vacant(entry) => entry.insert_vec(defaults),
+ }
+ }
+}
diff --git a/vendor/multimap/src/lib.rs b/vendor/multimap/src/lib.rs
new file mode 100644
index 00000000..35d5952c
--- /dev/null
+++ b/vendor/multimap/src/lib.rs
@@ -0,0 +1,1650 @@
+#![forbid(unsafe_code)]
+// Copyright (c) 2016 multimap developers
+//
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. All files in the project carrying such notice may not be copied,
+// modified, or distributed except according to those terms.
+
+//! A map implementation which allows storing multiple values per key.
+//!
+//! The interface is roughly based on std::collections::HashMap, but is changed
+//! and extended to accomodate the multi-value use case. In fact, MultiMap is
+//! implemented mostly as a thin wrapper around std::collections::HashMap and
+//! stores its values as a std::Vec per key.
+//!
+//! Values are guaranteed to be in insertion order as long as not manually
+//! changed. Keys are not ordered. Multiple idential key-value-pairs can exist
+//! in the MultiMap. A key can exist in the MultiMap with no associated value.
+//!
+//! # Examples
+//!
+//! ```
+//! use multimap::MultiMap;
+//!
+//! // create a new MultiMap. An explicit type signature can be omitted because of the
+//! // type inference.
+//! let mut queries = MultiMap::new();
+//!
+//! // insert some queries.
+//! queries.insert("urls", "http://rust-lang.org");
+//! queries.insert("urls", "http://mozilla.org");
+//! queries.insert("urls", "http://wikipedia.org");
+//! queries.insert("id", "42");
+//! queries.insert("name", "roger");
+//!
+//! // check if there's any urls.
+//! println!("Are there any urls in the multimap? {:?}.",
+//! if queries.contains_key("urls") {"Yes"} else {"No"} );
+//!
+//! // get the first item in a key's vector.
+//! assert_eq!(queries.get("urls"), Some(&"http://rust-lang.org"));
+//!
+//! // get all the urls.
+//! assert_eq!(queries.get_vec("urls"),
+//! Some(&vec!["http://rust-lang.org", "http://mozilla.org", "http://wikipedia.org"]));
+//!
+//! // iterate over all keys and the first value in the key's vector.
+//! for (key, value) in queries.iter() {
+//! println!("key: {:?}, val: {:?}", key, value);
+//! }
+//!
+//! // iterate over all keys and the key's vector.
+//! for (key, values) in queries.iter_all() {
+//! println!("key: {:?}, values: {:?}", key, values);
+//! }
+//!
+//! // the different methods for getting value(s) from the multimap.
+//! let mut map = MultiMap::new();
+//!
+//! map.insert("key1", 42);
+//! map.insert("key1", 1337);
+//!
+//! assert_eq!(map["key1"], 42);
+//! assert_eq!(map.get("key1"), Some(&42));
+//! assert_eq!(map.get_vec("key1"), Some(&vec![42, 1337]));
+//! ```
+
+use std::borrow::Borrow;
+use std::collections::hash_map::{IntoIter, Keys, RandomState};
+use std::collections::HashMap;
+use std::fmt::{self, Debug};
+use std::hash::{BuildHasher, Hash};
+use std::iter::{FromIterator, IntoIterator, Iterator};
+use std::ops::Index;
+
+pub use std::collections::hash_map::Iter as IterAll;
+pub use std::collections::hash_map::IterMut as IterAllMut;
+
+pub use entry::{Entry, OccupiedEntry, VacantEntry};
+
+mod entry;
+
+#[cfg(feature = "serde_impl")]
+pub mod serde;
+
+#[derive(Clone)]
+pub struct MultiMap<K, V, S = RandomState> {
+ inner: HashMap<K, Vec<V>, S>,
+}
+
+impl<K, V> MultiMap<K, V>
+where
+ K: Eq + Hash,
+{
+ /// Creates an empty MultiMap
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map: MultiMap<&str, isize> = MultiMap::new();
+ /// ```
+ pub fn new() -> MultiMap<K, V> {
+ MultiMap {
+ inner: HashMap::new(),
+ }
+ }
+
+ /// Creates an empty multimap with the given initial capacity.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map: MultiMap<&str, isize> = MultiMap::with_capacity(20);
+ /// ```
+ pub fn with_capacity(capacity: usize) -> MultiMap<K, V> {
+ MultiMap {
+ inner: HashMap::with_capacity(capacity),
+ }
+ }
+}
+
+impl<K, V, S> MultiMap<K, V, S>
+where
+ K: Eq + Hash,
+ S: BuildHasher,
+{
+ /// Creates an empty MultiMap which will use the given hash builder to hash keys.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ /// use std::collections::hash_map::RandomState;
+ ///
+ /// let s = RandomState::new();
+ /// let mut map: MultiMap<&str, isize> = MultiMap::with_hasher(s);
+ /// ```
+ pub fn with_hasher(hash_builder: S) -> MultiMap<K, V, S> {
+ MultiMap {
+ inner: HashMap::with_hasher(hash_builder),
+ }
+ }
+
+ /// Creates an empty MultiMap with the given intial capacity and hash builder.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ /// use std::collections::hash_map::RandomState;
+ ///
+ /// let s = RandomState::new();
+ /// let mut map: MultiMap<&str, isize> = MultiMap::with_capacity_and_hasher(20, s);
+ /// ```
+ pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> MultiMap<K, V, S> {
+ MultiMap {
+ inner: HashMap::with_capacity_and_hasher(capacity, hash_builder),
+ }
+ }
+
+ /// Inserts a key-value pair into the multimap. If the key does exist in
+ /// the map then the value is pushed to that key's vector. If the key doesn't
+ /// exist in the map a new vector with the given value is inserted.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert("key", 42);
+ /// ```
+ pub fn insert(&mut self, k: K, v: V) {
+ match self.entry(k) {
+ Entry::Occupied(mut entry) => {
+ entry.get_vec_mut().push(v);
+ }
+ Entry::Vacant(entry) => {
+ entry.insert_vec(vec![v]);
+ }
+ }
+ }
+
+ /// Inserts multiple key-value pairs into the multimap. If the key does exist in
+ /// the map then the values are extended into that key's vector. If the key
+ /// doesn't exist in the map a new vector collected from the given values is inserted.
+ ///
+ /// This may be more efficient than inserting values independently.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::<&str, &usize>::new();
+ /// map.insert_many("key", &[42, 43]);
+ /// ```
+ pub fn insert_many<I: IntoIterator<Item = V>>(&mut self, k: K, v: I) {
+ match self.entry(k) {
+ Entry::Occupied(mut entry) => {
+ entry.get_vec_mut().extend(v);
+ }
+ Entry::Vacant(entry) => {
+ entry.insert_vec(v.into_iter().collect::<Vec<_>>());
+ }
+ }
+ }
+
+ /// Inserts multiple key-value pairs into the multimap. If the key does exist in
+ /// the map then the values are extended into that key's vector. If the key
+ /// doesn't exist in the map a new vector collected from the given values is inserted.
+ ///
+ /// This may be more efficient than inserting values independently.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::<&str, usize>::new();
+ /// map.insert_many_from_slice("key", &[42, 43]);
+ /// ```
+ pub fn insert_many_from_slice(&mut self, k: K, v: &[V])
+ where
+ V: Clone,
+ {
+ match self.entry(k) {
+ Entry::Occupied(mut entry) => {
+ entry.get_vec_mut().extend_from_slice(v);
+ }
+ Entry::Vacant(entry) => {
+ entry.insert_vec(v.to_vec());
+ }
+ }
+ }
+
+ /// Returns true if the map contains a value for the specified key.
+ ///
+ /// The key may be any borrowed form of the map's key type, but Hash and Eq
+ /// on the borrowed form must match those for the key type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1, 42);
+ /// assert_eq!(map.contains_key(&1), true);
+ /// assert_eq!(map.contains_key(&2), false);
+ /// ```
+ pub fn contains_key<Q>(&self, k: &Q) -> bool
+ where
+ K: Borrow<Q>,
+ Q: Eq + Hash + ?Sized,
+ {
+ self.inner.contains_key(k)
+ }
+
+ /// Returns the number of unique keys in the map.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1, 42);
+ /// map.insert(2, 1337);
+ /// map.insert(2, 31337);
+ /// assert_eq!(map.len(), 2);
+ /// ```
+ pub fn len(&self) -> usize {
+ self.inner.len()
+ }
+
+ /// Removes a key from the map, returning the vector of values at
+ /// the key if the key was previously in the map.
+ ///
+ /// The key may be any borrowed form of the map's key type, but Hash and Eq
+ /// on the borrowed form must match those for the key type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1, 42);
+ /// map.insert(1, 1337);
+ /// assert_eq!(map.remove(&1), Some(vec![42, 1337]));
+ /// assert_eq!(map.remove(&1), None);
+ /// ```
+ pub fn remove<Q>(&mut self, k: &Q) -> Option<Vec<V>>
+ where
+ K: Borrow<Q>,
+ Q: Eq + Hash + ?Sized,
+ {
+ self.inner.remove(k)
+ }
+
+ /// Returns a reference to the first item in the vector corresponding to
+ /// the key.
+ ///
+ /// The key may be any borrowed form of the map's key type, but Hash and Eq
+ /// on the borrowed form must match those for the key type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1, 42);
+ /// map.insert(1, 1337);
+ /// assert_eq!(map.get(&1), Some(&42));
+ /// ```
+ pub fn get<Q>(&self, k: &Q) -> Option<&V>
+ where
+ K: Borrow<Q>,
+ Q: Eq + Hash + ?Sized,
+ {
+ self.inner.get(k)?.first()
+ }
+
+ /// Returns a mutable reference to the first item in the vector corresponding to
+ /// the key.
+ ///
+ /// The key may be any borrowed form of the map's key type, but Hash and Eq
+ /// on the borrowed form must match those for the key type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1, 42);
+ /// map.insert(1, 1337);
+ /// if let Some(v) = map.get_mut(&1) {
+ /// *v = 99;
+ /// }
+ /// assert_eq!(map[&1], 99);
+ /// ```
+ pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
+ where
+ K: Borrow<Q>,
+ Q: Eq + Hash + ?Sized,
+ {
+ self.inner.get_mut(k)?.get_mut(0)
+ }
+
+ /// Returns a reference to the vector corresponding to the key.
+ ///
+ /// The key may be any borrowed form of the map's key type, but Hash and Eq
+ /// on the borrowed form must match those for the key type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1, 42);
+ /// map.insert(1, 1337);
+ /// assert_eq!(map.get_vec(&1), Some(&vec![42, 1337]));
+ /// ```
+ pub fn get_vec<Q>(&self, k: &Q) -> Option<&Vec<V>>
+ where
+ K: Borrow<Q>,
+ Q: Eq + Hash + ?Sized,
+ {
+ self.inner.get(k)
+ }
+
+ /// Returns a mutable reference to the vector corresponding to the key.
+ ///
+ /// The key may be any borrowed form of the map's key type, but Hash and Eq
+ /// on the borrowed form must match those for the key type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1, 42);
+ /// map.insert(1, 1337);
+ /// if let Some(v) = map.get_vec_mut(&1) {
+ /// (*v)[0] = 1991;
+ /// (*v)[1] = 2332;
+ /// }
+ /// assert_eq!(map.get_vec(&1), Some(&vec![1991, 2332]));
+ /// ```
+ pub fn get_vec_mut<Q>(&mut self, k: &Q) -> Option<&mut Vec<V>>
+ where
+ K: Borrow<Q>,
+ Q: Eq + Hash + ?Sized,
+ {
+ self.inner.get_mut(k)
+ }
+
+ /// Returns true if the key is multi-valued.
+ ///
+ /// The key may be any borrowed form of the map's key type, but Hash and Eq
+ /// on the borrowed form must match those for the key type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1, 42);
+ /// map.insert(1, 1337);
+ /// map.insert(2, 2332);
+ ///
+ /// assert_eq!(map.is_vec(&1), true); // key is multi-valued
+ /// assert_eq!(map.is_vec(&2), false); // key is single-valued
+ /// assert_eq!(map.is_vec(&3), false); // key not in map
+ /// ```
+ pub fn is_vec<Q>(&self, k: &Q) -> bool
+ where
+ K: Borrow<Q>,
+ Q: Eq + Hash + ?Sized,
+ {
+ match self.get_vec(k) {
+ Some(val) => val.len() > 1,
+ None => false,
+ }
+ }
+
+ /// Returns the number of elements the map can hold without reallocating.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let map: MultiMap<usize, usize> = MultiMap::new();
+ /// assert!(map.capacity() >= 0);
+ /// ```
+ pub fn capacity(&self) -> usize {
+ self.inner.capacity()
+ }
+
+ /// Returns true if the map contains no elements.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// assert!(map.is_empty());
+ /// map.insert(1,42);
+ /// assert!(!map.is_empty());
+ /// ```
+ pub fn is_empty(&self) -> bool {
+ self.inner.is_empty()
+ }
+
+ /// Clears the map, removing all key-value pairs.
+ /// Keeps the allocated memory for reuse.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1,42);
+ /// map.clear();
+ /// assert!(map.is_empty());
+ /// ```
+ pub fn clear(&mut self) {
+ self.inner.clear();
+ }
+
+ /// An iterator visiting all keys in arbitrary order.
+ /// Iterator element type is &'a K.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1,42);
+ /// map.insert(1,1337);
+ /// map.insert(2,1337);
+ /// map.insert(4,1991);
+ ///
+ /// let mut keys: Vec<_> = map.keys().collect();
+ /// keys.sort();
+ /// assert_eq!(keys, [&1, &2, &4]);
+ /// ```
+ pub fn keys(&'_ self) -> Keys<'_, K, Vec<V>> {
+ self.inner.keys()
+ }
+
+ /// An iterator visiting pairs of each key and its first value in arbitrary order.
+ /// The iterator returns
+ /// a reference to the key and the first element in the corresponding key's vector.
+ /// Iterator element type is (&'a K, &'a V).
+ ///
+ /// See [`flat_iter`](Self::flat_iter)
+ /// for visiting all key-value pairs,
+ /// or [`iter_all`](Self::iter_all)
+ /// for visiting each key and its vector of values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1,42);
+ /// map.insert(1,1337);
+ /// map.insert(3,2332);
+ /// map.insert(4,1991);
+ ///
+ /// let mut pairs: Vec<_> = map.iter().collect();
+ /// pairs.sort_by_key(|p| p.0);
+ /// assert_eq!(pairs, [(&1, &42), (&3, &2332), (&4, &1991)]);
+ /// ```
+ pub fn iter(&self) -> Iter<K, V> {
+ Iter {
+ inner: self.inner.iter(),
+ }
+ }
+
+ /// A mutable iterator visiting pairs of each key and its first value
+ /// in arbitrary order. The iterator returns
+ /// a reference to the key and a mutable reference to the first element in the
+ /// corresponding key's vector. Iterator element type is (&'a K, &'a mut V).
+ ///
+ /// See [`flat_iter_mut`](Self::flat_iter_mut)
+ /// for visiting all key-value pairs,
+ /// or [`iter_all_mut`](Self::iter_all_mut)
+ /// for visiting each key and its vector of values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1,42);
+ /// map.insert(1,1337);
+ /// map.insert(3,2332);
+ /// map.insert(4,1991);
+ ///
+ /// for (_, value) in map.iter_mut() {
+ /// *value *= *value;
+ /// }
+ ///
+ /// let mut pairs: Vec<_> = map.iter_mut().collect();
+ /// pairs.sort_by_key(|p| p.0);
+ /// assert_eq!(pairs, [(&1, &mut 1764), (&3, &mut 5438224), (&4, &mut 3964081)]);
+ /// ```
+ pub fn iter_mut(&mut self) -> IterMut<K, V> {
+ IterMut {
+ inner: self.inner.iter_mut(),
+ }
+ }
+
+ /// An iterator visiting all key-value pairs in arbitrary order. The iterator returns
+ /// a reference to the key and the corresponding key's vector.
+ /// Iterator element type is (&'a K, &'a V).
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1,42);
+ /// map.insert(1,1337);
+ /// map.insert(3,2332);
+ /// map.insert(4,1991);
+ ///
+ /// let mut pairs: Vec<_> = map.iter_all().collect();
+ /// pairs.sort_by_key(|p| p.0);
+ /// assert_eq!(pairs, [(&1, &vec![42, 1337]), (&3, &vec![2332]), (&4, &vec![1991])]);
+ /// ```
+ pub fn iter_all(&self) -> IterAll<K, Vec<V>> {
+ self.inner.iter()
+ }
+
+ /// An iterator visiting all key-value pairs in arbitrary order. The iterator returns
+ /// a reference to the key and the corresponding key's vector.
+ /// Iterator element type is (&'a K, &'a V).
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1,42);
+ /// map.insert(1,1337);
+ /// map.insert(3,2332);
+ /// map.insert(4,1991);
+ ///
+ /// for (key, values) in map.iter_all_mut() {
+ /// for value in values.iter_mut() {
+ /// *value = 99;
+ /// }
+ /// }
+ ///
+ /// let mut pairs: Vec<_> = map.iter_all_mut().collect();
+ /// pairs.sort_by_key(|p| p.0);
+ /// assert_eq!(pairs, [(&1, &mut vec![99, 99]), (&3, &mut vec![99]), (&4, &mut vec![99])]);
+ /// ```
+ pub fn iter_all_mut(&mut self) -> IterAllMut<K, Vec<V>> {
+ self.inner.iter_mut()
+ }
+
+ /// An iterator visiting all key-value pairs in arbitrary order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1,42);
+ /// map.insert(1,1337);
+ /// map.insert(3,2332);
+ /// map.insert(4,1991);
+ ///
+ /// let mut pairs: Vec<_> = map.flat_iter().collect();
+ /// pairs.sort();
+ /// assert_eq!(pairs, [(&1, &42), (&1, &1337), (&3, &2332), (&4, &1991)]);
+ /// ```
+ pub fn flat_iter(&self) -> impl Iterator<Item = (&K, &V)> {
+ self.iter_all()
+ .flat_map(|(k, v)| v.iter().map(move |i| (k, i)))
+ }
+
+ /// A mutable iterator visiting all key-value pairs in arbitrary order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut map = MultiMap::new();
+ /// map.insert(1,42);
+ /// map.insert(1,1337);
+ /// map.insert(3,2332);
+ /// map.insert(4,1991);
+ ///
+ /// for (key, value) in map.flat_iter_mut() {
+ /// *value *= key;
+ /// }
+ ///
+ /// let mut pairs: Vec<_> = map.flat_iter().collect();
+ /// pairs.sort();
+ /// assert_eq!(pairs, [(&1, &42), (&1, &1337), (&3, &6996), (&4, &7964)]);
+ /// ```
+ pub fn flat_iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
+ self.iter_all_mut()
+ .flat_map(|(k, v)| v.iter_mut().map(move |i| (k, i)))
+ }
+
+ /// Gets the specified key's corresponding entry in the map for in-place manipulation.
+ /// It's possible to both manipulate the vector and the 'value' (the first value in the
+ /// vector).
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut m = MultiMap::new();
+ /// m.insert(1, 42);
+ ///
+ /// {
+ /// let mut v = m.entry(1).or_insert(43);
+ /// assert_eq!(v, &42);
+ /// *v = 44;
+ /// }
+ /// assert_eq!(m.entry(2).or_insert(666), &666);
+ ///
+ /// {
+ /// let mut v = m.entry(1).or_insert_vec(vec![43]);
+ /// assert_eq!(v, &vec![44]);
+ /// v.push(50);
+ /// }
+ /// assert_eq!(m.entry(2).or_insert_vec(vec![667]), &vec![666]);
+ ///
+ /// assert_eq!(m.get_vec(&1), Some(&vec![44, 50]));
+ /// ```
+ pub fn entry(&mut self, k: K) -> Entry<K, V> {
+ use std::collections::hash_map::Entry as HashMapEntry;
+ match self.inner.entry(k) {
+ HashMapEntry::Occupied(entry) => Entry::Occupied(OccupiedEntry { inner: entry }),
+ HashMapEntry::Vacant(entry) => Entry::Vacant(VacantEntry { inner: entry }),
+ }
+ }
+
+ /// Retains only the elements specified by the predicate.
+ ///
+ /// In other words, remove all pairs `(k, v)` such that `f(&k,&mut v)` returns `false`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use multimap::MultiMap;
+ ///
+ /// let mut m = MultiMap::new();
+ /// m.insert(1, 42);
+ /// m.insert(1, 99);
+ /// m.insert(2, 42);
+ /// m.retain(|&k, &v| { k == 1 && v == 42 });
+ /// assert_eq!(1, m.len());
+ /// assert_eq!(Some(&42), m.get(&1));
+ /// ```
+ pub fn retain<F>(&mut self, mut f: F)
+ where
+ F: FnMut(&K, &V) -> bool,
+ {
+ for (key, vector) in &mut self.inner {
+ vector.retain(|value| f(key, value));
+ }
+ self.inner.retain(|_, v| !v.is_empty());
+ }
+}
+
+impl<K, V, S, Q> Index<&Q> for MultiMap<K, V, S>
+where
+ K: Eq + Hash + Borrow<Q>,
+ Q: Eq + Hash + ?Sized,
+ S: BuildHasher,
+{
+ type Output = V;
+
+ fn index(&self, index: &Q) -> &V {
+ self.inner
+ .get(index)
+ .expect("no entry found for key")
+ .first()
+ .expect("no value found for key")
+ }
+}
+
+impl<K, V, S> Debug for MultiMap<K, V, S>
+where
+ K: Eq + Hash + Debug,
+ V: Debug,
+ S: BuildHasher,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_map().entries(self.iter_all()).finish()
+ }
+}
+
+impl<K, V, S> PartialEq for MultiMap<K, V, S>
+where
+ K: Eq + Hash,
+ V: PartialEq,
+ S: BuildHasher,
+{
+ fn eq(&self, other: &MultiMap<K, V, S>) -> bool {
+ if self.len() != other.len() {
+ return false;
+ }
+
+ self.iter_all()
+ .all(|(key, value)| other.get_vec(key).is_some_and(|v| *value == *v))
+ }
+}
+
+impl<K, V, S> Eq for MultiMap<K, V, S>
+where
+ K: Eq + Hash,
+ V: Eq,
+ S: BuildHasher,
+{
+}
+
+impl<K, V, S> Default for MultiMap<K, V, S>
+where
+ K: Eq + Hash,
+ S: BuildHasher + Default,
+{
+ fn default() -> MultiMap<K, V, S> {
+ MultiMap {
+ inner: Default::default(),
+ }
+ }
+}
+
+impl<K, V, S> FromIterator<(K, V)> for MultiMap<K, V, S>
+where
+ K: Eq + Hash,
+ S: BuildHasher + Default,
+{
+ fn from_iter<T: IntoIterator<Item = (K, V)>>(iterable: T) -> MultiMap<K, V, S> {
+ let iter = iterable.into_iter();
+ let hint = iter.size_hint().0;
+
+ let mut multimap = MultiMap::with_capacity_and_hasher(hint, S::default());
+ for (k, v) in iter {
+ multimap.insert(k, v);
+ }
+
+ multimap
+ }
+}
+
+impl<K, V, S> FromIterator<(K, Vec<V>)> for MultiMap<K, V, S>
+where
+ K: Eq + Hash,
+ V: Clone,
+ S: BuildHasher + Default,
+{
+ fn from_iter<T: IntoIterator<Item = (K, Vec<V>)>>(iterable: T) -> MultiMap<K, V, S> {
+ let iter = iterable.into_iter();
+ let hint = iter.size_hint().0;
+
+ let mut multimap = MultiMap::with_capacity_and_hasher(hint, S::default());
+ for (k, v) in iter {
+ multimap.insert_many_from_slice(k, &v[..])
+ }
+
+ multimap
+ }
+}
+
+impl<'a, K, V, S> IntoIterator for &'a MultiMap<K, V, S>
+where
+ K: Eq + Hash,
+ S: BuildHasher,
+{
+ type Item = (&'a K, &'a Vec<V>);
+ type IntoIter = IterAll<'a, K, Vec<V>>;
+
+ fn into_iter(self) -> IterAll<'a, K, Vec<V>> {
+ self.iter_all()
+ }
+}
+
+impl<'a, K, V, S> IntoIterator for &'a mut MultiMap<K, V, S>
+where
+ K: Eq + Hash,
+ S: BuildHasher,
+{
+ type Item = (&'a K, &'a mut Vec<V>);
+ type IntoIter = IterAllMut<'a, K, Vec<V>>;
+
+ fn into_iter(self) -> IterAllMut<'a, K, Vec<V>> {
+ self.inner.iter_mut()
+ }
+}
+
+impl<K, V, S> IntoIterator for MultiMap<K, V, S>
+where
+ K: Eq + Hash,
+ S: BuildHasher,
+{
+ type Item = (K, Vec<V>);
+ type IntoIter = IntoIter<K, Vec<V>>;
+
+ fn into_iter(self) -> IntoIter<K, Vec<V>> {
+ self.inner.into_iter()
+ }
+}
+
+impl<K, V, S> Extend<(K, V)> for MultiMap<K, V, S>
+where
+ K: Eq + Hash,
+ S: BuildHasher,
+{
+ fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
+ for (k, v) in iter {
+ self.insert(k, v);
+ }
+ }
+}
+
+impl<'a, K, V, S> Extend<(&'a K, &'a V)> for MultiMap<K, V, S>
+where
+ K: Eq + Hash + Copy,
+ V: Copy,
+ S: BuildHasher,
+{
+ fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) {
+ self.extend(iter.into_iter().map(|(&key, &value)| (key, value)));
+ }
+}
+
+impl<K, V, S> Extend<(K, Vec<V>)> for MultiMap<K, V, S>
+where
+ K: Eq + Hash,
+ S: BuildHasher,
+{
+ fn extend<T: IntoIterator<Item = (K, Vec<V>)>>(&mut self, iter: T) {
+ for (k, values) in iter {
+ match self.entry(k) {
+ Entry::Occupied(mut entry) => {
+ entry.get_vec_mut().extend(values);
+ }
+ Entry::Vacant(entry) => {
+ entry.insert_vec(values);
+ }
+ }
+ }
+ }
+}
+
+impl<'a, K, V, S> Extend<(&'a K, &'a Vec<V>)> for MultiMap<K, V, S>
+where
+ K: Eq + Hash + Copy,
+ V: Copy,
+ S: BuildHasher,
+{
+ fn extend<T: IntoIterator<Item = (&'a K, &'a Vec<V>)>>(&mut self, iter: T) {
+ self.extend(
+ iter.into_iter()
+ .map(|(&key, values)| (key, values.to_owned())),
+ );
+ }
+}
+
+#[derive(Clone)]
+pub struct Iter<'a, K: 'a, V: 'a> {
+ inner: IterAll<'a, K, Vec<V>>,
+}
+
+impl<'a, K, V> Iterator for Iter<'a, K, V> {
+ type Item = (&'a K, &'a V);
+
+ fn next(&mut self) -> Option<(&'a K, &'a V)> {
+ let (k, v) = self.inner.next()?;
+ let v = v.first()?;
+ Some((k, v))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+}
+
+impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
+ fn len(&self) -> usize {
+ self.inner.len()
+ }
+}
+
+pub struct IterMut<'a, K: 'a, V: 'a> {
+ inner: IterAllMut<'a, K, Vec<V>>,
+}
+
+impl<'a, K, V> Iterator for IterMut<'a, K, V> {
+ type Item = (&'a K, &'a mut V);
+
+ fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
+ let (k, v) = self.inner.next()?;
+ let v = v.first_mut()?;
+ Some((k, v))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+}
+
+impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
+ fn len(&self) -> usize {
+ self.inner.len()
+ }
+}
+
+#[macro_export]
+/// Create a `MultiMap` from a list of key value pairs
+///
+/// ## Example
+///
+/// ```
+/// # use multimap::MultiMap;
+/// #[macro_use] extern crate multimap;
+/// # fn main(){
+///
+/// let map = multimap!(
+/// "dog" => "husky",
+/// "dog" => "retreaver",
+/// "dog" => "shiba inu",
+/// "cat" => "cat"
+/// );
+/// # }
+///
+/// ```
+macro_rules! multimap{
+ (@replace_with_unit $_t:tt) => { () };
+ (@count $($key:expr),*) => { <[()]>::len(&[$($crate::multimap! { @replace_with_unit $key }),*]) };
+
+ ($($key:expr => $value:expr),* $(,)?)=>{
+ {
+ let mut map = $crate::MultiMap::with_capacity($crate::multimap! { @count $($key),* });
+ $(
+ map.insert($key,$value);
+ )*
+ map
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use std::collections::HashMap;
+ use std::iter::FromIterator;
+
+ use super::*;
+
+ #[test]
+ fn create() {
+ let _: MultiMap<usize, usize> = MultiMap {
+ inner: HashMap::new(),
+ };
+ }
+
+ #[test]
+ fn new() {
+ let _: MultiMap<usize, usize> = MultiMap::new();
+ }
+
+ #[test]
+ fn with_capacity() {
+ let _: MultiMap<usize, usize> = MultiMap::with_capacity(20);
+ }
+
+ #[test]
+ fn insert() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 3);
+ }
+
+ #[test]
+ fn insert_identical() {
+ let mut m = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(1, 42);
+ assert_eq!(m.get_vec(&1), Some(&vec![42, 42]));
+ }
+
+ #[test]
+ fn insert_many() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert_many(1, vec![3, 4]);
+ assert_eq!(Some(&vec![3, 4]), m.get_vec(&1));
+ }
+
+ #[test]
+ fn insert_many_again() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 2);
+ m.insert_many(1, vec![3, 4]);
+ assert_eq!(Some(&vec![2, 3, 4]), m.get_vec(&1));
+ }
+
+ #[test]
+ fn insert_many_overlap() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert_many(1, vec![2, 3]);
+ m.insert_many(1, vec![3, 4]);
+ assert_eq!(Some(&vec![2, 3, 3, 4]), m.get_vec(&1));
+ }
+
+ #[test]
+ fn insert_many_from_slice() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert_many_from_slice(1, &[3, 4]);
+ assert_eq!(Some(&vec![3, 4]), m.get_vec(&1));
+ }
+
+ #[test]
+ fn insert_many_from_slice_again() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 2);
+ m.insert_many_from_slice(1, &[3, 4]);
+ assert_eq!(Some(&vec![2, 3, 4]), m.get_vec(&1));
+ }
+
+ #[test]
+ fn insert_existing() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 3);
+ m.insert(1, 4);
+ assert_eq!(Some(&vec![3, 4]), m.get_vec(&1));
+ }
+
+ #[test]
+ #[should_panic(expected = "no entry found for key")]
+ fn index_no_entry() {
+ let m: MultiMap<usize, usize> = MultiMap::new();
+ let _ = &m[&1];
+ }
+
+ #[test]
+ fn index() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 41);
+ m.insert(2, 42);
+ m.insert(3, 43);
+ let values = m[&2];
+ assert_eq!(values, 42);
+ }
+
+ #[test]
+ #[should_panic(expected = "no value found for key")]
+ fn index_empty_vec() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.get_vec_mut(&1).unwrap().clear();
+ let values = m[&1];
+ assert_eq!(values, 42);
+ }
+
+ #[test]
+ fn contains_key_true() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ assert!(m.contains_key(&1));
+ }
+
+ #[test]
+ fn contains_key_false() {
+ let m: MultiMap<usize, usize> = MultiMap::new();
+ assert!(!m.contains_key(&1));
+ }
+
+ #[test]
+ fn len() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(2, 1337);
+ m.insert(3, 99);
+ assert_eq!(m.len(), 3);
+ }
+
+ #[test]
+ fn remove_not_present() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ let v = m.remove(&1);
+ assert_eq!(v, None);
+ }
+
+ #[test]
+ fn remove_present() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ let v = m.remove(&1);
+ assert_eq!(v, Some(vec![42]));
+ }
+
+ #[test]
+ fn get_not_present() {
+ let m: MultiMap<usize, usize> = MultiMap::new();
+ assert_eq!(m.get(&1), None);
+ }
+
+ #[test]
+ fn get_present() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ assert_eq!(m.get(&1), Some(&42));
+ }
+
+ #[test]
+ fn get_empty() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.get_vec_mut(&1).and_then(Vec::pop);
+ assert_eq!(m.get(&1), None);
+ }
+
+ #[test]
+ fn get_vec_not_present() {
+ let m: MultiMap<usize, usize> = MultiMap::new();
+ assert_eq!(m.get_vec(&1), None);
+ }
+
+ #[test]
+ fn get_vec_present() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(1, 1337);
+ assert_eq!(m.get_vec(&1), Some(&vec![42, 1337]));
+ }
+
+ #[test]
+ fn capacity() {
+ let m: MultiMap<usize, usize> = MultiMap::with_capacity(20);
+ assert!(m.capacity() >= 20);
+ }
+
+ #[test]
+ fn is_empty_true() {
+ let m: MultiMap<usize, usize> = MultiMap::new();
+ assert!(m.is_empty());
+ }
+
+ #[test]
+ fn is_empty_false() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ assert!(!m.is_empty());
+ }
+
+ #[test]
+ fn clear() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.clear();
+ assert!(m.is_empty());
+ }
+
+ #[test]
+ fn get_mut() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ if let Some(v) = m.get_mut(&1) {
+ *v = 1337;
+ }
+ assert_eq!(m[&1], 1337)
+ }
+
+ #[test]
+ fn get_vec_mut() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(1, 1337);
+ if let Some(v) = m.get_vec_mut(&1) {
+ (*v)[0] = 5;
+ (*v)[1] = 10;
+ }
+ assert_eq!(m.get_vec(&1), Some(&vec![5, 10]))
+ }
+
+ #[test]
+ fn get_mut_empty() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.get_vec_mut(&1).and_then(Vec::pop);
+ assert_eq!(m.get_mut(&1), None);
+ }
+
+ #[test]
+ fn keys() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(2, 42);
+ m.insert(4, 42);
+ m.insert(8, 42);
+
+ let keys: Vec<_> = m.keys().cloned().collect();
+ assert_eq!(keys.len(), 4);
+ assert!(keys.contains(&1));
+ assert!(keys.contains(&2));
+ assert!(keys.contains(&4));
+ assert!(keys.contains(&8));
+ }
+
+ #[test]
+ fn iter() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(1, 42);
+ m.insert(4, 42);
+ m.insert(8, 42);
+
+ assert!(m.iter().all(|(_, &v)| v == 42));
+
+ let mut iter = m.iter();
+
+ for _ in iter.by_ref().take(2) {}
+
+ assert_eq!(iter.len(), 1);
+ }
+
+ #[test]
+ fn iter_empty_vec() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(42, 42);
+ m.get_vec_mut(&42).unwrap().clear();
+
+ assert!(m.iter().next().is_none());
+ }
+
+ #[test]
+ fn flat_iter() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(1, 43);
+ m.insert(4, 42);
+ m.insert(8, 42);
+
+ let keys = [1, 4, 8];
+
+ for (key, value) in m.flat_iter() {
+ assert!(keys.contains(key));
+
+ if key == &1 {
+ assert!(value == &42 || value == &43);
+ } else {
+ assert_eq!(value, &42);
+ }
+ }
+ }
+
+ #[test]
+ fn flat_iter_mut() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(1, 43);
+ m.insert(4, 42);
+ m.insert(8, 42);
+
+ let keys = [1, 4, 8];
+
+ for (key, value) in m.flat_iter_mut() {
+ assert!(keys.contains(key));
+
+ if key == &1 {
+ assert!(value == &42 || value == &43);
+
+ *value = 55;
+ assert_eq!(value, &55);
+ } else {
+ assert_eq!(value, &42);
+
+ *value = 76;
+ assert_eq!(value, &76);
+ }
+ }
+ }
+
+ #[test]
+ fn intoiterator_for_reference_type() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(1, 43);
+ m.insert(4, 42);
+ m.insert(8, 42);
+
+ let keys = [1, 4, 8];
+
+ for (key, value) in &m {
+ assert!(keys.contains(key));
+
+ if key == &1 {
+ assert_eq!(value, &vec![42, 43]);
+ } else {
+ assert_eq!(value, &vec![42]);
+ }
+ }
+ }
+
+ #[test]
+ fn intoiterator_for_mutable_reference_type() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(1, 43);
+ m.insert(4, 42);
+ m.insert(8, 42);
+
+ let keys = [1, 4, 8];
+
+ for (key, value) in &mut m {
+ assert!(keys.contains(key));
+
+ if key == &1 {
+ assert_eq!(value, &vec![42, 43]);
+ value.push(666);
+ } else {
+ assert_eq!(value, &vec![42]);
+ }
+ }
+
+ assert_eq!(m.get_vec(&1), Some(&vec![42, 43, 666]));
+ }
+
+ #[test]
+ fn intoiterator_consuming() {
+ let mut m: MultiMap<usize, usize> = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(1, 43);
+ m.insert(4, 42);
+ m.insert(8, 42);
+
+ let keys = [1, 4, 8];
+
+ for (key, value) in m {
+ assert!(keys.contains(&key));
+
+ if key == 1 {
+ assert_eq!(value, vec![42, 43]);
+ } else {
+ assert_eq!(value, vec![42]);
+ }
+ }
+ }
+
+ #[test]
+ fn test_fmt_debug() {
+ let mut map = MultiMap::new();
+ let empty: MultiMap<i32, i32> = MultiMap::new();
+
+ map.insert(1, 2);
+ map.insert(1, 5);
+ map.insert(1, -1);
+ map.insert(3, 4);
+
+ let map_str = format!("{:?}", map);
+
+ assert!(map_str == "{1: [2, 5, -1], 3: [4]}" || map_str == "{3: [4], 1: [2, 5, -1]}");
+ assert_eq!(format!("{:?}", empty), "{}");
+ }
+
+ #[test]
+ fn test_eq() {
+ let mut m1 = MultiMap::new();
+ m1.insert(1, 2);
+ m1.insert(2, 3);
+ m1.insert(3, 4);
+ let mut m2 = MultiMap::new();
+ m2.insert(1, 2);
+ m2.insert(2, 3);
+ assert_ne!(m1, m2);
+ m2.insert(3, 4);
+ assert_eq!(m1, m2);
+ m2.insert(3, 4);
+ assert_ne!(m1, m2);
+ m1.insert(3, 4);
+ assert_eq!(m1, m2);
+ }
+
+ #[test]
+ fn test_eq_empty_key() {
+ let mut m1 = MultiMap::new();
+ m1.insert(1, 2);
+ m1.insert(2, 3);
+ let mut m2 = MultiMap::new();
+ m2.insert(1, 2);
+ m2.insert_many(2, []);
+ assert_ne!(m1, m2);
+ m2.insert_many(2, [3]);
+ assert_eq!(m1, m2);
+ }
+
+ #[test]
+ fn test_default() {
+ let _: MultiMap<u8, u8> = Default::default();
+ }
+
+ #[test]
+ fn test_from_iterator() {
+ let vals: Vec<(&str, i64)> = vec![("foo", 123), ("bar", 456), ("foo", 789)];
+ let multimap: MultiMap<&str, i64> = MultiMap::from_iter(vals);
+
+ let foo_vals: &Vec<i64> = multimap.get_vec("foo").unwrap();
+ assert!(foo_vals.contains(&123));
+ assert!(foo_vals.contains(&789));
+
+ let bar_vals: &Vec<i64> = multimap.get_vec("bar").unwrap();
+ assert!(bar_vals.contains(&456));
+ }
+
+ #[test]
+ fn test_from_vec_iterator() {
+ let vals: Vec<(&str, Vec<i64>)> = vec![
+ ("foo", vec![123, 456]),
+ ("bar", vec![234]),
+ ("foobar", vec![567, 678, 789]),
+ ("bar", vec![12, 23, 34]),
+ ];
+
+ let multimap: MultiMap<&str, i64> = MultiMap::from_iter(vals);
+
+ let foo_vals: &Vec<i64> = multimap.get_vec("foo").unwrap();
+ assert!(foo_vals.contains(&123));
+ assert!(foo_vals.contains(&456));
+
+ let bar_vals: &Vec<i64> = multimap.get_vec("bar").unwrap();
+ assert!(bar_vals.contains(&234));
+ assert!(bar_vals.contains(&12));
+ assert!(bar_vals.contains(&23));
+ assert!(bar_vals.contains(&34));
+
+ let foobar_vals: &Vec<i64> = multimap.get_vec("foobar").unwrap();
+ assert!(foobar_vals.contains(&567));
+ assert!(foobar_vals.contains(&678));
+ assert!(foobar_vals.contains(&789));
+ }
+
+ #[test]
+ fn test_extend_consuming_hashmap() {
+ let mut a = MultiMap::new();
+ a.insert(1, 42);
+
+ let mut b = HashMap::new();
+ b.insert(1, 43);
+ b.insert(2, 666);
+
+ a.extend(b);
+
+ assert_eq!(a.len(), 2);
+ assert_eq!(a.get_vec(&1), Some(&vec![42, 43]));
+ }
+
+ #[test]
+ fn test_extend_ref_hashmap() {
+ let mut a = MultiMap::new();
+ a.insert(1, 42);
+
+ let mut b = HashMap::new();
+ b.insert(1, 43);
+ b.insert(2, 666);
+
+ a.extend(&b);
+
+ assert_eq!(a.len(), 2);
+ assert_eq!(a.get_vec(&1), Some(&vec![42, 43]));
+ assert_eq!(b.len(), 2);
+ assert_eq!(b[&1], 43);
+ }
+
+ #[test]
+ fn test_extend_consuming_multimap() {
+ let mut a = MultiMap::new();
+ a.insert(1, 42);
+
+ let mut b = MultiMap::new();
+ b.insert(1, 43);
+ b.insert(1, 44);
+ b.insert(2, 666);
+
+ a.extend(b);
+
+ assert_eq!(a.len(), 2);
+ assert_eq!(a.get_vec(&1), Some(&vec![42, 43, 44]));
+ }
+
+ #[test]
+ fn test_extend_ref_multimap() {
+ let mut a = MultiMap::new();
+ a.insert(1, 42);
+
+ let mut b = MultiMap::new();
+ b.insert(1, 43);
+ b.insert(1, 44);
+ b.insert(2, 666);
+
+ a.extend(&b);
+
+ assert_eq!(a.len(), 2);
+ assert_eq!(a.get_vec(&1), Some(&vec![42, 43, 44]));
+ assert_eq!(b.len(), 2);
+ assert_eq!(b.get_vec(&1), Some(&vec![43, 44]));
+ }
+
+ #[test]
+ fn test_entry() {
+ let mut m = MultiMap::new();
+ m.insert(1, 42);
+
+ {
+ let v = m.entry(1).or_insert(43);
+ assert_eq!(v, &42);
+ *v = 44;
+ }
+ assert_eq!(m.entry(2).or_insert(666), &666);
+
+ assert_eq!(m[&1], 44);
+ assert_eq!(m[&2], 666);
+ }
+
+ #[test]
+ fn test_entry_vec() {
+ let mut m = MultiMap::new();
+ m.insert(1, 42);
+
+ {
+ let v = m.entry(1).or_insert_vec(vec![43]);
+ assert_eq!(v, &vec![42]);
+ *v.first_mut().unwrap() = 44;
+ }
+ assert_eq!(m.entry(2).or_insert_vec(vec![666]), &vec![666]);
+
+ assert_eq!(m[&1], 44);
+ assert_eq!(m[&2], 666);
+ }
+
+ #[test]
+ fn test_is_vec() {
+ let mut m = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(1, 1337);
+ m.insert(2, 2332);
+
+ assert!(m.is_vec(&1));
+ assert!(!m.is_vec(&2));
+ assert!(!m.is_vec(&3));
+ }
+
+ #[test]
+ fn test_macro() {
+ let mut manual_map = MultiMap::new();
+ manual_map.insert("key1", 42);
+ assert_eq!(manual_map, multimap!("key1" => 42));
+
+ manual_map.insert("key1", 1337);
+ manual_map.insert("key2", 2332);
+ let macro_map = multimap! {
+ "key1" => 42,
+ "key1" => 1337,
+ "key2" => 2332
+ };
+ assert_eq!(manual_map, macro_map);
+ }
+
+ #[test]
+ fn retain_removes_element() {
+ let mut m = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(1, 99);
+ m.retain(|&k, &v| k == 1 && v == 42);
+ assert_eq!(1, m.len());
+ assert_eq!(Some(&42), m.get(&1));
+ }
+
+ #[test]
+ fn retain_also_removes_empty_vector() {
+ let mut m = MultiMap::new();
+ m.insert(1, 42);
+ m.insert(1, 99);
+ m.insert(2, 42);
+ m.retain(|&k, &v| k == 1 && v == 42);
+ assert_eq!(1, m.len());
+ assert_eq!(Some(&42), m.get(&1));
+ }
+}
diff --git a/vendor/multimap/src/serde.rs b/vendor/multimap/src/serde.rs
new file mode 100644
index 00000000..51ccae66
--- /dev/null
+++ b/vendor/multimap/src/serde.rs
@@ -0,0 +1,149 @@
+// Copyright (c) 2016 multimap developers
+//
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. All files in the project carrying such notice may not be copied,
+// modified, or distributed except according to those terms.
+
+//! Serde trait implementations for MultiMap
+
+extern crate serde;
+
+use std::fmt;
+use std::hash::{BuildHasher, Hash};
+use std::marker::PhantomData;
+
+use self::serde::de::{MapAccess, Visitor};
+use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
+
+use MultiMap;
+
+impl<K, V, BS> Serialize for MultiMap<K, V, BS>
+where
+ K: Serialize + Eq + Hash,
+ V: Serialize,
+ BS: BuildHasher,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.inner.serialize(serializer)
+ }
+}
+
+impl<K, V, S> MultiMapVisitor<K, V, S>
+where
+ K: Hash + Eq,
+{
+ fn new() -> Self {
+ MultiMapVisitor {
+ marker: PhantomData,
+ }
+ }
+}
+
+struct MultiMapVisitor<K, V, S> {
+ marker: PhantomData<MultiMap<K, V, S>>,
+}
+
+impl<'a, K, V, S> Visitor<'a> for MultiMapVisitor<K, V, S>
+where
+ K: Deserialize<'a> + Eq + Hash,
+ V: Deserialize<'a>,
+ S: BuildHasher + Default,
+{
+ type Value = MultiMap<K, V, S>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("expected a map")
+ }
+
+ fn visit_map<M>(self, mut visitor: M) -> Result<Self::Value, M::Error>
+ where
+ M: MapAccess<'a>,
+ {
+ let mut values =
+ MultiMap::with_capacity_and_hasher(visitor.size_hint().unwrap_or(0), S::default());
+
+ while let Some((key, value)) = visitor.next_entry()? {
+ values.inner.insert(key, value);
+ }
+
+ Ok(values)
+ }
+}
+
+impl<'a, K, V, S> Deserialize<'a> for MultiMap<K, V, S>
+where
+ K: Deserialize<'a> + Eq + Hash,
+ V: Deserialize<'a>,
+ S: BuildHasher + Default,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'a>,
+ {
+ deserializer.deserialize_map(MultiMapVisitor::<K, V, S>::new())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+
+ extern crate serde_test;
+
+ use self::serde_test::{assert_tokens, Token};
+
+ use super::*;
+
+ #[test]
+ fn test_empty() {
+ let map = MultiMap::<char, u8>::new();
+
+ assert_tokens(&map, &[Token::Map { len: Some(0) }, Token::MapEnd]);
+ }
+
+ #[test]
+ fn test_single() {
+ let mut map = MultiMap::<char, u8>::new();
+ map.insert('x', 1);
+
+ assert_tokens(
+ &map,
+ &[
+ Token::Map { len: Some(1) },
+ Token::Char('x'),
+ Token::Seq { len: Some(1) },
+ Token::U8(1),
+ Token::SeqEnd,
+ Token::MapEnd,
+ ],
+ );
+ }
+
+ #[test]
+ fn test_multiple() {
+ let mut map = MultiMap::<char, u8>::new();
+ map.insert('x', 1);
+ map.insert('x', 3);
+ map.insert('x', 1);
+ map.insert('x', 5);
+
+ assert_tokens(
+ &map,
+ &[
+ Token::Map { len: Some(1) },
+ Token::Char('x'),
+ Token::Seq { len: Some(4) },
+ Token::U8(1),
+ Token::U8(3),
+ Token::U8(1),
+ Token::U8(5),
+ Token::SeqEnd,
+ Token::MapEnd,
+ ],
+ );
+ }
+}