Allow non-breaking config additions.

If stars aligned properly, we might imagine writing this:

    #[non_exhaustive]
    struct Config {
        pub field: Foo,
        pub other: Bar,
    }

...with semantics that would allow the defining crate (here, Rocket), to
construct the structure directly while consumers would need to use
public constructors or struct update syntax:

    Config {
        field: Foo,
        other: Bar,
        ..Default::default()
    }

Alas, this is not the way `non_exhaustive` works on structs. You cannot
use field-update syntax to construct `Config` above. You must use public
constructors. This means builder methods or mutating an already built
struct. This is not what we want.

I don't know why it works this way. I don't see why it must. Something
something Drop.

So we have this hack from the pre-non_exhaustive era.
This commit is contained in:
Sergio Benitez 2021-06-07 19:01:22 -07:00
parent 5f50d5e232
commit 333da45470
2 changed files with 37 additions and 1 deletions

View File

@ -92,6 +92,22 @@ pub struct Config {
/// Whether to use colors and emoji when logging. **(default: `true`)** /// Whether to use colors and emoji when logging. **(default: `true`)**
#[serde(deserialize_with = "figment::util::bool_from_str_or_int")] #[serde(deserialize_with = "figment::util::bool_from_str_or_int")]
pub cli_colors: bool, pub cli_colors: bool,
/// PRIVATE: This structure may grow (but never change otherwise) in a
/// non-breaking release. As such, constructing this structure should
/// _always_ be done using a public constructor or update syntax:
///
/// ```rust
/// use rocket::Config;
///
/// let config = Config {
/// port: 1024,
/// keep_alive: 10,
/// ..Default::default()
/// };
/// ```
#[doc(hidden)]
#[serde(skip)]
pub __non_exhaustive: (),
} }
impl Default for Config { impl Default for Config {
@ -150,8 +166,9 @@ impl Config {
secret_key: SecretKey::zero(), secret_key: SecretKey::zero(),
temp_dir: std::env::temp_dir(), temp_dir: std::env::temp_dir(),
log_level: LogLevel::Normal, log_level: LogLevel::Normal,
cli_colors: true,
shutdown: Shutdown::default(), shutdown: Shutdown::default(),
cli_colors: true,
__non_exhaustive: (),
} }
} }

View File

@ -188,6 +188,7 @@ impl fmt::Display for Sig {
/// grace: 10, /// grace: 10,
/// mercy: 5, /// mercy: 5,
/// force: true, /// force: true,
/// ..Default::default()
/// }, /// },
/// ..Config::default() /// ..Config::default()
/// }; /// };
@ -236,7 +237,24 @@ pub struct Shutdown {
/// cooperate. /// cooperate.
/// ///
/// **default: `true`** /// **default: `true`**
#[serde(deserialize_with = "figment::util::bool_from_str_or_int")]
pub force: bool, pub force: bool,
/// PRIVATE: This structure may grow (but never change otherwise) in a
/// non-breaking release. As such, constructing this structure should
/// _always_ be done using a public constructor or update syntax:
///
/// ```rust
/// use rocket::config::Shutdown;
///
/// let config = Shutdown {
/// grace: 5,
/// mercy: 10,
/// ..Default::default()
/// };
/// ```
#[doc(hidden)]
#[serde(skip)]
pub __non_exhaustive: (),
} }
impl fmt::Display for Shutdown { impl fmt::Display for Shutdown {
@ -266,6 +284,7 @@ impl Default for Shutdown {
grace: 2, grace: 2,
mercy: 3, mercy: 3,
force: true, force: true,
__non_exhaustive: (),
} }
} }
} }