diff --git a/src/ondisk.rs b/src/ondisk.rs index 76f417b..eb31427 100644 --- a/src/ondisk.rs +++ b/src/ondisk.rs @@ -1271,6 +1271,28 @@ macro_rules! make_bitfield_serde {( )* } } + + #[cfg(feature = "serde")] + paste::paste!{ + /// Use this for serialization in order to make serde skip those + /// fields where the meaning of a raw value is unknown to us. + /// + /// Caller can then override Serializer::skip_field and thus find out + /// which fields were skipped, inferring where errors were. + #[doc(hidden)] + #[allow(non_camel_case_types)] + #[cfg_attr(feature = "serde", derive(Serialize))] + #[cfg_attr(feature = "serde", serde(rename = "" $StructName))] + pub(crate) struct [] { + $( + $(#[serde(skip_serializing_if="Option::is_none")] + pub $field_name: Option<$field_ty>,)? + $(#[serde(skip_serializing_if="Option::is_none")] + $(#[$serde_field_orig_meta])* + pub $field_name: Option<$serde_ty>,)? + )* + } + } }} make_bitfield_serde! { @@ -2657,21 +2679,11 @@ pub mod memory { #[repr(u32)] #[derive(Clone, Copy)] pub struct RdimmDdr4Voltages { - pub _1_2V || #[serde(default)] bool : bool | pub get bool : pub set bool, + pub _1_2V || #[serde(default)] #[serde(rename = "1.2 V")] bool : bool | pub get bool : pub set bool, pub _reserved_1 || #[serde(default)] SerdeHex32 : B31, // all = 7 } } - #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] - #[cfg_attr(feature = "serde", serde(deny_unknown_fields))] - #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] - #[cfg_attr(feature = "serde", serde(rename = "RdimmDdr4Voltages"))] - pub struct CustomSerdeRdimmDdr4Voltages { - #[cfg_attr(feature = "serde", serde(rename = "1.2 V"))] - pub _1_2V: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub _reserved_1: u32, - } macro_rules! define_compat_bitfield_field { ($compat_field:ident, $current_field:ident) => { paste! { @@ -2820,27 +2832,13 @@ pub mod memory { #[repr(u32)] #[derive(Clone, Copy)] pub struct UdimmDdr4Voltages { - pub _1_5V || #[serde(default)] bool : bool | pub get bool : pub set bool, - pub _1_35V || #[serde(default)] bool : bool | pub get bool : pub set bool, - pub _1_25V || #[serde(default)] bool : bool | pub get bool : pub set bool, + pub _1_5V || #[serde(default)] #[serde(rename = "1.5 V")] bool : bool | pub get bool : pub set bool, + pub _1_35V || #[serde(default)] #[serde(rename = "1.35 V")] bool : bool | pub get bool : pub set bool, + pub _1_25V || #[serde(default)] #[serde(rename = "1.25 V")] bool : bool | pub get bool : pub set bool, // all = 7 pub _reserved_1 || #[serde(default)] SerdeHex32 : B29, } } - #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] - #[cfg_attr(feature = "serde", serde(deny_unknown_fields))] - #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] - #[cfg_attr(feature = "serde", serde(rename = "UdimmDdr4Voltages"))] - pub struct CustomSerdeUdimmDdr4Voltages { - #[cfg_attr(feature = "serde", serde(rename = "1.5 V"))] - pub _1_5V: bool, - #[cfg_attr(feature = "serde", serde(rename = "1.35 V"))] - pub _1_35V: bool, - #[cfg_attr(feature = "serde", serde(rename = "1.25 V"))] - pub _1_25V: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub _reserved_1: u32, - } impl UdimmDdr4Voltages { define_compat_bitfield_field!(v_1_5, _1_5V); define_compat_bitfield_field!(v_1_35, _1_35V); @@ -2915,21 +2913,11 @@ pub mod memory { #[repr(u32)] #[derive(Clone, Copy)] pub struct LrdimmDdr4Voltages { - pub _1_2V || #[serde(default)] bool : bool | pub get bool : pub set bool, + pub _1_2V || #[serde(default)] #[serde(rename = "1.2 V")] bool : bool | pub get bool : pub set bool, // all = 7 pub _reserved_1 || #[serde(default)] SerdeHex32 : B31, } } - #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] - #[cfg_attr(feature = "serde", serde(deny_unknown_fields))] - #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] - #[cfg_attr(feature = "serde", serde(rename = "LrdimmDdr4Voltages"))] - pub struct CustomSerdeLrdimmDdr4Voltages { - #[cfg_attr(feature = "serde", serde(rename = "1.2 V"))] - pub _1_2V: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub _reserved_1: u32, - } impl LrdimmDdr4Voltages { define_compat_bitfield_field!(v_1_2, _1_2V); @@ -3843,7 +3831,7 @@ pub mod memory { } } #[cfg(feature = "serde")] - #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + #[cfg_attr(feature = "serde", derive(Deserialize))] #[cfg_attr(feature = "serde", serde(deny_unknown_fields))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "serde", serde(rename = "ErrorOutControlBeepCode"))] @@ -3853,6 +3841,14 @@ pub mod memory { pub peak_attr: ErrorOutControlBeepCodePeakAttr, } #[cfg(feature = "serde")] + #[cfg_attr(feature = "serde", derive(Serialize))] + #[cfg_attr(feature = "serde", serde(rename = "ErrorOutControlBeepCode"))] + pub(crate) struct CustomSerdePermissiveSerializingErrorOutControlBeepCode { + pub custom_error_type: Option, + pub peak_map: Option, + pub peak_attr: Option, + } + #[cfg(feature = "serde")] impl ErrorOutControlBeepCode { pub(crate) fn serde_custom_error_type( &self, @@ -4330,7 +4326,7 @@ Clone)] } #[cfg(feature = "serde")] - #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + #[cfg_attr(feature = "serde", derive(Deserialize))] #[cfg_attr(feature = "serde", serde(deny_unknown_fields))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr( @@ -4341,6 +4337,15 @@ Clone)] pub raw_body: DdrPostPackageRepairBody, } #[cfg(feature = "serde")] + #[cfg_attr(feature = "serde", derive(Serialize))] + #[cfg_attr( + feature = "serde", + serde(rename = "DdrPostPackageRepairElement") + )] + pub struct CustomSerdePermissiveSerializingDdrPostPackageRepairElement { + pub raw_body: Option, + } + #[cfg(feature = "serde")] impl DdrPostPackageRepairElement { pub(crate) fn serde_raw_body( &self, diff --git a/src/serializers.rs b/src/serializers.rs index c211958..561141f 100644 --- a/src/serializers.rs +++ b/src/serializers.rs @@ -19,7 +19,7 @@ use crate::psp::*; // Note: This is written such that it will fail if the underlying struct has // fields added/removed/renamed--if those have a public setter. -macro_rules! impl_struct_serde_conversion{($StructName:ident, $SerdeStructName:ident, [$($field_name:ident),* $(,)?] +macro_rules! impl_struct_serde_conversion{($StructName:ident, $SerdeStructName:ident, $SerializingStructName:ident, [$($field_name:ident),* $(,)?] ) => ( paste::paste!{ #[cfg(feature = "serde")] @@ -37,9 +37,9 @@ macro_rules! impl_struct_serde_conversion{($StructName:ident, $SerdeStructName:i impl serde::Serialize for $StructName { fn serialize(&self, serializer: S) -> core::result::Result where S: serde::Serializer, { - $SerdeStructName { + $SerializingStructName { $( - $field_name: self.[]().map_err(|_| serde::ser::Error::custom("value unknown"))?.into(), + $field_name: self.[]().ok(), )* }.serialize(serializer) } @@ -62,6 +62,7 @@ macro_rules! impl_struct_serde_conversion{($StructName:ident, $SerdeStructName:i impl_struct_serde_conversion!( ENTRY_HEADER, SerdeENTRY_HEADER, + SerdePermissiveSerializingENTRY_HEADER, [ group_id, entry_id, @@ -80,12 +81,14 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( PriorityLevels, SerdePriorityLevels, + SerdePermissiveSerializingPriorityLevels, [hard_force, high, medium, event_logging, low, normal, _reserved_1,] ); impl_struct_serde_conversion!( Ddr4DataBusElement, SerdeDdr4DataBusElement, + SerdePermissiveSerializingDdr4DataBusElement, [ dimm_slots_per_channel, ddr_rates, @@ -105,16 +108,19 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( Ddr4DimmRanks, SerdeDdr4DimmRanks, + SerdePermissiveSerializingDdr4DimmRanks, [unpopulated, single_rank, dual_rank, quad_rank,] ); impl_struct_serde_conversion!( LrdimmDdr4DimmRanks, SerdeLrdimmDdr4DimmRanks, + SerdePermissiveSerializingLrdimmDdr4DimmRanks, [unpopulated, lr, _reserved_1,] ); impl_struct_serde_conversion!( DdrRates, SerdeDdrRates, + SerdePermissiveSerializingDdrRates, [ _reserved_1, _reserved_2, @@ -152,12 +158,14 @@ impl_struct_serde_conversion!( ); impl_struct_serde_conversion!( RdimmDdr4Voltages, - CustomSerdeRdimmDdr4Voltages, + SerdeRdimmDdr4Voltages, + SerdePermissiveSerializingRdimmDdr4Voltages, [_1_2V, _reserved_1,] ); impl_struct_serde_conversion!( RdimmDdr4CadBusElement, SerdeRdimmDdr4CadBusElement, + SerdePermissiveSerializingRdimmDdr4CadBusElement, [ dimm_slots_per_channel, ddr_rates, @@ -177,12 +185,14 @@ impl_struct_serde_conversion!( ); impl_struct_serde_conversion!( UdimmDdr4Voltages, - CustomSerdeUdimmDdr4Voltages, + SerdeUdimmDdr4Voltages, + SerdePermissiveSerializingUdimmDdr4Voltages, [_1_5V, _1_35V, _1_25V, _reserved_1,] ); impl_struct_serde_conversion!( UdimmDdr4CadBusElement, SerdeUdimmDdr4CadBusElement, + SerdePermissiveSerializingUdimmDdr4CadBusElement, [ dimm_slots_per_channel, ddr_rates, @@ -202,12 +212,14 @@ impl_struct_serde_conversion!( ); impl_struct_serde_conversion!( LrdimmDdr4Voltages, - CustomSerdeLrdimmDdr4Voltages, + SerdeLrdimmDdr4Voltages, + SerdePermissiveSerializingLrdimmDdr4Voltages, [_1_2V, _reserved_1,] ); impl_struct_serde_conversion!( LrdimmDdr4CadBusElement, SerdeLrdimmDdr4CadBusElement, + SerdePermissiveSerializingLrdimmDdr4CadBusElement, [ dimm_slots_per_channel, ddr_rates, @@ -229,6 +241,7 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( V2_HEADER, SerdeV2_HEADER, + SerdePermissiveSerializingV2_HEADER, [ signature, header_size, @@ -243,6 +256,7 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( V3_HEADER_EXT, SerdeV3_HEADER_EXT, + SerdePermissiveSerializingV3_HEADER_EXT, [ signature, _reserved_1, @@ -267,11 +281,13 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( GROUP_HEADER, SerdeGROUP_HEADER, + SerdePermissiveSerializingGROUP_HEADER, [signature, group_id, header_size, version, _reserved_, group_size,] ); impl_struct_serde_conversion!( BoardIdGettingMethodEeprom, SerdeBoardIdGettingMethodEeprom, + SerdePermissiveSerializingBoardIdGettingMethodEeprom, [ access_method, i2c_controller_index, @@ -283,6 +299,7 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( IdRevApcbMapping, SerdeIdRevApcbMapping, + SerdePermissiveSerializingIdRevApcbMapping, [ id_and_rev_and_feature_mask, id_and_feature_value, @@ -293,11 +310,13 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( SlinkRegion, SerdeSlinkRegion, + SerdePermissiveSerializingSlinkRegion, [size, alignment, socket, phys_nbio_map, interleaving, _reserved_,] ); impl_struct_serde_conversion!( AblConsoleOutControl, SerdeAblConsoleOutControl, + SerdePermissiveSerializingAblConsoleOutControl, [ enable_console_logging, enable_mem_flow_logging, @@ -316,6 +335,7 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( NaplesAblConsoleOutControl, SerdeNaplesAblConsoleOutControl, + SerdePermissiveSerializingNaplesAblConsoleOutControl, [ enable_console_logging, enable_mem_flow_logging, @@ -333,11 +353,13 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( AblBreakpointControl, SerdeAblBreakpointControl, + SerdePermissiveSerializingAblBreakpointControl, [enable_breakpoint, break_on_all_dies,] ); impl_struct_serde_conversion!( ExtVoltageControl, SerdeExtVoltageControl, + SerdePermissiveSerializingExtVoltageControl, [ enabled, _reserved_, @@ -354,6 +376,7 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( LrdimmDdr4DataBusElement, SerdeLrdimmDdr4DataBusElement, + SerdePermissiveSerializingLrdimmDdr4DataBusElement, [ dimm_slots_per_channel, ddr_rates, @@ -373,26 +396,31 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( MaxFreqElement, SerdeMaxFreqElement, + SerdePermissiveSerializingMaxFreqElement, [dimm_slots_per_channel, _reserved_, conditions, speeds,] ); impl_struct_serde_conversion!( LrMaxFreqElement, SerdeLrMaxFreqElement, + SerdePermissiveSerializingLrMaxFreqElement, [dimm_slots_per_channel, _reserved_, conditions, speeds,] ); impl_struct_serde_conversion!( Gpio, SerdeGpio, + SerdePermissiveSerializingGpio, [pin, iomux_control, bank_control,] ); impl_struct_serde_conversion!( ErrorOutControlBeepCode, CustomSerdeErrorOutControlBeepCode, + CustomSerdePermissiveSerializingErrorOutControlBeepCode, [custom_error_type, peak_map, peak_attr,] ); impl_struct_serde_conversion!( ErrorOutControl116, SerdeErrorOutControl116, + SerdePermissiveSerializingErrorOutControl116, [ enable_error_reporting, enable_error_reporting_gpio, @@ -421,6 +449,7 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( ErrorOutControl112, SerdeErrorOutControl112, + SerdePermissiveSerializingErrorOutControl112, [ enable_error_reporting, enable_error_reporting_gpio, @@ -450,46 +479,54 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( DimmsPerChannelSelector, SerdeDimmsPerChannelSelector, + SerdePermissiveSerializingDimmsPerChannelSelector, [one_dimm, two_dimms, three_dimms, four_dimms, _reserved_1,] ); impl_struct_serde_conversion!( ErrorOutControlBeepCodePeakAttr, SerdeErrorOutControlBeepCodePeakAttr, + SerdePermissiveSerializingErrorOutControlBeepCodePeakAttr, [peak_count, pulse_width, repeat_count, _reserved_1,] ); impl_struct_serde_conversion!( OdtPatPatterns, SerdeOdtPatPatterns, + SerdePermissiveSerializingOdtPatPatterns, [reading_pattern, _reserved_1, writing_pattern, _reserved_2,] ); impl_struct_serde_conversion!( LrdimmDdr4OdtPatDimmRankBitmaps, SerdeLrdimmDdr4OdtPatDimmRankBitmaps, + SerdePermissiveSerializingLrdimmDdr4OdtPatDimmRankBitmaps, [dimm0, dimm1, dimm2, _reserved_1,] ); impl_struct_serde_conversion!( Ddr4OdtPatDimmRankBitmaps, SerdeDdr4OdtPatDimmRankBitmaps, + SerdePermissiveSerializingDdr4OdtPatDimmRankBitmaps, [dimm0, dimm1, dimm2, _reserved_1,] ); impl_struct_serde_conversion!( DimmSlotsSelection, SerdeDimmSlotsSelection, + SerdePermissiveSerializingDimmSlotsSelection, [dimm_slot_0, dimm_slot_1, dimm_slot_2, dimm_slot_3, _reserved_1,] ); impl_struct_serde_conversion!( ChannelIdsSelection, SerdeChannelIdsSelection, + SerdePermissiveSerializingChannelIdsSelection, [a, b, c, d, e, f, g, h,] ); impl_struct_serde_conversion!( SocketIds, SerdeSocketIds, + SerdePermissiveSerializingSocketIds, [ socket_0, socket_1, socket_2, socket_3, socket_4, socket_5, socket_6, socket_7, @@ -499,6 +536,7 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( Ddr4OdtPatElement, SerdeDdr4OdtPatElement, + SerdePermissiveSerializingDdr4OdtPatElement, [ dimm_rank_bitmaps, cs0_odt_patterns, @@ -510,6 +548,7 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( LrdimmDdr4OdtPatElement, SerdeLrdimmDdr4OdtPatElement, + SerdePermissiveSerializingLrdimmDdr4OdtPatElement, [ dimm_rank_bitmaps, cs0_odt_patterns, @@ -521,76 +560,91 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( CkeTristateMap, SerdeCkeTristateMap, + SerdePermissiveSerializingCkeTristateMap, [type_, payload_size, sockets, channels, dimms, connections,] ); impl_struct_serde_conversion!( OdtTristateMap, SerdeOdtTristateMap, + SerdePermissiveSerializingOdtTristateMap, [type_, payload_size, sockets, channels, dimms, connections,] ); impl_struct_serde_conversion!( CsTristateMap, SerdeCsTristateMap, + SerdePermissiveSerializingCsTristateMap, [type_, payload_size, sockets, channels, dimms, connections,] ); impl_struct_serde_conversion!( MaxDimmsPerChannel, SerdeMaxDimmsPerChannel, + SerdePermissiveSerializingMaxDimmsPerChannel, [type_, payload_size, sockets, channels, dimms, value,] ); impl_struct_serde_conversion!( MemclkMap, SerdeMemclkMap, + SerdePermissiveSerializingMemclkMap, [type_, payload_size, sockets, channels, dimms, connections,] ); impl_struct_serde_conversion!( MaxChannelsPerSocket, SerdeMaxChannelsPerSocket, + SerdePermissiveSerializingMaxChannelsPerSocket, [type_, payload_size, sockets, channels, dimms, value,] ); impl_struct_serde_conversion!( MemBusSpeed, SerdeMemBusSpeed, + SerdePermissiveSerializingMemBusSpeed, [type_, payload_size, sockets, channels, dimms, timing_mode, bus_speed,] ); impl_struct_serde_conversion!( MaxCsPerChannel, SerdeMaxCsPerChannel, + SerdePermissiveSerializingMaxCsPerChannel, [type_, payload_size, sockets, channels, dimms, value,] ); impl_struct_serde_conversion!( MemTechnology, SerdeMemTechnology, + SerdePermissiveSerializingMemTechnology, [type_, payload_size, sockets, channels, dimms, technology_type,] ); impl_struct_serde_conversion!( WriteLevellingSeedDelay, SerdeWriteLevellingSeedDelay, + SerdePermissiveSerializingWriteLevellingSeedDelay, [type_, payload_size, sockets, channels, dimms, seed, ecc_seed,] ); impl_struct_serde_conversion!( RxEnSeed, SerdeRxEnSeed, + SerdePermissiveSerializingRxEnSeed, [type_, payload_size, sockets, channels, dimms, seed, ecc_seed,] ); impl_struct_serde_conversion!( LrDimmNoCs6Cs7Routing, SerdeLrDimmNoCs6Cs7Routing, + SerdePermissiveSerializingLrDimmNoCs6Cs7Routing, [type_, payload_size, sockets, channels, dimms, value,] ); impl_struct_serde_conversion!( SolderedDownSodimm, SerdeSolderedDownSodimm, + SerdePermissiveSerializingSolderedDownSodimm, [type_, payload_size, sockets, channels, dimms, value,] ); impl_struct_serde_conversion!( LvDimmForce1V5, SerdeLvDimmForce1V5, + SerdePermissiveSerializingLvDimmForce1V5, [type_, payload_size, sockets, channels, dimms, value,] ); impl_struct_serde_conversion!( MinimumRwDataEyeWidth, SerdeMinimumRwDataEyeWidth, + SerdePermissiveSerializingMinimumRwDataEyeWidth, [ type_, payload_size, @@ -604,41 +658,49 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( CpuFamilyFilter, SerdeCpuFamilyFilter, + SerdePermissiveSerializingCpuFamilyFilter, [type_, payload_size, cpu_family_revision,] ); impl_struct_serde_conversion!( SolderedDownDimmsPerChannel, SerdeSolderedDownDimmsPerChannel, + SerdePermissiveSerializingSolderedDownDimmsPerChannel, [type_, payload_size, sockets, channels, dimms, value,] ); impl_struct_serde_conversion!( MemPowerPolicy, SerdeMemPowerPolicy, + SerdePermissiveSerializingMemPowerPolicy, [type_, payload_size, sockets, channels, dimms, value,] ); impl_struct_serde_conversion!( MotherboardLayers, SerdeMotherboardLayers, + SerdePermissiveSerializingMotherboardLayers, [type_, payload_size, sockets, channels, dimms, value,] ); impl_struct_serde_conversion!( IdApcbMapping, SerdeIdApcbMapping, + SerdePermissiveSerializingIdApcbMapping, [id_and_feature_mask, id_and_feature_value, board_instance_index,] ); impl_struct_serde_conversion!( BoardIdGettingMethodCustom, SerdeBoardIdGettingMethodCustom, + SerdePermissiveSerializingBoardIdGettingMethodCustom, [access_method, feature_mask,] ); impl_struct_serde_conversion!( BoardIdGettingMethodGpio, SerdeBoardIdGettingMethodGpio, + SerdePermissiveSerializingBoardIdGettingMethodGpio, [access_method, bit_locations,] ); impl_struct_serde_conversion!( BoardIdGettingMethodSmbus, SerdeBoardIdGettingMethodSmbus, + SerdePermissiveSerializingBoardIdGettingMethodSmbus, [ access_method, i2c_controller_index, @@ -652,6 +714,7 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( FchGppClkMapSelection, SerdeFchGppClkMapSelection, + SerdePermissiveSerializingFchGppClkMapSelection, [ s0_gpp0_off, s0_gpp1_off, @@ -667,15 +730,22 @@ impl_struct_serde_conversion!( _reserved_2, ] ); -impl_struct_serde_conversion!(Terminator, SerdeTerminator, [type_,]); +impl_struct_serde_conversion!( + Terminator, + SerdeTerminator, + SerdePermissiveSerializingTerminator, + [type_,] +); impl_struct_serde_conversion!( DdrPostPackageRepairElement, CustomSerdeDdrPostPackageRepairElement, + CustomSerdePermissiveSerializingDdrPostPackageRepairElement, [raw_body,] ); impl_struct_serde_conversion!( DdrPostPackageRepairBody, SerdeDdrPostPackageRepairBody, + SerdePermissiveSerializingDdrPostPackageRepairBody, [ bank, rank_multiplier, @@ -694,6 +764,7 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( DimmInfoSmbusElement, SerdeDimmInfoSmbusElement, + SerdePermissiveSerializingDimmInfoSmbusElement, [ dimm_slot_present, socket_id, @@ -708,16 +779,19 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( ConsoleOutControl, SerdeConsoleOutControl, + SerdePermissiveSerializingConsoleOutControl, [abl_console_out_control, abl_breakpoint_control, _reserved_,] ); impl_struct_serde_conversion!( NaplesConsoleOutControl, SerdeNaplesConsoleOutControl, + SerdePermissiveSerializingNaplesConsoleOutControl, [abl_console_out_control, abl_breakpoint_control, _reserved_,] ); impl_struct_serde_conversion!( BoardInstances, SerdeBoardInstances, + SerdePermissiveSerializingBoardInstances, [ instance_0, instance_1, @@ -740,16 +814,19 @@ impl_struct_serde_conversion!( impl_struct_serde_conversion!( Parameter, SerdeParameter, + SerdePermissiveSerializingParameter, [time_point, token, value_size, value, _reserved_0,] ); impl_struct_serde_conversion!( ParameterAttributes, SerdeParameterAttributes, + SerdePermissiveSerializingParameterAttributes, [time_point, token, size_minus_one, _reserved_0,] ); impl_struct_serde_conversion!( MemPmuBistTestSelect, SerdeMemPmuBistTestSelect, + SerdePermissiveSerializingMemPmuBistTestSelect, [ algorithm_1, algorithm_2, diff --git a/src/struct_accessors.rs b/src/struct_accessors.rs index 00778f4..f05b1fc 100644 --- a/src/struct_accessors.rs +++ b/src/struct_accessors.rs @@ -319,7 +319,7 @@ macro_rules! make_accessors {( paste::paste!{ #[doc(hidden)] #[allow(non_camel_case_types)] - #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + #[cfg_attr(feature = "serde", derive(Deserialize))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] // Doing remoting automatically would make it impossible for the user to use another one. // Since the config format presumably needs to be @@ -333,6 +333,32 @@ macro_rules! make_accessors {( )* } } + + #[cfg(feature = "serde")] + paste::paste!{ + /// Use this for serialization in order to make serde skip those fields + /// where the meaning of a raw value is unknown to us. + /// + /// Caller can then override Serializer::skip_field and thus find out + /// which fields were skipped, inferring where errors were. + #[doc(hidden)] + #[allow(non_camel_case_types)] + #[cfg_attr(feature = "serde", derive(Serialize))] + #[cfg_attr(feature = "serde", serde(rename = "" $StructName))] + // Rust's serde automatically has Options transparent--but not Results. + // See also for + // limitations (that don't hit us since our zerocopy structs + // can't have Option> anyway). + pub(crate) struct [] { + $( + $(#[serde(skip_serializing_if="Option::is_none")] + pub $field_name: Option<$field_ty>,)? + $(#[serde(skip_serializing_if="Option::is_none")] + $(#[$serde_field_orig_meta])* + pub $field_name: Option<$serde_ty>,)? + )* + } + } )} pub(crate) use make_accessors; diff --git a/tests/headers.rs b/tests/headers.rs index 9dd6924..c2b5ffb 100644 --- a/tests/headers.rs +++ b/tests/headers.rs @@ -182,3 +182,42 @@ fn test_unknown_field() { } }; } + +#[cfg(feature = "serde")] +fn take_header_from_collection_mut< + 'a, + T: Sized + zerocopy::FromBytes + zerocopy::AsBytes, +>( + buf: &mut &'a mut [u8], +) -> Option<&'a mut T> { + use std::mem::take; + use zerocopy::LayoutVerified; + + let xbuf = take(&mut *buf); + match LayoutVerified::<_, T>::new_from_prefix(xbuf) { + Some((item, xbuf)) => { + *buf = xbuf; + Some(item.into_mut()) + } + None => None, + } +} + +#[cfg(feature = "serde")] +#[test] +fn test_skip_field() { + use std::mem::size_of; + + use amd_apcb::memory::AblConsoleOutControl; + // 3 is definitely not a valid value for a bool. + let mut data = [3u8; size_of::()]; + let mut buf = &mut data[..]; + let header = + take_header_from_collection_mut::(&mut buf) + .unwrap(); + let s = serde_yaml::to_string(&header).unwrap(); + assert!(s.find("enable_console_logging").is_none()); + header.set_enable_console_logging(true); + let s = serde_yaml::to_string(&header).unwrap(); + assert!(s.find("enable_console_logging").is_some()); +}