Skip to content

Commit

Permalink
Try out serde's new #[serde(untagged)] attribute on enum variants.
Browse files Browse the repository at this point in the history
  • Loading branch information
azriel91 committed Jun 16, 2023
1 parent 7a46d5d commit 3f42051
Show file tree
Hide file tree
Showing 18 changed files with 263 additions and 402 deletions.
50 changes: 23 additions & 27 deletions crate/params/src/params_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,6 @@ where
/// If no value spec was previously serialized, then the command
/// context build will return an error.
Stored,
/// Uses the provided value.
///
/// The value used is whatever is passed in to the command context
/// builder.
Value {
/// The value to use.
value: T,
},
/// Uses a value loaded from `resources` at runtime.
///
/// The value may have been provided by workspace params, or
Expand All @@ -71,6 +63,12 @@ where
/// the user must provide the `MappingFn` in subsequent command
/// context builds.
MappingFn(Box<dyn MappingFn<Output = T>>),
/// Uses the provided value.
///
/// The value used is whatever is passed in to the command context
/// builder.
#[serde(untagged)]
Value(T),
/// Resolves this value through `ValueSpec`s for each of its fields.
///
/// This is like `T`, but with each field wrapped in
Expand All @@ -87,10 +85,8 @@ where
//
// There shouldn't need to be automatic detection of non-recursive fields for stdlib types,
// because `peace_params` should just implement `ValueSpec` for those types.
FieldWise {
/// The field wise spec.
field_wise_spec: T::FieldWiseSpec,
},
#[serde(untagged)]
FieldWise(T::FieldWiseSpec),
}

impl<T> ParamsSpec<T>
Expand All @@ -113,10 +109,10 @@ where
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Stored => f.write_str("Stored"),
Self::Value { value } => f.debug_tuple("Value").field(value).finish(),
Self::InMemory => f.write_str("InMemory"),
Self::MappingFn(mapping_fn) => f.debug_tuple("MappingFn").field(mapping_fn).finish(),
Self::FieldWise { field_wise_spec } => {
Self::Value(value) => f.debug_tuple("Value").field(value).finish(),
Self::FieldWise(field_wise_spec) => {
f.debug_tuple("FieldWise").field(field_wise_spec).finish()
}
}
Expand All @@ -128,7 +124,7 @@ where
T: Params + Clone + Debug + Send + Sync + 'static,
{
fn from(value: T) -> Self {
Self::Value { value }
Self::Value(value)
}
}

Expand All @@ -143,7 +139,6 @@ where
value_resolution_ctx: &mut ValueResolutionCtx,
) -> Result<T, ParamsResolveError> {
match self {
ParamsSpec::Value { value } => Ok(value.clone()),
ParamsSpec::Stored | ParamsSpec::InMemory => match resources.try_borrow::<T>() {
Ok(value) => Ok((*value).clone()),
Err(borrow_fail) => match borrow_fail {
Expand All @@ -158,7 +153,8 @@ where
},
},
ParamsSpec::MappingFn(mapping_fn) => mapping_fn.map(resources, value_resolution_ctx),
ParamsSpec::FieldWise { field_wise_spec } => {
ParamsSpec::Value(value) => Ok(value.clone()),
ParamsSpec::FieldWise(field_wise_spec) => {
field_wise_spec.resolve(resources, value_resolution_ctx)
}
}
Expand All @@ -170,7 +166,6 @@ where
value_resolution_ctx: &mut ValueResolutionCtx,
) -> Result<T::Partial, ParamsResolveError> {
match self {
ParamsSpec::Value { value } => Ok(T::Partial::from((*value).clone())),
ParamsSpec::Stored | ParamsSpec::InMemory => match resources.try_borrow::<T>() {
Ok(value) => Ok(T::Partial::from((*value).clone())),
Err(borrow_fail) => match borrow_fail {
Expand All @@ -187,7 +182,8 @@ where
ParamsSpec::MappingFn(mapping_fn) => mapping_fn
.try_map(resources, value_resolution_ctx)
.map(|t| t.map(T::Partial::from).unwrap_or_else(T::Partial::default)),
ParamsSpec::FieldWise { field_wise_spec } => {
ParamsSpec::Value(value) => Ok(T::Partial::from((*value).clone())),
ParamsSpec::FieldWise(field_wise_spec) => {
field_wise_spec.resolve_partial(resources, value_resolution_ctx)
}
}
Expand All @@ -208,9 +204,9 @@ where
fn is_usable(&self) -> bool {
match self {
Self::Stored => false,
Self::Value { .. } | Self::InMemory => true,
Self::InMemory | Self::Value(_) => true,
Self::MappingFn(mapping_fn) => mapping_fn.is_valued(),
Self::FieldWise { field_wise_spec } => field_wise_spec.is_usable(),
Self::FieldWise(field_wise_spec) => field_wise_spec.is_usable(),
}
}

Expand All @@ -230,18 +226,18 @@ where
Self::Stored => *self = other.clone(),

// Use set value / no change on these variants
Self::Value { .. } | Self::InMemory | Self::MappingFn(_) => {}
Self::InMemory | Self::MappingFn(_) | Self::Value(_) => {}

//
Self::FieldWise { field_wise_spec } => {
Self::FieldWise(field_wise_spec) => {
match other {
// Don't merge stored field wise specs over provided specs.
Self::Stored | Self::Value { .. } | Self::InMemory | Self::MappingFn(_) => {}
Self::Stored | Self::InMemory | Self::MappingFn(_) | Self::Value(_) => {}

// Merge specs fieldwise.
Self::FieldWise {
field_wise_spec: field_wise_spec_other,
} => AnySpecRt::merge(field_wise_spec, field_wise_spec_other),
Self::FieldWise(field_wise_spec_other) => {
AnySpecRt::merge(field_wise_spec, field_wise_spec_other)
}
}
}
}
Expand Down
30 changes: 12 additions & 18 deletions crate/params/src/params_spec_de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ where
/// If no value spec was previously serialized, then the command
/// context build will return an error.
Stored,
/// Uses the provided value.
///
/// The value used is whatever is passed in to the command context
/// builder.
Value {
/// The value to use.
value: T,
},
/// Uses a value loaded from `resources` at runtime.
///
/// The value may have been provided by workspace params, or
Expand All @@ -42,13 +34,17 @@ where
/// Look up some data populated by a predecessor, and compute the value
/// from that data.
MappingFn(MappingFnImpl<T, FnPlaceholder<T>, ((),)>),
/// Uses the provided value.
///
/// The value used is whatever is passed in to the command context
/// builder.
#[serde(untagged)]
Value(T),
/// Resolves this value through `ValueSpec`s for each of its fields.
///
/// This is like `T`, but with each field wrapped in `ValueSpecDe<T>`.
FieldWise {
/// The field wise spec.
field_wise_spec: T::FieldWiseSpec,
},
#[serde(untagged)]
FieldWise(T::FieldWiseSpec),
}

impl<T> Debug for ParamsSpecDe<T>
Expand All @@ -58,12 +54,12 @@ where
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Stored => f.write_str("Stored"),
Self::Value { value } => f.debug_tuple("Value").field(value).finish(),
Self::InMemory => f.write_str("InMemory"),
Self::MappingFn(mapping_fn_impl) => {
f.debug_tuple("MappingFn").field(&mapping_fn_impl).finish()
}
Self::FieldWise { field_wise_spec } => {
Self::Value(value) => f.debug_tuple("Value").field(value).finish(),
Self::FieldWise(field_wise_spec) => {
f.debug_tuple("FieldWise").field(field_wise_spec).finish()
}
}
Expand All @@ -77,14 +73,12 @@ where
fn from(value_spec_de: ParamsSpecDe<T>) -> Self {
match value_spec_de {
ParamsSpecDe::Stored => ParamsSpec::Stored,
ParamsSpecDe::Value { value } => ParamsSpec::Value { value },
ParamsSpecDe::Value(value) => ParamsSpec::Value(value),
ParamsSpecDe::InMemory => ParamsSpec::InMemory,
ParamsSpecDe::MappingFn(mapping_fn_impl) => {
ParamsSpec::MappingFn(Box::new(mapping_fn_impl))
}
ParamsSpecDe::FieldWise { field_wise_spec } => {
ParamsSpec::FieldWise { field_wise_spec }
}
ParamsSpecDe::FieldWise(field_wise_spec) => ParamsSpec::FieldWise(field_wise_spec),
}
}
}
26 changes: 12 additions & 14 deletions crate/params/src/params_spec_fieldless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,6 @@ where
/// If no value spec was previously serialized, then the command
/// context build will return an error.
Stored,
/// Uses the provided value.
///
/// The value used is whatever is passed in to the command context
/// builder.
Value {
/// The value to use.
value: T,
},
/// Uses a value loaded from `resources` at runtime.
///
/// The value may have been provided by workspace params, or
Expand All @@ -72,6 +64,12 @@ where
/// the user must provide the `MappingFn` in subsequent command
/// context builds.
MappingFn(Box<dyn MappingFn<Output = T>>),
/// Uses the provided value.
///
/// The value used is whatever is passed in to the command context
/// builder.
#[serde(untagged)]
Value(T),
}

impl<T> ParamsSpecFieldless<T>
Expand All @@ -94,9 +92,9 @@ where
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Stored => f.write_str("Stored"),
Self::Value { value } => f.debug_tuple("Value").field(value).finish(),
Self::InMemory => f.write_str("InMemory"),
Self::MappingFn(mapping_fn) => f.debug_tuple("MappingFn").field(mapping_fn).finish(),
Self::Value(value) => f.debug_tuple("Value").field(value).finish(),
}
}
}
Expand All @@ -106,7 +104,7 @@ where
T: ParamsFieldless + Clone + Debug + Send + Sync + 'static,
{
fn from(value: T) -> Self {
Self::Value { value }
Self::Value(value)
}
}

Expand All @@ -121,7 +119,6 @@ where
value_resolution_ctx: &mut ValueResolutionCtx,
) -> Result<T, ParamsResolveError> {
match self {
ParamsSpecFieldless::Value { value } => Ok(value.clone()),
ParamsSpecFieldless::Stored | ParamsSpecFieldless::InMemory => {
match resources.try_borrow::<T>() {
Ok(value) => Ok((*value).clone()),
Expand All @@ -140,6 +137,7 @@ where
ParamsSpecFieldless::MappingFn(mapping_fn) => {
mapping_fn.map(resources, value_resolution_ctx)
}
ParamsSpecFieldless::Value(value) => Ok(value.clone()),
}
}

Expand All @@ -149,7 +147,6 @@ where
value_resolution_ctx: &mut ValueResolutionCtx,
) -> Result<T::Partial, ParamsResolveError> {
match self {
ParamsSpecFieldless::Value { value } => Ok(T::Partial::from((*value).clone())),
ParamsSpecFieldless::Stored | ParamsSpecFieldless::InMemory => {
match resources.try_borrow::<T>() {
Ok(value) => Ok(T::Partial::from((*value).clone())),
Expand All @@ -168,6 +165,7 @@ where
ParamsSpecFieldless::MappingFn(mapping_fn) => mapping_fn
.try_map(resources, value_resolution_ctx)
.map(|t| t.map(T::Partial::from).unwrap_or_else(T::Partial::default)),
ParamsSpecFieldless::Value(value) => Ok(T::Partial::from((*value).clone())),
}
}
}
Expand All @@ -185,8 +183,8 @@ where
fn is_usable(&self) -> bool {
match self {
Self::Stored => false,
Self::Value { .. } | Self::InMemory => true,
Self::MappingFn(mapping_fn) => mapping_fn.is_valued(),
Self::Value(_) | Self::InMemory => true,
}
}

Expand All @@ -205,7 +203,7 @@ where
Self::Stored => *self = other.clone(),

// Use set value / no change on these variants
Self::Value { .. } | Self::InMemory | Self::MappingFn(_) => {}
Self::InMemory | Self::MappingFn(_) | Self::Value(_) => {}
}
}
}
Expand Down
18 changes: 8 additions & 10 deletions crate/params/src/params_spec_fieldless_de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ where
/// If no value spec was previously serialized, then the command
/// context build will return an error.
Stored,
/// Uses the provided value.
///
/// The value used is whatever is passed in to the command context
/// builder.
Value {
/// The value to use.
value: T,
},
/// Uses a value loaded from `resources` at runtime.
///
/// The value may have been provided by workspace params, or
Expand All @@ -42,6 +34,12 @@ where
/// Look up some data populated by a predecessor, and compute the value
/// from that data.
MappingFn(MappingFnImpl<T, FnPlaceholder<T>, ((),)>),
/// Uses the provided value.
///
/// The value used is whatever is passed in to the command context
/// builder.
#[serde(untagged)]
Value(T),
}

impl<T> Debug for ParamsSpecFieldlessDe<T>
Expand All @@ -51,11 +49,11 @@ where
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Stored => f.write_str("Stored"),
Self::Value { value } => f.debug_tuple("Value").field(value).finish(),
Self::InMemory => f.write_str("InMemory"),
Self::MappingFn(mapping_fn_impl) => {
f.debug_tuple("MappingFn").field(&mapping_fn_impl).finish()
}
Self::Value(value) => f.debug_tuple("Value").field(value).finish(),
}
}
}
Expand All @@ -67,11 +65,11 @@ where
fn from(value_spec_de: ParamsSpecFieldlessDe<T>) -> Self {
match value_spec_de {
ParamsSpecFieldlessDe::Stored => ParamsSpecFieldless::Stored,
ParamsSpecFieldlessDe::Value { value } => ParamsSpecFieldless::Value { value },
ParamsSpecFieldlessDe::InMemory => ParamsSpecFieldless::InMemory,
ParamsSpecFieldlessDe::MappingFn(mapping_fn_impl) => {
ParamsSpecFieldless::MappingFn(Box::new(mapping_fn_impl))
}
ParamsSpecFieldlessDe::Value(value) => ParamsSpecFieldless::Value(value),
}
}
}

0 comments on commit 3f42051

Please sign in to comment.