mirror of https://github.com/rwf2/Rocket.git
Implement 'De(Serialize)' for 'Method'.
This commit is contained in:
parent
ca655051ba
commit
d2c2725689
|
@ -3,9 +3,30 @@ use std::str::FromStr;
|
|||
|
||||
use self::Method::*;
|
||||
|
||||
// TODO: Support non-standard methods, here and in codegen.
|
||||
// TODO: Support non-standard methods, here and in codegen?
|
||||
|
||||
/// Representation of HTTP methods.
|
||||
///
|
||||
/// # (De)serialization
|
||||
///
|
||||
/// `Method` is both `Serialize` and `Deserialize`, represented as an
|
||||
/// [uncased](crate::uncased) string. For example, [`Method::Get`] serializes to
|
||||
/// `"GET"` and deserializes from any casing of `"GET"` including `"get"`,
|
||||
/// `"GeT"`, and `"GET"`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[cfg(feature = "serde")] mod serde {
|
||||
/// # use serde_ as serde;
|
||||
/// use serde::{Serialize, Deserialize};
|
||||
/// use rocket::http::Method;
|
||||
///
|
||||
/// #[derive(Deserialize, Serialize)]
|
||||
/// # #[serde(crate = "serde_")]
|
||||
/// struct Foo {
|
||||
/// method: Method,
|
||||
/// }
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum Method {
|
||||
/// The `GET` variant.
|
||||
|
@ -127,3 +148,38 @@ impl fmt::Display for Method {
|
|||
self.as_str().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[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 Method {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_str(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
struct DeVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for DeVisitor {
|
||||
type Value = Method;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(formatter, "valid HTTP method string")
|
||||
}
|
||||
|
||||
fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
|
||||
Method::from_str(v).map_err(|_| E::invalid_value(Unexpected::Str(v), &self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Method {
|
||||
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
deserializer.deserialize_str(DeVisitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ use pretty_assertions::assert_eq;
|
|||
|
||||
use rocket::{Config, uri};
|
||||
use rocket::http::uri::{Absolute, Asterisk, Authority, Origin, Reference};
|
||||
use rocket::http::Method;
|
||||
|
||||
#[derive(PartialEq, Debug, Serialize, Deserialize)]
|
||||
struct UriContainer<'a> {
|
||||
|
@ -23,6 +24,13 @@ struct UriContainerOwned {
|
|||
reference: Reference<'static>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Serialize, Deserialize)]
|
||||
struct MethodContainer {
|
||||
mget: Method,
|
||||
mput: Method,
|
||||
mpost: Method,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uri_serde() {
|
||||
figment::Jail::expect_with(|jail| {
|
||||
|
@ -111,3 +119,32 @@ fn uri_serde_round_trip() {
|
|||
reference: uri!("https://rocket.rs:8000/index.html").into(),
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn method_serde() {
|
||||
figment::Jail::expect_with(|jail| {
|
||||
jail.create_file("Rocket.toml", r#"
|
||||
[default]
|
||||
mget = "GET"
|
||||
mput = "PuT"
|
||||
mpost = "post"
|
||||
"#)?;
|
||||
|
||||
let methods: MethodContainer = Config::figment().extract()?;
|
||||
assert_eq!(methods, MethodContainer {
|
||||
mget: Method::Get,
|
||||
mput: Method::Put,
|
||||
mpost: Method::Post
|
||||
});
|
||||
|
||||
let tmp = Figment::from(Serialized::defaults(methods));
|
||||
let methods: MethodContainer = tmp.extract()?;
|
||||
assert_eq!(methods, MethodContainer {
|
||||
mget: Method::Get,
|
||||
mput: Method::Put,
|
||||
mpost: Method::Post
|
||||
});
|
||||
|
||||
Ok(())
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue