Implement Deserialize for rocket::Config

This commit is contained in:
Ryan Leckey 2017-06-16 14:09:01 -07:00
parent 3fcf6c43dc
commit f73649f703
5 changed files with 127 additions and 2 deletions

View File

@ -34,6 +34,8 @@ rustls = { version = "0.8.0", optional = true }
cookie = { version = "0.8.1", features = ["percent-encode", "secure"] }
hyper = { version = "0.10.11", default-features = false }
ordermap = "0.2"
serde = "^1.0.8"
serde_derive = "^1.0.8"
[dependencies.hyper-rustls]
git = "https://github.com/SergioBenitez/hyper-rustls"

View File

@ -770,3 +770,124 @@ impl PartialEq for Config {
&& self.extras == other.extras
}
}
impl<'de> ::serde::de::Deserialize<'de> for Config {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where D: ::serde::de::Deserializer<'de>
{
struct ConfigVisitor;
#[derive(Deserialize)]
struct TlsRawConfig {
certs: String,
key: String,
}
impl<'de> ::serde::de::Visitor<'de> for ConfigVisitor {
type Value = Config;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct Config")
}
fn visit_map<V>(self, mut map: V) -> ::std::result::Result<Config, V::Error>
where V: ::serde::de::MapAccess<'de>
{
let mut environment: Option<Environment> = None;
let mut address: Option<String> = None;
let mut port: Option<u16> = None;
let mut workers: Option<u16> = None;
let mut log_level: Option<LoggingLevel> = None;
let mut secret_key: Option<String> = None;
let mut tls: Option<TlsRawConfig> = None;
let mut limits: Option<Limits> = None;
let mut extras = HashMap::<String, Value>::new();
while let Some(key) = map.next_key::<String>()?.as_ref() {
let key: &str = &*key;
match key {
"environment" => {
let env_str: String = map.next_value()?;
environment = Some(env_str.parse().map_err(|_| {
::serde::de::Error::invalid_value(::serde::de::Unexpected::Str(&env_str), &self)
})?);
},
"address" => {
address = map.next_value()?;
},
"port" => {
port = map.next_value()?;
},
"workers" => {
workers = map.next_value()?;
}
"log_level" => {
log_level = map.next_value()?;
}
"secret_key" => {
secret_key = map.next_value()?;
}
"tls" => {
tls = map.next_value()?;
}
"limits" => {
limits = map.next_value()?;
}
_ => {
extras.insert(key.into(), map.next_value()?);
}
}
}
// FIXME: Remove unwrap
let mut config = Config::new(
environment.unwrap_or_else(|| Environment::active().unwrap())).unwrap();
config.set_extras(extras);
if let Some(address) = address {
// FIXME: Remove unwrap
config.set_address(address).unwrap();
}
if let Some(port) = port {
config.set_port(port);
}
if let Some(workers) = workers {
config.set_workers(workers);
}
if let Some(log_level) = log_level {
config.set_log_level(log_level);
}
if let Some(secret_key) = secret_key {
// FIXME: Remove unwrap
config.set_secret_key(secret_key).unwrap();
}
if let Some(tls) = tls {
// FIXME: Remove unwrap
config.set_tls(&tls.certs, &tls.key).unwrap();
}
if let Some(limits) = limits {
config.set_limits(limits);
}
Ok(config)
}
}
deserializer.deserialize_map(ConfigVisitor)
}
}

View File

@ -76,7 +76,7 @@ pub struct TlsConfig;
/// .limit("forms", 64 * 1024)
/// .limit("json", 3 * 1024 * 1024);
/// ```
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Deserialize)]
pub struct Limits {
// We cache this internally but don't share that fact in the API.
pub(crate) forms: u64,

View File

@ -116,6 +116,8 @@ extern crate memchr;
extern crate base64;
extern crate smallvec;
extern crate ordermap;
extern crate serde;
#[macro_use] extern crate serde_derive;
#[cfg(test)] #[macro_use] extern crate lazy_static;

View File

@ -9,7 +9,7 @@ use yansi::Color::*;
struct RocketLogger(LoggingLevel);
/// Defines the different levels for log messages.
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
#[derive(PartialEq, Eq, Debug, Clone, Copy, Deserialize)]
pub enum LoggingLevel {
/// Only shows errors and warning.
Critical,