pub use tycho_util_proc::PartialConfig;
pub trait PartialConfig: Sized {
type Partial: serde::Serialize;
fn into_partial(self) -> Self::Partial;
}
impl<T: PartialConfig> PartialConfig for Option<T> {
type Partial = Option<T::Partial>;
#[inline]
fn into_partial(self) -> Self::Partial {
self.map(T::into_partial)
}
}
#[cfg(test)]
mod tests {
use serde::Serialize;
use super::*;
#[derive(Clone, Copy, PartialConfig, Serialize, PartialEq, Eq)]
struct RootConfig {
#[important]
important_field: usize,
default_field: usize,
#[partial]
subconfig: SubConfig,
}
impl Default for RootConfig {
fn default() -> Self {
Self {
important_field: 123,
default_field: 456,
subconfig: Default::default(),
}
}
}
#[derive(Clone, Copy, PartialConfig, Serialize, PartialEq, Eq)]
struct SubConfig {
#[important]
important_field2: usize,
default_field2: usize,
}
impl Default for SubConfig {
fn default() -> Self {
Self {
important_field2: 789,
default_field2: 12,
}
}
}
#[test]
fn partial_config_works() {
let root_config = RootConfig::default();
#[allow(unused)]
let RootConfigPartial {
important_field,
subconfig: SubConfigPartial { important_field2 },
} = root_config.into_partial();
let json = serde_json::to_string(&root_config.into_partial()).unwrap();
assert_eq!(
json,
r#"{"important_field":123,"subconfig":{"important_field2":789}}"#
);
}
#[derive(Default, Clone, Copy, PartialConfig, Serialize, PartialEq, Eq)]
struct NewtypeConfig(#[partial] SubConfig);
#[test]
fn newtype_parsing_works() {
let tuple_config = NewtypeConfig::default();
#[allow(unused)]
let NewtypeConfigPartial(SubConfigPartial { important_field2 }) =
tuple_config.into_partial();
let json = serde_json::to_string(&tuple_config.into_partial()).unwrap();
assert_eq!(json, r#"{"important_field2":789}"#);
}
}