Skip to main content

dpdu_api_types/
enums.rs

1#[cfg(feature = "strum")]
2macro_rules! impl_as_str {
3    ($enum:ty) => {
4        impl $enum {
5            /// Returns string representation of enum variant.
6            pub fn as_str(&self) -> &str {
7                self.as_ref()
8            }
9        }
10    };
11}
12
13#[repr(u32)]
14#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
15#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
17/// Item type values
18pub enum PduIt {
19    /// IOCTL UNUM32
20    IoUnum32 = 0x1000,
21    /// IOCTL program voltage
22    IoProgVoltage = 0x1001,
23    /// IOCTL Byte Array
24    IoByteArray = 0x1002,
25    /// IOCTL Filter
26    IoFilter = 0x1003,
27    /// IOCTL event queue priority
28    IoEventQueueProperty = 0x1004,
29    /// Resource status
30    RscStatus = 0x1100,
31    /// Communication parameter (ComParam)
32    Param = 0x1200,
33    /// Result
34    Result = 0x1300,
35    /// Status notification
36    Status = 0x1301,
37    /// Error notification
38    Error = 0x1302,
39    /// Information notification
40    Info = 0x1303,
41    /// Resource ID
42    RscId = 0x1400,
43    /// Resource conflict
44    RscConflict = 0x1500,
45    /// Module ID
46    ModuleId = 0x1600,
47    /// Unique response ID table
48    UniqueRespIdTable = 0x1700,
49    /// DoIP Vehicle ID request
50    IoVehicleIdRequest = 0x1800,
51    /// DoIP ethernet activation
52    EthSwitchState = 0x1801,
53    /// DoIP entity addressing
54    EntityAddress = 0x1802,
55    /// DoIP entity status
56    EntityStatus = 0x1803,
57}
58
59#[cfg(feature = "strum")]
60#[cfg(feature = "strum")]
61impl_as_str!(PduIt);
62
63#[repr(u32)]
64#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
65#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
66#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
67/// Communication primitive (ComParam) type
68pub enum PduCopt {
69    /// Start communication with an ECU
70    StartComm = 0x8001,
71    /// Stop communication with an ECU
72    StopComm = 0x8002,
73    /// Updates an existing [ComParameter] on an active logical communication link
74    UpdateParam = 0x8003,
75    /// Send request or response data
76    SendRecv = 0x8004,
77    /// Wait a specified time before executing the next [ComPrimitive]
78    Delay = 0x8005,
79    /// Opposite of [PduCopt::UpdateParam], copies active com param from logical communication
80    /// link to a working buffer
81    RestoreParam = 0x8006,
82}
83
84#[cfg(feature = "strum")]
85#[cfg(feature = "strum")]
86impl_as_str!(PduCopt);
87
88#[repr(u32)]
89#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
90#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
91#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
92/// Object type
93pub enum PduObjt {
94    /// Protocol object
95    Protocol = 0x8021,
96    /// Bus type object
97    BusType = 0x8022,
98    /// IO control object
99    IoCtrl = 0x8023,
100    /// Communication Parameter object
101    ComParam = 0x8024,
102    /// Pin type object
103    PinType = 0x8025,
104    /// resource object
105    Resource = 0x8026,
106}
107
108#[cfg(feature = "strum")]
109#[cfg(feature = "strum")]
110impl_as_str!(PduObjt);
111
112#[repr(u32)]
113#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
114#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
115#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
116/// Status codes
117pub enum PduStatus {
118    /// Communication parameter has not been acted upon yet
119    CopstIdle = 0x8010,
120    /// Communication parameter is being run
121    CopstExecuting = 0x8011,
122    /// Communication parameter is finished being run
123    CopstFinished = 0x8012,
124    /// Communication parameter was cancelled
125    CopstCancelled = 0x8013,
126    /// Communication parameter is waiting to be executed again (Cyclic communication parameter)
127    CopstWaiting = 0x8014,
128    /// Communication logical link is offline
129    CllstOffline = 0x8050,
130    /// Communication logical link is online
131    CllstOnline = 0x8051,
132    /// Communication logical link is online and has been started (In a Tx/Rx state)
133    CllstCommStarted = 0x8052,
134    /// Vehicle communication interface is ready for communication
135    ModstReady = 0x8060,
136    /// Vehicle communication interface is not ready for communication
137    ModstNotReady = 0x8061,
138    /// Vehicle communication interface is unavailable for connection
139    ModstNotAvail = 0x8062,
140    /// Vehicle communication interface is available for connection
141    ModstAvail = 0x8063,
142}
143
144#[cfg(feature = "strum")]
145#[cfg(feature = "strum")]
146impl_as_str!(PduStatus);
147
148#[repr(u32)]
149#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
150#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
151#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
152/// Information events
153pub enum PduInfo {
154    /// New vehicle communication list is available
155    ModuleListChange = 0x8070,
156    /// A change has occurred with the lock status on a shared resource
157    ResourceLockChange = 0x8071,
158    /// A communication parameter on a logical link has been changed
159    ComParamChange = 0x8072,
160}
161
162#[cfg(feature = "strum")]
163#[cfg(feature = "strum")]
164impl_as_str!(PduInfo);
165
166#[repr(u32)]
167#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
168#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
169#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
170/// Event callback
171pub enum PduEvtData {
172    /// There is event data available to read by the application
173    Available = 0x801,
174    /// The ComLogicalLink has lost event data due to a buffer overrun
175    Lost = 0x0802,
176}
177
178#[cfg(feature = "strum")]
179#[cfg(feature = "strum")]
180impl_as_str!(PduEvtData);
181
182#[repr(u32)]
183#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
184#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
185#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
186/// Filter type
187pub enum PduFilter {
188    /// Matched messages go into the receive queue
189    Pass = 0x00000001,
190    /// Matched messages stay out of the receive queue
191    Block = 0x00000002,
192    /// Matches messages go into the receive queue that are UUDT only (For ISO1765)
193    PassUudt = 0x00000011,
194    /// Matches messages stay out of the receive queue that are UUDT only (For ISO1765)
195    BlockUudt = 0x00000012,
196}
197
198#[cfg(feature = "strum")]
199#[cfg(feature = "strum")]
200impl_as_str!(PduFilter);
201
202#[repr(u32)]
203#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
204#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
205#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
206/// IOCTL queue mode
207pub enum PduQueueMode {
208    /// Attempt to allocate memory for every event coming in to the receive queue. This queue size can keep
209    /// growing until the API runs out of allocation memory
210    Unlimited = 0x00000000,
211    /// Attempt to allocate a fixed buffer size for events coming into the receive queue. Events are discarded
212    /// from the receive queue if the buffer is full
213    Limited = 0x00000001,
214    /// Attempt to allocate a fixed buffer size for events coming into the receive queue. Events overwrite
215    /// stored events if the buffer is full (Like a circular buffer)
216    Circular = 0x00000002,
217}
218
219#[cfg(feature = "strum")]
220impl_as_str!(PduQueueMode);
221
222#[repr(u32)]
223#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
224#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
225#[cfg_attr(feature = "thiserror", derive(thiserror::Error))]
226#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
227/// Function return values
228pub enum PduError {
229    /// No Error (Function call OK)
230    #[cfg_attr(feature = "thiserror", error("No error (function call OK)"))]
231    StatusNoError = 0x00000000,
232
233    /// Function call failed (Generic failure)
234    #[cfg_attr(feature = "thiserror", error("Function call failed (Generic failure)"))]
235    FctFailed = 0x00000001,
236
237    /// Reserved for ISO 22900-2
238    #[cfg_attr(feature = "thiserror", error("Reserved for ISO 22900-2"))]
239    Reserved1 = 0x00000010,
240
241    /// Communication failed between host and MVCI
242    #[cfg_attr(
243        feature = "thiserror",
244        error("Communication failed between host and MVCI")
245    )]
246    CommPcToVciFailed = 0x00000011,
247
248    /// PDU API has not yet been constructed
249    #[cfg_attr(feature = "thiserror", error("PDU API has not yet been constructed"))]
250    PduApiNotConstructed = 0x00000020,
251
252    /// PDU Destruct was not called before another PDU Construct
253    #[cfg_attr(
254        feature = "thiserror",
255        error("PDU Destruct was not called before another PDU Construct")
256    )]
257    SharingViolation = 0x00000021,
258
259    /// Resource is already in use
260    #[cfg_attr(feature = "thiserror", error("Resource is already in use"))]
261    ResourceBusy = 0x00000030,
262
263    /// Resource table changed
264    #[cfg_attr(feature = "thiserror", error("Resource table changed"))]
265    ResourceTableChanged = 0x00000031,
266
267    /// Generic resource error
268    #[cfg_attr(feature = "thiserror", error("Generic resource error"))]
269    ResourceError = 0x00000032,
270
271    /// ComLogicalLink cannot be offline and perform the requested action
272    #[cfg_attr(
273        feature = "thiserror",
274        error("ComLogicalLink cannot be offline and perform the requested action")
275    )]
276    CllNotConnected = 0x00000040,
277
278    /// ComLogicalLink must be started to perform the requested action
279    #[cfg_attr(
280        feature = "thiserror",
281        error("ComLogicalLink must be started to perform the requested action")
282    )]
283    CllNotStarted = 0x00000041,
284
285    /// A parameter parsed into the function was invalid
286    #[cfg_attr(
287        feature = "thiserror",
288        error("A parameter parsed into the function was invalid")
289    )]
290    InvalidParameters = 0x00000050,
291
292    /// A handle provided was invalid
293    #[cfg_attr(feature = "thiserror", error("A handle provided was invalid"))]
294    InvalidHandle = 0x00000060,
295
296    /// Option value was unsupported
297    #[cfg_attr(feature = "thiserror", error("Option value was unsupported"))]
298    ValueNotSupported = 0x00000061,
299
300    /// IOCTL Command ID was unsupported
301    #[cfg_attr(feature = "thiserror", error("IOCTL Command ID was unsupported"))]
302    IdNotSupported = 0x00000062,
303
304    /// Communication parameter was unsupported
305    #[cfg_attr(
306        feature = "thiserror",
307        error("Communication parameter was unsupported")
308    )]
309    ComParamNotSupported = 0x00000063,
310
311    /// Physical communication parameter cannot be changed as it is locked by another LogicalLink
312    #[cfg_attr(
313        feature = "thiserror",
314        error(
315            "Physical communication parameter cannot be changed as it is locked by another LogicalLink"
316        )
317    )]
318    ComParamLocked = 0x00000064,
319
320    /// Transmit queue is full
321    #[cfg_attr(feature = "thiserror", error("Transmit queue is full"))]
322    TxQueueFull = 0x00000070,
323
324    /// No more events are available to read
325    #[cfg_attr(feature = "thiserror", error("No more events are available to read"))]
326    EventQueueEmpty = 0x00000071,
327
328    /// IOCTL - Voltage value supplied is unsupported by the MVCI module
329    #[cfg_attr(
330        feature = "thiserror",
331        error("IOCTL - Voltage value supplied is unsupported by the MVCI module")
332    )]
333    VoltageNotSupported = 0x00000080,
334
335    /// IOCTL - Pin or resource is not supported by the MVCI module
336    #[cfg_attr(
337        feature = "thiserror",
338        error("IOCTL - Pin or resource is not supported by the MVCI module")
339    )]
340    MuxRscNotSupported = 0x00000081,
341
342    /// Cable attached to MVCI module is unknown
343    #[cfg_attr(
344        feature = "thiserror",
345        error("Cable attached to MVCI module is unknown")
346    )]
347    CableUnknown = 0x00000082,
348
349    /// No cable attached to the MVCI module
350    #[cfg_attr(feature = "thiserror", error("No cable attached to the MVCI module"))]
351    NoCableDetected = 0x00000083,
352
353    /// ComLogicalLink is already connected
354    #[cfg_attr(feature = "thiserror", error("ComLogicalLink is already connected"))]
355    CllConnected = 0x00000084,
356
357    /// Physical Com parameters cannot be changes as a temporary one
358    #[cfg_attr(
359        feature = "thiserror",
360        error("Physical Com parameters cannot be changes as a temporary one")
361    )]
362    TempParamNotAllowed = 0x00000090,
363
364    /// Resource is already locked
365    #[cfg_attr(feature = "thiserror", error("Resource is already locked"))]
366    RscLocked = 0x000000A0,
367
368    /// Resource is already locked by another ComLogicalLink
369    #[cfg_attr(
370        feature = "thiserror",
371        error("Resource is already locked by another ComLogicalLink")
372    )]
373    RscLockedByAnotherCll = 0x000000A1,
374
375    /// Resource is already unlocked
376    #[cfg_attr(feature = "thiserror", error("Resource is already unlocked"))]
377    RscNotLocked = 0x000000A2,
378
379    /// Module is not connected or ready
380    #[cfg_attr(feature = "thiserror", error("Module is not connected or ready"))]
381    ModuleNotConnected = 0x000000A3,
382
383    /// API software is out of date
384    #[cfg_attr(feature = "thiserror", error("API software is out of date"))]
385    ApiSwOutOfDate = 0x000000A4,
386
387    /// VCI firmware is out of date
388    #[cfg_attr(feature = "thiserror", error("VCI firmware is out of date"))]
389    ModuleFwOutOfDate = 0x000000A5,
390
391    /// Requested pin is not routed by the MVCI's cable
392    #[cfg_attr(
393        feature = "thiserror",
394        error("Requested pin is not routed by the MVCI's cable")
395    )]
396    PinNotConnected = 0x000000A6,
397
398    /// IP protocol not supported
399    #[cfg_attr(feature = "thiserror", error("IP protocol not supported"))]
400    IpProtocolNotSupported = 0x000000B0,
401
402    /// DoIP Routing activation failed (Generic failure)
403    #[cfg_attr(
404        feature = "thiserror",
405        error("DoIP Routing activation failed (Generic failure)")
406    )]
407    DoIpRoutingActivationFailed = 0x000000B1,
408
409    /// DoIP Routing activation failed - missing / wrong authentication
410    #[cfg_attr(
411        feature = "thiserror",
412        error("DoIP Routing activation failed - missing / wrong authentication")
413    )]
414    DoIpRoutingActivationAuthFailed = 0x000000B2,
415
416    /// DoIP Logical address is defined multiple times so it is ambiguous
417    #[cfg_attr(
418        feature = "thiserror",
419        error("DoIP Logical address is defined multiple times so it is ambiguous")
420    )]
421    DoIpAmbiguousLogicalAddress = 0x000000B3,
422
423    /// DoIP Routing activation failed - Unknown or invalid source address
424    #[cfg_attr(
425        feature = "thiserror",
426        error("DoIP Routing activation failed - Unknown or invalid source address")
427    )]
428    DoIpRoutineActivationInvalidSrcAddress = 0x000000B4,
429
430    /// DoIP Routing activation failed - No more free sockets available
431    #[cfg_attr(
432        feature = "thiserror",
433        error("DoIP Routing activation failed - No more free sockets available")
434    )]
435    DoIpRoutingActivationNoDataSocketAvailable = 0x000000B5,
436
437    /// DoIP Routing activation failed - The source address changed
438    #[cfg_attr(
439        feature = "thiserror",
440        error("DoIP Routing activation failed - The source address changed")
441    )]
442    DoIpRoutineActivationSourceAddressChanged = 0x000000B6,
443
444    /// DoIP Routing activation failed - Source address already in use
445    #[cfg_attr(
446        feature = "thiserror",
447        error("DoIP Routing activation failed - Source address already in use")
448    )]
449    DoIpRoutingActivationSourceAddressInUse = 0x000000B7,
450
451    /// DoIP Routing activation failed - Rejected confirmation
452    #[cfg_attr(
453        feature = "thiserror",
454        error("DoIP Routing activation failed - Rejected confirmation")
455    )]
456    DoIpRoutineActivationConfirmationRejected = 0x000000B8,
457
458    /// DoIP Routing activation failed - Requested activation type was unsupported
459    #[cfg_attr(
460        feature = "thiserror",
461        error("DoIP Routing activation failed - Requested activation type was unsupported")
462    )]
463    DoIpRoutineActivationTypeUnsupported = 0x000000B9,
464
465    /// DoIP Routing activation failed - Response code was unknown
466    #[cfg_attr(
467        feature = "thiserror",
468        error("DoIP Routing activation failed - Response code was unknown")
469    )]
470    DoIpRoutineActivationResponseCodeUnknown = 0x000000BA,
471
472    /// DoIP Routing activation failed - Timeout waiting for activation response
473    #[cfg_attr(
474        feature = "thiserror",
475        error("DoIP Routing activation failed - Timeout waiting for activation response")
476    )]
477    DoIpRoutingActivationResponseTimeout = 0x000000BB,
478
479    /// DoIP general timeout
480    #[cfg_attr(feature = "thiserror", error("DoIP general timeout"))]
481    DoIpResponseTimeout = 0x000000BC,
482}
483
484#[cfg(feature = "strum")]
485impl_as_str!(PduError);
486
487impl PduError {
488    /// Returns `true` if the result indicates success according to the API.
489    pub fn is_success(&self) -> bool {
490        matches!(self, PduError::StatusNoError)
491    }
492}
493
494#[repr(u32)]
495#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
496#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
497#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
498/// Function error events (Used in asynchronous situations)
499pub enum PduErrorEvt {
500    /// No error
501    NoError = 0x00000000,
502    /// Structure of the received data frame was incorrect
503    FrameStruct = 0x00000100,
504    /// Transmit error
505    TxError = 0x00000101,
506    /// Tester present transmit error or ECU responded negatively to the request
507    TesterPresentError = 0x00000102,
508    /// ComParam could not be set as resource was locked
509    RscLocked = 0x00000109,
510    /// Receive message timeout
511    RxTimeout = 0x00000103,
512    /// Receive message error at a protocol level
513    RxError = 0x00000104,
514    /// ComPrimitive error by protocol
515    ProtErr = 0x00000105,
516    /// Communication to MVCI module was lost
517    LostCommToVci = 0x00000106,
518    /// MVCI hardware fault
519    VciHardwareFault = 0x00000107,
520    /// Protocol initialization error
521    InitError = 0x00000108,
522}
523
524#[cfg(feature = "strum")]
525impl_as_str!(PduErrorEvt);
526
527#[repr(u32)]
528#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
529#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
530#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
531/// ComParam data type
532pub enum PduPt {
533    /// Unsigned 8 bit
534    Unum8 = 0x000000101,
535    /// Signed 8 bit
536    Snum8 = 0x000000102,
537    /// Unsigned 16 bit
538    Unum16 = 0x000000103,
539    /// Signed 16 bit
540    Snum16 = 0x000000104,
541    /// Unsigned 32 bit
542    Unum32 = 0x000000105,
543    /// Signed 32 bit
544    Snum32 = 0x000000106,
545    /// Byte array
546    ByteField = 0x000000107,
547    /// Structure
548    StructField = 0x000000108,
549    /// Array of 32bit values
550    LongField = 0x00000109,
551}
552
553#[cfg(feature = "strum")]
554impl_as_str!(PduPt);
555
556#[repr(u32)]
557#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
558#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
559#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
560/// ComParam data class
561pub enum PduPc {
562    /// Message timing
563    Timing = 1,
564    /// Initialization of communication
565    Init = 2,
566    /// General com param
567    Com = 3,
568    /// Error handling ComParam
569    ErrHdl = 4,
570    /// BusType specific ComParam
571    BusType = 5,
572    ///
573    UniqueId = 6,
574    /// Tester present ComParam
575    TesterPresent = 7,
576}
577
578#[cfg(feature = "strum")]
579impl_as_str!(PduPc);
580
581#[repr(u32)]
582#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
583#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
584#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
585/// ComParam struct type
586pub enum PduCpst {
587    /// Session timing
588    SessionTiming = 0x00000001,
589    /// Access timing
590    AccessTiming = 0x00000002,
591}
592
593#[cfg(feature = "strum")]
594impl_as_str!(PduCpst);
595
596#[repr(u8)]
597#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
598#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
599#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
600/// Vehicle preselection mode
601pub enum VidPreselectMode {
602    /// No preselection
603    None = 0,
604    /// DoIP with given VIN
605    Vin = 1,
606    /// DoIP with given EID
607    Eid = 2,
608}
609
610#[cfg(feature = "strum")]
611impl_as_str!(VidPreselectMode);
612
613#[repr(u8)]
614#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
615#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
616#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
617/// DoIP Combination mode
618pub enum CombinationMode {
619    /// No combination
620    None = 0,
621    /// Combine common VIN
622    VIN = 1,
623    /// Combine common GroupID
624    Group = 2,
625    /// Combine all
626    All = 3,
627}
628
629#[cfg(feature = "strum")]
630impl_as_str!(CombinationMode);
631
632#[repr(u8)]
633#[cfg_attr(feature = "num_enum", derive(num_enum::TryFromPrimitive))]
634#[cfg_attr(feature = "num_enum", derive(strum::AsRefStr))]
635#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
636/// Timing set types used by [ParamStructAccessTiming]
637pub enum TimingSet {
638    /// Default timing set
639    Default = 1,
640    /// Override received timing from ECU
641    OverrideReceived = 2,
642    /// Override received timing from tester
643    OverrideTester = 3,
644    /// Normal timing set
645    Normal = 4,
646    /// Extended timing set
647    Extended = 0xFF,
648}
649
650#[cfg(feature = "strum")]
651impl_as_str!(TimingSet);
652
653#[cfg(feature = "serde")]
654impl serde::Serialize for TimingSet {
655    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
656    where
657        S: serde::Serializer,
658    {
659        let value = match self {
660            TimingSet::Default => 1,
661            TimingSet::OverrideReceived => 2,
662            TimingSet::OverrideTester => 3,
663            TimingSet::Normal => 4,
664            TimingSet::Extended => 0xFF,
665        };
666
667        serializer.serialize_u8(value)
668    }
669}
670
671#[cfg(feature = "serde")]
672impl<'de> serde::Deserialize<'de> for TimingSet {
673    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
674    where
675        D: serde::Deserializer<'de>,
676    {
677        struct TimingSetVisitor;
678
679        impl<'de> serde::de::Visitor<'de> for TimingSetVisitor {
680            type Value = TimingSet;
681
682            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
683                formatter.write_str("TimingSet as u8 or string")
684            }
685
686            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
687            where
688                E: serde::de::Error,
689            {
690                match value {
691                    1 => Ok(TimingSet::Default),
692                    2 => Ok(TimingSet::OverrideReceived),
693                    3 => Ok(TimingSet::OverrideTester),
694                    4 => Ok(TimingSet::Normal),
695                    0xFF => Ok(TimingSet::Extended),
696                    v => Err(E::custom(format!("unknown value {:#04X}", v))),
697                }
698            }
699
700            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
701            where
702                E: serde::de::Error,
703            {
704                match value {
705                    "Default" | "default" => Ok(TimingSet::Default),
706                    "OverrideReceived" | "override_received" => Ok(TimingSet::OverrideReceived),
707                    "OverrideTester" | "override_tester" => Ok(TimingSet::OverrideTester),
708                    "Normal" | "normal" => Ok(TimingSet::Normal),
709                    "Extended" | "extended" => Ok(TimingSet::Extended),
710                    v => Err(E::custom(format!("unknown TimingSet {}", v))),
711                }
712            }
713        }
714
715        deserializer.deserialize_any(TimingSetVisitor)
716    }
717}