-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow responding with named MessagePack data.
Closes #2107
- Loading branch information
1 parent
1f82d4b
commit df71f79
Showing
3 changed files
with
170 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#![cfg(feature = "msgpack")] | ||
|
||
use rocket::{Rocket, Build}; | ||
use rocket::serde::msgpack; | ||
use rocket::local::blocking::Client; | ||
|
||
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Eq)] | ||
struct Person { | ||
name: String, | ||
age: u8, | ||
gender: Gender, | ||
} | ||
|
||
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Eq)] | ||
#[serde(tag = "gender")] | ||
enum Gender { | ||
Male, | ||
Female, | ||
NonBinary, | ||
} | ||
|
||
#[rocket::post("/age_named", data = "<person>")] | ||
fn named(person: msgpack::MsgPack<Person>) -> msgpack::Named<Person> { | ||
let person = Person { age: person.age + 1, ..person.into_inner() }; | ||
msgpack::MsgPack(person) | ||
} | ||
|
||
#[rocket::post("/age_compact", data = "<person>")] | ||
fn compact(person: msgpack::MsgPack<Person>) -> msgpack::Compact<Person> { | ||
let person = Person { age: person.age + 1, ..person.into_inner() }; | ||
msgpack::MsgPack(person) | ||
} | ||
|
||
fn rocket() -> Rocket<Build> { | ||
rocket::build() | ||
.mount("/", rocket::routes![named, compact]) | ||
} | ||
|
||
fn read_string(buf: &mut rmp::decode::Bytes) -> String { | ||
let mut string_buf = vec![0; 32]; // Awful but we're just testing. | ||
rmp::decode::read_str(buf, &mut string_buf).unwrap().to_string() | ||
} | ||
|
||
#[test] | ||
fn check_named_roundtrip() { | ||
let client = Client::debug(rocket()).unwrap(); | ||
let person = Person { | ||
name: "Cal".to_string(), | ||
age: 17, | ||
gender: Gender::NonBinary, | ||
}; | ||
let response = client | ||
.post("/age_named") | ||
.body(rmp_serde::to_vec_named(&person).unwrap()) | ||
.dispatch() | ||
.into_bytes() | ||
.unwrap(); | ||
let mut bytes = rmp::decode::Bytes::new(&response); | ||
assert_eq!(rmp::decode::read_map_len(&mut bytes).unwrap(), 3); | ||
assert_eq!(&read_string(&mut bytes), "name"); | ||
assert_eq!(&read_string(&mut bytes), "Cal"); | ||
assert_eq!(&read_string(&mut bytes), "age"); | ||
assert_eq!(rmp::decode::read_int::<u8, _>(&mut bytes).unwrap(), 18); | ||
assert_eq!(&read_string(&mut bytes), "gender"); | ||
// Enums are complicated in serde. In this test, they're encoded like this: | ||
// (JSON equivalent) `{ "gender": "NonBinary" }`, where that object is itself | ||
// the value of the `gender` key in the outer object. `#[serde(flatten)]` | ||
// on the `gender` key in the outer object fixes this, but it prevents `rmp` | ||
// from using compact mode, which would break the test. | ||
assert_eq!(rmp::decode::read_map_len(&mut bytes).unwrap(), 1); | ||
assert_eq!(&read_string(&mut bytes), "gender"); | ||
assert_eq!(&read_string(&mut bytes), "NonBinary"); | ||
} | ||
|
||
#[test] | ||
fn check_compact_roundtrip() { | ||
let client = Client::debug(rocket()).unwrap(); | ||
let person = Person { | ||
name: "Maeve".to_string(), | ||
age: 15, | ||
gender: Gender::Female, | ||
}; | ||
let response = client | ||
.post("/age_compact") | ||
.body(rmp_serde::to_vec(&person).unwrap()) | ||
.dispatch() | ||
.into_bytes() | ||
.unwrap(); | ||
let mut bytes = rmp::decode::Bytes::new(&response); | ||
assert_eq!(rmp::decode::read_array_len(&mut bytes).unwrap(), 3); | ||
assert_eq!(&read_string(&mut bytes), "Maeve"); | ||
assert_eq!(rmp::decode::read_int::<u8, _>(&mut bytes).unwrap(), 16); | ||
// Equivalent to the named representation, gender here is encoded like this: | ||
// `[ "Female" ]`. | ||
assert_eq!(rmp::decode::read_array_len(&mut bytes).unwrap(), 1); | ||
assert_eq!(&read_string(&mut bytes), "Female"); | ||
} |