mirror of https://github.com/rwf2/Rocket.git
parent
8f2ee138ea
commit
a474fde85b
|
@ -92,6 +92,26 @@ impl StatusClass {
|
|||
/// ```
|
||||
///
|
||||
/// [`response::status`]: ../response/status/index.html
|
||||
///
|
||||
/// # (De)serialization
|
||||
///
|
||||
/// `Status` is both `Serialize` and `Deserialize`, represented as a `u16`. For
|
||||
/// example, [`Status::Ok`] (de)serializes from/to `200`. Any integer in the
|
||||
/// range `[100, 600)` is allowed to deserialize into a `Status`.`
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[cfg(feature = "serde")] mod serde {
|
||||
/// # use serde_ as serde;
|
||||
/// use serde::{Serialize, Deserialize};
|
||||
/// use rocket::http::Status;
|
||||
///
|
||||
/// #[derive(Deserialize, Serialize)]
|
||||
/// # #[serde(crate = "serde_")]
|
||||
/// struct Foo {
|
||||
/// status: Status,
|
||||
/// }
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Status {
|
||||
/// The HTTP status code associated with this status.
|
||||
|
@ -359,3 +379,50 @@ impl Ord for Status {
|
|||
self.code.cmp(&other.code)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
mod serde {
|
||||
use std::fmt;
|
||||
use super::*;
|
||||
|
||||
use serde_::ser::{Serialize, Serializer};
|
||||
use serde_::de::{Deserialize, Deserializer, Error, Visitor, Unexpected};
|
||||
|
||||
impl<'a> Serialize for Status {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_u16(self.code)
|
||||
}
|
||||
}
|
||||
|
||||
struct DeVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for DeVisitor {
|
||||
type Value = Status;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(formatter, "HTTP status code integer in range [100, 600)")
|
||||
}
|
||||
|
||||
fn visit_i64<E: Error>(self, v: i64) -> Result<Self::Value, E> {
|
||||
if v < 100 || v >= 600 {
|
||||
return Err(E::invalid_value(Unexpected::Signed(v), &self));
|
||||
}
|
||||
|
||||
Ok(Status::new(v as u16))
|
||||
}
|
||||
|
||||
fn visit_u64<E: Error>(self, v: u64) -> Result<Self::Value, E> {
|
||||
if v < 100 || v >= 600 {
|
||||
return Err(E::invalid_value(Unexpected::Unsigned(v), &self));
|
||||
}
|
||||
|
||||
Ok(Status::new(v as u16))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Status {
|
||||
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
deserializer.deserialize_u16(DeVisitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use pretty_assertions::assert_eq;
|
|||
|
||||
use rocket::{Config, uri};
|
||||
use rocket::http::uri::{Absolute, Asterisk, Authority, Origin, Reference};
|
||||
use rocket::http::Method;
|
||||
use rocket::http::{Method, Status};
|
||||
|
||||
#[derive(PartialEq, Debug, Serialize, Deserialize)]
|
||||
struct UriContainer<'a> {
|
||||
|
@ -31,6 +31,13 @@ struct MethodContainer {
|
|||
mpost: Method,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Serialize, Deserialize)]
|
||||
struct StatusContainer {
|
||||
a: Status,
|
||||
b: Status,
|
||||
c: Status,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uri_serde() {
|
||||
figment::Jail::expect_with(|jail| {
|
||||
|
@ -148,3 +155,52 @@ fn method_serde() {
|
|||
Ok(())
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn status_serde() {
|
||||
figment::Jail::expect_with(|jail| {
|
||||
jail.create_file("Rocket.toml", r#"
|
||||
[default]
|
||||
a = 500
|
||||
b = 100
|
||||
c = 404
|
||||
"#)?;
|
||||
|
||||
let statuses: StatusContainer = Config::figment().extract()?;
|
||||
assert_eq!(statuses, StatusContainer {
|
||||
a: Status::InternalServerError,
|
||||
b: Status::Continue,
|
||||
c: Status::NotFound
|
||||
});
|
||||
|
||||
let tmp = Figment::from(Serialized::defaults(statuses));
|
||||
let statuses: StatusContainer = tmp.extract()?;
|
||||
assert_eq!(statuses, StatusContainer {
|
||||
a: Status::InternalServerError,
|
||||
b: Status::Continue,
|
||||
c: Status::NotFound
|
||||
});
|
||||
|
||||
jail.create_file("Rocket.toml", r#"
|
||||
[default]
|
||||
a = 99
|
||||
b = 100
|
||||
c = 404
|
||||
"#)?;
|
||||
|
||||
let statuses: Result<StatusContainer, _> = Config::figment().extract();
|
||||
assert!(statuses.is_err());
|
||||
|
||||
jail.create_file("Rocket.toml", r#"
|
||||
[default]
|
||||
a = 500
|
||||
b = 100
|
||||
c = 600
|
||||
"#)?;
|
||||
|
||||
let statuses: Result<StatusContainer, _> = Config::figment().extract();
|
||||
assert!(statuses.is_err());
|
||||
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue