Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ arbitrary = { version = "1.0", optional = true, default-features = false }
quickcheck = { version = "1.0", optional = true, default-features = false }
serde = { version = "1.0", optional = true, default-features = false }
rayon = { version = "1.9", optional = true }
sval = { version = "2", optional = true, default-features = false }

# deprecated: use borsh's "indexmap" feature instead.
borsh = { version = "1.2", optional = true, default-features = false }
Expand Down Expand Up @@ -51,11 +52,11 @@ sign-tag = true
tag-name = "{{version}}"

[package.metadata.docs.rs]
features = ["arbitrary", "quickcheck", "serde", "borsh", "rayon"]
features = ["arbitrary", "quickcheck", "serde", "borsh", "rayon", "sval"]
rustdoc-args = ["--cfg", "docsrs"]

[workspace]
members = ["test-nostd", "test-serde"]
members = ["test-nostd", "test-serde", "test-sval"]

[lints.clippy]
style = "allow"
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ mod macros;
mod borsh;
#[cfg(feature = "serde")]
mod serde;
#[cfg(feature = "sval")]
mod sval;
mod util;

pub mod map;
Expand Down
36 changes: 36 additions & 0 deletions src/sval.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#![cfg_attr(docsrs, doc(cfg(feature = "serde")))]

use crate::{IndexMap, IndexSet};
use sval::{Stream, Value};

impl<K: Value, V: Value, S> Value for IndexMap<K, V, S> {
fn stream<'sval, ST: Stream<'sval> + ?Sized>(&'sval self, stream: &mut ST) -> sval::Result {
stream.map_begin(Some(self.len()))?;

for (k, v) in self {
stream.map_key_begin()?;
stream.value(k)?;
stream.map_key_end()?;

stream.map_value_begin()?;
stream.value(v)?;
stream.map_value_end()?;
}

stream.map_end()
}
}

impl<K: Value, S> Value for IndexSet<K, S> {
fn stream<'sval, ST: Stream<'sval> + ?Sized>(&'sval self, stream: &mut ST) -> sval::Result {
stream.seq_begin(Some(self.len()))?;

for value in self {
stream.seq_value_begin()?;
stream.value(value)?;
stream.seq_value_end()?;
}

stream.seq_end()
}
}
13 changes: 13 additions & 0 deletions test-sval/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "test-sval"
version = "0.1.0"
publish = false
edition = "2021"

[dependencies]

[dev-dependencies]
fnv = "1.0"
indexmap = { path = "..", features = ["sval"] }
sval = { version = "2", features = ["derive"] }
sval_test = "2"
104 changes: 104 additions & 0 deletions test-sval/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#![cfg(test)]

use fnv::FnvBuildHasher;
use indexmap::{indexmap, indexset, IndexMap, IndexSet};
use sval_test::{assert_tokens, Token};

#[test]
fn test_sval_map() {
let map = indexmap! { 1 => 2, 3 => 4 };
assert_tokens(
&map,
&[
Token::MapBegin(Some(2)),
Token::MapKeyBegin,
Token::I32(1),
Token::MapKeyEnd,
Token::MapValueBegin,
Token::I32(2),
Token::MapValueEnd,
Token::MapKeyBegin,
Token::I32(3),
Token::MapKeyEnd,
Token::MapValueBegin,
Token::I32(4),
Token::MapValueEnd,
Token::MapEnd,
],
);
}

#[test]
fn test_sval_set() {
let set = indexset! { 1, 2, 3, 4 };
assert_tokens(
&set,
&[
Token::SeqBegin(Some(4)),
Token::SeqValueBegin,
Token::I32(1),
Token::SeqValueEnd,
Token::SeqValueBegin,
Token::I32(2),
Token::SeqValueEnd,
Token::SeqValueBegin,
Token::I32(3),
Token::SeqValueEnd,
Token::SeqValueBegin,
Token::I32(4),
Token::SeqValueEnd,
Token::SeqEnd,
],
);
}

#[test]
fn test_sval_map_fnv_hasher() {
let mut map: IndexMap<i32, i32, FnvBuildHasher> = Default::default();
map.insert(1, 2);
map.insert(3, 4);
assert_tokens(
&map,
&[
Token::MapBegin(Some(2)),
Token::MapKeyBegin,
Token::I32(1),
Token::MapKeyEnd,
Token::MapValueBegin,
Token::I32(2),
Token::MapValueEnd,
Token::MapKeyBegin,
Token::I32(3),
Token::MapKeyEnd,
Token::MapValueBegin,
Token::I32(4),
Token::MapValueEnd,
Token::MapEnd,
],
);
}

#[test]
fn test_sval_set_fnv_hasher() {
let mut set: IndexSet<i32, FnvBuildHasher> = Default::default();
set.extend(1..5);
assert_tokens(
&set,
&[
Token::SeqBegin(Some(4)),
Token::SeqValueBegin,
Token::I32(1),
Token::SeqValueEnd,
Token::SeqValueBegin,
Token::I32(2),
Token::SeqValueEnd,
Token::SeqValueBegin,
Token::I32(3),
Token::SeqValueEnd,
Token::SeqValueBegin,
Token::I32(4),
Token::SeqValueEnd,
Token::SeqEnd,
],
);
}