Skip to content

Commit

Permalink
add serde serialization support
Browse files Browse the repository at this point in the history
  • Loading branch information
keithamus committed Apr 4, 2024
1 parent 49c5a71 commit 868c118
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 1 deletion.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,22 @@ harness = false
# implement its `Allocator` trait.
allocator-api2 = { version = "0.2.8", default-features = false, optional = true }

# This dependency is here to allow integration with Serde, if the `serde` feature is enabled
serde = { version = "1.0.171", optional = true }

[dev-dependencies]
quickcheck = "1.0.3"
criterion = "0.3.6"
rand = "0.8.5"
serde_json = "1.0.115"

[features]
default = []
collections = []
boxed = []
allocator_api = []
std = []
serde = ["dep:serde"]

# [profile.bench]
# debug = true
50 changes: 49 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,32 @@ arenas.
}
```

Eventually [all `std` collection types will be parameterized by an
#### Serde

Adding the `serde` feature flag will enable transparent serialization for Vec.

```toml
[dependencies]
bumpalo = { version = "3.9", features = ["collections", "serde"] }
```

```rust,ignore
use bumpalo::{Bump, collections::Vec};
// Create a new bump arena.
let bump = Bump::new();
// Create a `Box`
let vec = Vec::new_in( &bump);
vec.push(1);
vec.push(2);
// Serialize with serde_json
assert_eq!(serde_json::to_string(&vec).unwrap(), "[1, 2]");
```

Eventually
[all `std` collection types will be parameterized by an
allocator](https://github.com/rust-lang/rust/issues/42774) and we can remove
this `collections` module and use the `std` versions.

Expand Down Expand Up @@ -153,6 +178,29 @@ in its space itself.
}
```

#### Serde

Adding the `serde` feature flag will enable transparent serialization of boxed
values.

```toml
[dependencies]
bumpalo = { version = "3.9", features = ["boxed", "serde"] }
```

```rust,ignore
use bumpalo::{Bump, boxed::Box};
// Create a new bump arena.
let bump = Bump::new();
// Create a `Box`
let box = Box::new_in("hello", &bump);
// Serialize with serde_json
assert_eq!(serde_json::to_string(&box).unwrap(), "\"hello\"");
```

### `#![no_std]` Support

Bumpalo is a `no_std` crate by default. It depends only on the `alloc` and `core` crates.
Expand Down
13 changes: 13 additions & 0 deletions src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,3 +681,16 @@ impl<'a, T, const N: usize> TryFrom<Box<'a, [T]>> for Box<'a, [T; N]> {
}
}
}

#[cfg(feature = "serde")]
use serde::{Serialize, Serializer};

#[cfg(feature = "serde")]
impl<'a, T> Serialize for Box<'a, T>
where
T: Serialize,
{
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
(**self).serialize(serializer)
}
}
20 changes: 20 additions & 0 deletions src/collections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2760,3 +2760,23 @@ impl<'bump> io::Write for Vec<'bump, u8> {
Ok(())
}
}

#[cfg(feature = "serde")]
use serde::{ser::SerializeSeq, Serialize, Serializer};

#[cfg(feature = "serde")]
impl<'a, T> Serialize for Vec<'a, T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.len))?;
for e in self.iter() {
seq.serialize_element(e)?;
}
seq.end()
}
}
10 changes: 10 additions & 0 deletions tests/all/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,13 @@ fn into_raw_aliasing() {
let mut_ref = unsafe { &mut *raw };
dbg!(mut_ref);
}

#[cfg(feature = "serde")]
#[test]
fn test_box_serializes() {
let bump = Bump::new();
let boxed = Box::new_in(1, &bump);
assert_eq!(serde_json::to_string(&boxed).unwrap(), "1");
let boxedStr = Box::new_in("a", &bump);
assert_eq!(serde_json::to_string(&boxedStr).unwrap(), "\"a\"");
}
13 changes: 13 additions & 0 deletions tests/all/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,16 @@ fn test_vec_write() {

assert_eq!(v, &[1, 2, 3]);
}

#[cfg(feature = "serde")]
#[test]
fn test_vec_serializes() {
let bump = Bump::new();
let mut vec = Vec::new_in(&bump);
vec.push("hello");
vec.push("world");
assert_eq!(
serde_json::to_string(&vec).unwrap(),
"[\"hello\",\"world\"]"
);
}

0 comments on commit 868c118

Please sign in to comment.