Skip to content

Commit e01e16d

Browse files
preston-evans98dj8yf0μl
and
dj8yf0μl
authored
fix: add indexmap support (#346)
* Add indexmap support * ci: downgrade serde_bytes for msrv job * Update test.sh * ci: msrv downgrade condition * test: add snapshots --------- Co-authored-by: dj8yf0μl <[email protected]>
1 parent a34f324 commit e01e16d

File tree

9 files changed

+211
-6
lines changed

9 files changed

+211
-6
lines changed

.github/test.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ cargo test --features ascii,unstable__schema 'schema::test_ascii_strings'
2323
########## features = ["rc"] group
2424
cargo test --features rc 'roundtrip::test_rc'
2525
cargo test --features rc,unstable__schema 'schema::test_rc'
26+
########## features = ["indexmap"] group
27+
cargo test --features indexmap 'roundtrip::test_indexmap'
28+
# checking with `derive` too just for the sake of redundancy https://github.com/near/borsh-rs/pull/346
29+
cargo test --features indexmap,derive 'roundtrip::test_indexmap'
2630
########## features = ["de_strict_order"] group
2731
cargo test --features de_strict_order 'roundtrip::test_hash_map'
2832
cargo test --features de_strict_order 'roundtrip::test_btree_map'
@@ -44,6 +48,10 @@ cargo test --no-default-features --features ascii,unstable__schema 'schema::test
4448
########## features = ["rc"] group
4549
cargo test --no-default-features --features rc 'roundtrip::test_rc'
4650
cargo test --no-default-features --features rc,unstable__schema 'schema::test_rc'
51+
########## features = ["indexmap"] group
52+
cargo test --no-default-features --features indexmap 'roundtrip::test_indexmap'
53+
# checking with `derive` too just for the sake of redundancy https://github.com/near/borsh-rs/pull/346
54+
cargo test --no-default-features --features indexmap,derive 'roundtrip::test_indexmap'
4755
########## features = ["hashbrown"] group
4856
cargo test --no-default-features --features hashbrown
4957
cargo test --no-default-features --features hashbrown,derive

.github/workflows/rust.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ jobs:
3636
run: rustup default ${{ matrix.rust_version }}
3737
- name: print rustc version
3838
run: rustc --version
39-
# - name: downgrade `toml_edit`, time`, `toml_datetime` crate to support older Rust toolchain
40-
# if: matrix.rust_version == '1.67.0'
41-
# run: |
42-
# cargo update -p toml_edit --precise 0.21.0
39+
- name: downgrade `serde_bytes` crate to support older Rust toolchain
40+
if: matrix.rust_version == '1.67'
41+
run: |
42+
cargo update -p serde_bytes --precise 0.11.16
4343
- name: Run tests
4444
run: ./.github/test.sh
4545

@@ -52,8 +52,8 @@ jobs:
5252
uses: dtolnay/rust-toolchain@nightly
5353
# a failure on this check means, that some of `syn` crate's enums have been extended
5454
# with new variants.
55-
# consult https://github.com/serde-rs/serde/blob/master/serde_derive/src/bound.rs#L100 ,
56-
# the implementation of `FindTyParams` may have been updated already
55+
# consult https://github.com/serde-rs/serde/blob/master/serde_derive/src/bound.rs#L100 ,
56+
# the implementation of `FindTyParams` may have been updated already
5757
- name: Run exhaustive check tests
5858
run: RUSTFLAGS="-A unused_imports -D warnings" cargo check --workspace --features force_exhaustive_checks
5959

borsh/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ borsh-derive = { path = "../borsh-derive", version = "~1.5.5", optional = true }
3939
# sudden breaking changes with an open range of versions, so we limit the range by not yet released 0.16.0 version:
4040
hashbrown = { version = ">=0.11,<0.16.0", optional = true }
4141
bytes = { version = "1", optional = true }
42+
indexmap = { version = "2", optional = true }
4243
bson = { version = "2", optional = true }
4344

4445
[dev-dependencies]

borsh/src/de/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,39 @@ impl BorshDeserialize for bson::oid::ObjectId {
453453
}
454454
}
455455

456+
#[cfg(feature = "indexmap")]
457+
// Taken from https://github.com/indexmap-rs/indexmap/blob/dd06e5773e4f91748396c67d00c83637f5c0dd49/src/borsh.rs#L39
458+
// license: MIT OR Apache-2.0
459+
impl<K, V, S> BorshDeserialize for indexmap::IndexMap<K, V, S>
460+
where
461+
K: BorshDeserialize + Eq + core::hash::Hash,
462+
V: BorshDeserialize,
463+
S: core::hash::BuildHasher + Default,
464+
{
465+
#[inline]
466+
fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> {
467+
check_zst::<K>()?;
468+
let vec = <Vec<(K, V)>>::deserialize_reader(reader)?;
469+
Ok(vec.into_iter().collect::<indexmap::IndexMap<K, V, S>>())
470+
}
471+
}
472+
473+
#[cfg(feature = "indexmap")]
474+
// Taken from https://github.com/indexmap-rs/indexmap/blob/dd06e5773e4f91748396c67d00c83637f5c0dd49/src/borsh.rs#L75
475+
// license: MIT OR Apache-2.0
476+
impl<T, S> BorshDeserialize for indexmap::IndexSet<T, S>
477+
where
478+
T: BorshDeserialize + Eq + core::hash::Hash,
479+
S: core::hash::BuildHasher + Default,
480+
{
481+
#[inline]
482+
fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> {
483+
check_zst::<T>()?;
484+
let vec = <Vec<T>>::deserialize_reader(reader)?;
485+
Ok(vec.into_iter().collect::<indexmap::IndexSet<T, S>>())
486+
}
487+
}
488+
456489
impl<T> BorshDeserialize for Cow<'_, T>
457490
where
458491
T: ToOwned + ?Sized,

borsh/src/ser/mod.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,58 @@ impl BorshSerialize for bson::oid::ObjectId {
317317
}
318318
}
319319

320+
#[cfg(feature = "indexmap")]
321+
// Taken from https://github.com/indexmap-rs/indexmap/blob/dd06e5773e4f91748396c67d00c83637f5c0dd49/src/borsh.rs#L74C1-L86C2
322+
// license: MIT OR Apache-2.0
323+
impl<T, S> BorshSerialize for indexmap::IndexSet<T, S>
324+
where
325+
T: BorshSerialize,
326+
{
327+
#[inline]
328+
fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
329+
check_zst::<T>()?;
330+
331+
let iterator = self.iter();
332+
333+
u32::try_from(iterator.len())
334+
.map_err(|_| ErrorKind::InvalidData)?
335+
.serialize(writer)?;
336+
337+
for item in iterator {
338+
item.serialize(writer)?;
339+
}
340+
341+
Ok(())
342+
}
343+
}
344+
345+
#[cfg(feature = "indexmap")]
346+
// Taken from https://github.com/indexmap-rs/indexmap/blob/dd06e5773e4f91748396c67d00c83637f5c0dd49/src/borsh.rs#L15
347+
// license: MIT OR Apache-2.0
348+
impl<K, V, S> BorshSerialize for indexmap::IndexMap<K, V, S>
349+
where
350+
K: BorshSerialize,
351+
V: BorshSerialize,
352+
{
353+
#[inline]
354+
fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
355+
check_zst::<K>()?;
356+
357+
let iterator = self.iter();
358+
359+
u32::try_from(iterator.len())
360+
.map_err(|_| ErrorKind::InvalidData)?
361+
.serialize(writer)?;
362+
363+
for (key, value) in iterator {
364+
key.serialize(writer)?;
365+
value.serialize(writer)?;
366+
}
367+
368+
Ok(())
369+
}
370+
}
371+
320372
impl<T> BorshSerialize for VecDeque<T>
321373
where
322374
T: BorshSerialize,
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
source: borsh/tests/roundtrip/test_indexmap.rs
3+
expression: serialized_map
4+
---
5+
[
6+
3,
7+
0,
8+
0,
9+
0,
10+
1,
11+
0,
12+
0,
13+
0,
14+
2,
15+
0,
16+
0,
17+
0,
18+
3,
19+
0,
20+
0,
21+
0,
22+
4,
23+
0,
24+
0,
25+
0,
26+
5,
27+
0,
28+
0,
29+
0,
30+
6,
31+
0,
32+
0,
33+
0,
34+
]
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
source: borsh/tests/roundtrip/test_indexmap.rs
3+
expression: serialized_set
4+
---
5+
[
6+
6,
7+
0,
8+
0,
9+
0,
10+
1,
11+
0,
12+
0,
13+
0,
14+
2,
15+
0,
16+
0,
17+
0,
18+
3,
19+
0,
20+
0,
21+
0,
22+
4,
23+
0,
24+
0,
25+
0,
26+
5,
27+
0,
28+
0,
29+
0,
30+
6,
31+
0,
32+
0,
33+
0,
34+
]
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use borsh::BorshDeserialize;
2+
use indexmap::{IndexMap, IndexSet};
3+
4+
#[test]
5+
// Taken from https://github.com/indexmap-rs/indexmap/blob/dd06e5773e4f91748396c67d00c83637f5c0dd49/src/borsh.rs#L100
6+
// license: MIT OR Apache-2.0
7+
fn test_indexmap_roundtrip() {
8+
let original_map: IndexMap<i32, i32> = {
9+
let mut map = IndexMap::new();
10+
map.insert(1, 2);
11+
map.insert(3, 4);
12+
map.insert(5, 6);
13+
map
14+
};
15+
let serialized_map = borsh::to_vec(&original_map).unwrap();
16+
#[cfg(feature = "std")]
17+
insta::assert_debug_snapshot!(serialized_map);
18+
19+
let deserialized_map: IndexMap<i32, i32> =
20+
BorshDeserialize::try_from_slice(&serialized_map).unwrap();
21+
assert_eq!(original_map, deserialized_map);
22+
}
23+
24+
#[test]
25+
// Taken from https://github.com/indexmap-rs/indexmap/blob/dd06e5773e4f91748396c67d00c83637f5c0dd49/src/borsh.rs#L115
26+
// license: MIT OR Apache-2.0
27+
fn test_indexset_roundtrip() {
28+
let mut original_set = IndexSet::new();
29+
[1, 2, 3, 4, 5, 6].iter().for_each(|&i| {
30+
original_set.insert(i);
31+
});
32+
33+
let serialized_set = borsh::to_vec(&original_set).unwrap();
34+
35+
#[cfg(feature = "std")]
36+
insta::assert_debug_snapshot!(serialized_set);
37+
38+
let deserialized_set: IndexSet<i32> =
39+
BorshDeserialize::try_from_slice(&serialized_set).unwrap();
40+
assert_eq!(original_set, deserialized_set);
41+
}

borsh/tests/tests.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ mod roundtrip {
5252
mod test_cells;
5353
#[cfg(feature = "rc")]
5454
mod test_rc;
55+
#[cfg(feature = "indexmap")]
56+
mod test_indexmap;
5557

5658
#[cfg(feature = "derive")]
5759
mod requires_derive_category {

0 commit comments

Comments
 (0)