Skip to main content

rsomeip_proto/
primitives.rs

1//! SOME/IP primitive types.
2//!
3//! This module provides strongly-typed definitions for the primitives used by the SOME/IP protocol.
4
5use rsomeip_bytes::{Buf, BufMut, Deserialize, DeserializeError, Serialize, SerializeError};
6
7/// Implements basic functionality for new-types that wrap a single primitive.
8///
9/// Includes const (`new` and `as_`) and non-const (`from` and `into`) methods for converting between
10/// the new-type and its internal representation, and implements [`Serialize`], [`Deserialize`] and
11/// [`std::fmt::Display`] for the type.
12macro_rules! impl_basic_type {
13    ($name:ident, $repr:ty, $getter:ident, $fmt:literal) => {
14        impl $name {
15            #[doc=concat!("Creates a new [`", stringify!($name), "`] with the given `value`.")]
16            ///
17            /// # Examples
18            ///
19            /// ```rust
20            #[doc=concat!("use rsomeip_proto::", stringify!($name), ";")]
21            ///
22            #[doc=concat!("let value = ", stringify!($name), "::new(1 as ", stringify!($repr), ");")]
23            #[doc=concat!("assert_eq!(value.", stringify!($getter), "(), 1 as ", stringify!($repr), ");")]
24            /// ```
25            #[inline]
26            #[must_use]
27            pub const fn new(value: $repr) -> Self {
28                Self(value)
29            }
30
31            #[doc=concat!("Returns the [`", stringify!($repr), "`] representation of this [`", stringify!($name), "`].")]
32            ///
33            /// # Examples
34            ///
35            /// ```rust
36            #[doc=concat!("use rsomeip_proto::", stringify!($name), ";")]
37            ///
38            #[doc=concat!("let value = ", stringify!($name), "::new(1 as ", stringify!($repr), ");")]
39            #[doc=concat!("assert_eq!(value.", stringify!($getter), "(), 1 as ", stringify!($repr), ");")]
40            /// ```
41            #[inline]
42            #[must_use]
43            pub const fn $getter(self) -> $repr {
44                self.0
45            }
46        }
47
48        impl From<$repr> for $name {
49            fn from(value: $repr) -> Self {
50                Self::new(value)
51            }
52        }
53
54        impl From<$name> for $repr {
55            fn from(value: $name) -> Self {
56                value.0
57            }
58        }
59
60        impl rsomeip_bytes::Serialize for $name {
61            fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, rsomeip_bytes::SerializeError> {
62                self.0.serialize(buffer)
63            }
64
65            fn size_hint(&self) -> usize {
66                self.0.size_hint()
67            }
68        }
69
70        impl rsomeip_bytes::Deserialize for $name {
71            type Output = Self;
72
73            fn deserialize(buffer: &mut impl Buf) -> Result<Self::Output, rsomeip_bytes::DeserializeError> {
74                <$repr>::deserialize(buffer).map(Self::new)
75            }
76        }
77
78        impl ::std::fmt::Display for $name {
79            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
80                write!(f, $fmt, self.0)
81            }
82        }
83    };
84}
85
86macro_rules! impl_basic_type_u16 {
87    ($name:ident) => {
88        impl_basic_type!($name, u16, as_u16, "{:04x?}");
89    };
90}
91
92macro_rules! impl_basic_type_u8 {
93    ($name:ident) => {
94        impl_basic_type!($name, u8, as_u8, "{:02x?}");
95    };
96}
97
98/// Unique identifier of a service interface.
99///
100/// A service is a logical combination of zero or more [methods], zero or more events, and zero or
101/// more fields.
102///
103/// [methods]: MethodId
104#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
105pub struct ServiceId(u16);
106
107impl_basic_type_u16!(ServiceId);
108
109/// Unique identifier of a method, field or event on a service interface.
110///
111/// A method is a callable function, procedure or subroutine which can be invoked by consumers of a
112/// service.
113///
114/// A field represents a status or valid value on which getters, setters and notifiers act upon.
115///
116/// An event is a uni-directional data transmission that is invoked on changes or cyclically and
117/// is sent to consumers of a service.
118///
119/// # Practices
120///
121/// It's common practice to split the ID space of [`MethodId`] between methods and
122/// events/notifications.
123///
124/// Methods would use the range `0x0000-0x7fff` and events/notifications would use the range
125/// `0x8fff-0xffff`.
126#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
127pub struct MethodId(u16);
128
129impl_basic_type_u16!(MethodId);
130
131/// Unique identifier of a method or event on a service interface.
132///
133/// Consists of [`ServiceId`] followed by a [`MethodId`].
134#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
135pub struct MessageId {
136    /// Service portion of the id.
137    pub service: ServiceId,
138    /// Method portion of the id.
139    pub method: MethodId,
140}
141
142impl MessageId {
143    /// Creates a new [`MessageId`] with the given `service` and `method` ids.
144    ///
145    /// # Examples
146    ///
147    /// ```rust
148    /// use rsomeip_proto::{MethodId, MessageId, ServiceId};
149    ///
150    /// let id = MessageId::new(ServiceId::new(0x1234), MethodId::new(0x5678));
151    /// assert_eq!(id.service.as_u16(), 0x1234);
152    /// assert_eq!(id.method.as_u16(), 0x5678);
153    /// ```
154    #[inline]
155    #[must_use]
156    pub const fn new(service: ServiceId, method: MethodId) -> Self {
157        Self { service, method }
158    }
159
160    /// Returns `self` with its [`ServiceId`] set to `value`.
161    ///
162    /// # Examples
163    ///
164    /// ```rust
165    /// use rsomeip_proto::{MessageId, ServiceId};
166    ///
167    /// let id = MessageId::default().with_service(ServiceId::new(0x1234));
168    /// assert_eq!(id.service.as_u16(), 0x1234);
169    /// ```
170    #[inline]
171    #[must_use]
172    pub const fn with_service(mut self, value: ServiceId) -> Self {
173        self.service = value;
174        self
175    }
176
177    /// Returns `self` with its [`MethodId`] set to `value`.
178    ///
179    /// # Examples
180    ///
181    /// ```rust
182    /// use rsomeip_proto::{MethodId, MessageId};
183    ///
184    /// let id = MessageId::default().with_method(MethodId::new(0x1234));
185    /// assert_eq!(id.method.as_u16(), 0x1234);
186    /// ```
187    #[inline]
188    #[must_use]
189    pub const fn with_method(mut self, value: MethodId) -> Self {
190        self.method = value;
191        self
192    }
193
194    /// Creates a new [`MessageId`] from the given [`u32`].
195    ///
196    /// # Examples
197    ///
198    /// ```rust
199    /// use rsomeip_proto::MessageId;
200    ///
201    /// let id = MessageId::from_u32(0x1234_5678);
202    /// assert_eq!(id.service.as_u16(), 0x1234);
203    /// assert_eq!(id.method.as_u16(), 0x5678);
204    /// ```
205    #[inline]
206    #[must_use]
207    pub const fn from_u32(value: u32) -> Self {
208        let service = ServiceId::new((value >> 16) as u16);
209        let method = MethodId::new((value & 0xffff) as u16);
210        Self::new(service, method)
211    }
212
213    /// Returns the [`u32`] representation of `self`.
214    ///
215    /// # Examples
216    ///
217    /// ```rust
218    /// use rsomeip_proto::{MethodId, MessageId, ServiceId};
219    ///
220    /// let id = MessageId::new(ServiceId::new(0x1234), MethodId::new(0x5678));
221    /// assert_eq!(id.as_u32(), 0x1234_5678);
222    /// ```
223    #[inline]
224    #[must_use]
225    pub const fn as_u32(self) -> u32 {
226        let service = (self.service.as_u16() as u32) << 16;
227        service | (self.method.as_u16() as u32)
228    }
229}
230
231impl From<u32> for MessageId {
232    fn from(value: u32) -> Self {
233        Self::from_u32(value)
234    }
235}
236
237impl From<MessageId> for u32 {
238    fn from(value: MessageId) -> Self {
239        value.as_u32()
240    }
241}
242
243impl Serialize for MessageId {
244    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
245        self.as_u32().serialize(buffer)
246    }
247
248    fn size_hint(&self) -> usize {
249        size_of::<u32>()
250    }
251}
252
253impl Deserialize for MessageId {
254    type Output = Self;
255
256    fn deserialize(buffer: &mut impl Buf) -> Result<Self::Output, DeserializeError> {
257        u32::deserialize(buffer).map(Self::from_u32)
258    }
259}
260
261impl std::fmt::Display for MessageId {
262    /// Formats `self` using the given formatter.
263    ///
264    /// # Examples
265    ///
266    /// ```rust
267    /// use rsomeip_proto::{ServiceId, MethodId, MessageId};
268    ///
269    /// let service = ServiceId::new(0x1234);
270    /// let method = MethodId::new(0x5678);
271    /// let message = MessageId::new(service, method);
272    /// assert_eq!(format!("{message}"), "1234.5678");
273    /// ```
274    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
275        write!(f, "{}.{}", self.service, self.method)
276    }
277}
278
279/// Unique identifier of the client of a service interface.
280///
281/// This is used to differentiate calls from multiple clients to the same method.
282///
283/// Should be unique in the network.
284#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
285pub struct ClientId(u16);
286
287impl_basic_type_u16!(ClientId);
288
289impl ClientId {
290    /// Returns the prefix of this id.
291    ///
292    /// # Examples
293    ///
294    /// ```rust
295    /// use rsomeip_proto::ClientId;
296    ///
297    /// let id = ClientId::new(0x0034).with_prefix(0x12);
298    /// assert_eq!(id.as_u16(), 0x1234);
299    /// assert_eq!(id.prefix(), 0x12);
300    /// ```
301    #[inline]
302    #[must_use]
303    pub const fn prefix(&self) -> u8 {
304        self.0.to_be_bytes()[0]
305    }
306
307    /// Returns `self` with the given `prefix`.
308    ///
309    /// # Examples
310    ///
311    /// ```rust
312    /// use rsomeip_proto::ClientId;
313    ///
314    /// let id = ClientId::new(0x0034).with_prefix(0x12);
315    /// assert_eq!(id.as_u16(), 0x1234);
316    /// assert_eq!(id.prefix(), 0x12);
317    /// ```
318    #[inline]
319    #[must_use]
320    pub const fn with_prefix(mut self, prefix: u8) -> Self {
321        self.0 |= (prefix as u16) << 8;
322        self
323    }
324}
325
326/// Unique identifier of a sequential message or request.
327///
328/// Used to differentiate messages to the same method or event.
329///
330/// # Session Handling
331///
332/// When session handling is active (`0x0001-0xffff`), the session ID should be
333/// incremented according to the respective use case.
334///
335/// After reaching `0xffff`, the session ID should wrap back around to `1`.
336///
337/// ## Request/Response
338///
339/// Each new request should increment the ID by `1` and each response should copy over
340/// the same ID from the request.
341///
342/// ## SOME/IP-TP
343///
344/// Each SOME/IP-TP segment should carry over the ID of the original message.
345#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
346pub struct SessionId(u16);
347
348impl_basic_type_u16!(SessionId);
349
350impl SessionId {
351    /// Default value when session handling is disabled.
352    pub const DISABLED: Self = Self::new(0);
353
354    /// Default value when session handling is enabled.
355    pub const ENABLED: Self = Self::new(1);
356
357    /// Whether session handling is enabled.
358    ///
359    /// Session handling is considered enabled if the [`SessionId`] is greater than `0`.
360    ///
361    /// # Examples
362    ///
363    /// ```rust
364    /// use rsomeip_proto::SessionId;
365    ///
366    /// assert!(SessionId::ENABLED.is_enabled());
367    /// assert!(!SessionId::DISABLED.is_enabled());
368    /// ```
369    #[inline]
370    #[must_use]
371    pub const fn is_enabled(self) -> bool {
372        self.0 > 0
373    }
374
375    /// Increments this [`SessionId`] by one and returns the old value.
376    ///
377    /// After `0xffff`, incrementing the ID wraps it back to `1`.
378    ///
379    /// # Examples
380    ///
381    /// ```rust
382    /// use rsomeip_proto::SessionId;
383    ///
384    /// let mut session = SessionId::new(0x0001);
385    /// assert_eq!(session.increment().as_u16(), 0x0001);
386    /// assert_eq!(session.as_u16(), 0x0002);
387    /// ```
388    #[expect(clippy::return_self_not_must_use)]
389    pub const fn increment(&mut self) -> Self {
390        let old = self.0;
391        self.0 = match old.wrapping_add(1) {
392            0 => 1,
393            x => x,
394        };
395        Self::new(old)
396    }
397}
398
399/// Unique identifier of message to a service interface.
400///
401/// Consists of a [`ClientId`] followed by a [`SessionId`].
402#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
403pub struct RequestId {
404    /// Client portion of the id.
405    pub client: ClientId,
406    /// Session portion of the id.
407    pub session: SessionId,
408}
409
410impl RequestId {
411    /// Creates a new [`RequestId`] with the given `client` and `session` ids.
412    ///
413    /// # Examples
414    ///
415    /// ```rust
416    /// use rsomeip_proto::{ClientId, RequestId, SessionId};
417    ///
418    /// let id = RequestId::new(ClientId::new(0x1234), SessionId::new(0x5678));
419    /// assert_eq!(id.client.as_u16(), 0x1234);
420    /// assert_eq!(id.session.as_u16(), 0x5678);
421    /// ```
422    #[inline]
423    #[must_use]
424    pub const fn new(client: ClientId, session: SessionId) -> Self {
425        Self { client, session }
426    }
427
428    /// Returns `self` with its [`ClientId`] set to `value`.
429    ///
430    /// # Examples
431    ///
432    /// ```rust
433    /// use rsomeip_proto::{ClientId, RequestId};
434    ///
435    /// let id = RequestId::default().with_client(ClientId::new(0x1234));
436    /// assert_eq!(id.client.as_u16(), 0x1234);
437    /// ```
438    #[inline]
439    #[must_use]
440    pub const fn with_client(mut self, value: ClientId) -> Self {
441        self.client = value;
442        self
443    }
444
445    /// Returns `self` with its [`SessionId`] set to `value`.
446    ///
447    /// # Examples
448    ///
449    /// ```rust
450    /// use rsomeip_proto::{RequestId, SessionId};
451    ///
452    /// let id = RequestId::default().with_session(SessionId::new(0x1234));
453    /// assert_eq!(id.session.as_u16(), 0x1234);
454    /// ```
455    #[inline]
456    #[must_use]
457    pub const fn with_session(mut self, value: SessionId) -> Self {
458        self.session = value;
459        self
460    }
461
462    /// Creates a new [`RequestId`] from the given [`u32`].
463    ///
464    /// # Examples
465    ///
466    /// ```rust
467    /// use rsomeip_proto::RequestId;
468    ///
469    /// let id = RequestId::from_u32(0x1234_5678);
470    /// assert_eq!(id.client.as_u16(), 0x1234);
471    /// assert_eq!(id.session.as_u16(), 0x5678);
472    /// ```
473    #[must_use]
474    pub const fn from_u32(value: u32) -> Self {
475        let client = ClientId::new((value >> 16) as u16);
476        let session = SessionId::new((value & 0xffff) as u16);
477        Self::new(client, session)
478    }
479
480    /// Returns the [`u32`] representation of `self`.
481    ///
482    /// # Examples
483    ///
484    /// ```rust
485    /// use rsomeip_proto::{ClientId, RequestId, SessionId};
486    ///
487    /// let id = RequestId::new(ClientId::new(0x1234), SessionId::new(0x5678));
488    /// assert_eq!(id.as_u32(), 0x1234_5678);
489    /// ```
490    #[must_use]
491    pub const fn as_u32(self) -> u32 {
492        let client = (self.client.as_u16() as u32) << 16;
493        client | (self.session.as_u16() as u32)
494    }
495}
496
497impl From<u32> for RequestId {
498    fn from(value: u32) -> Self {
499        Self::from_u32(value)
500    }
501}
502
503impl From<RequestId> for u32 {
504    fn from(value: RequestId) -> Self {
505        value.as_u32()
506    }
507}
508
509impl Serialize for RequestId {
510    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
511        self.as_u32().serialize(buffer)
512    }
513
514    fn size_hint(&self) -> usize {
515        size_of::<u32>()
516    }
517}
518
519impl Deserialize for RequestId {
520    type Output = Self;
521
522    fn deserialize(buffer: &mut impl Buf) -> Result<Self::Output, DeserializeError> {
523        u32::deserialize(buffer).map(Self::from_u32)
524    }
525}
526
527impl std::fmt::Display for RequestId {
528    /// Formats `self` using the given formatter.
529    ///
530    /// # Examples
531    ///
532    /// ```rust
533    /// use rsomeip_proto::{ClientId, RequestId, SessionId};
534    ///
535    /// let client = ClientId::new(0x1234);
536    /// let session = SessionId::new(0x5678);
537    /// let request = RequestId::new(client, session);
538    /// assert_eq!(format!("{request}"), "1234.5678");
539    /// ```
540    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
541        write!(f, "{}.{}", self.client, self.session)
542    }
543}
544
545/// Major version of the SOME/IP protocol.
546#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
547pub struct ProtocolVersion(u8);
548
549impl_basic_type_u8!(ProtocolVersion);
550
551/// Major version of a service interface.
552///
553/// # Compatibility
554///
555/// The [`InterfaceVersion`] identifies the format of the SOME/IP message body.
556///
557/// It should be incremented for any of the following reasons:
558///
559/// - incompatible changes to the payload format
560/// - incompatible changes to the service behavior
561/// - required by application design
562#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
563pub struct InterfaceVersion(u8);
564
565impl_basic_type_u8!(InterfaceVersion);
566
567/// [`MessageType`] and associated flags packed into a single byte.
568#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
569pub struct MessageTypeField(u8);
570
571impl_basic_type_u8!(MessageTypeField);
572
573impl MessageTypeField {
574    /// Transport Protocol flag. Determines if the message is a segment of a larger message.
575    pub const TP_FLAG: u8 = 0x20;
576
577    /// A mask of all [`MessageTypeField`] flags.
578    pub const ALL_FLAGS: u8 = Self::TP_FLAG;
579
580    /// Whether the Transport Protocol flag is set.
581    ///
582    /// # Examples
583    ///
584    /// ```rust
585    /// use rsomeip_proto::MessageTypeField;
586    ///
587    /// assert!(!MessageTypeField::new(0).is_tp());
588    /// assert!(MessageTypeField::new(MessageTypeField::TP_FLAG).is_tp());
589    /// ```
590    #[inline]
591    #[must_use]
592    pub const fn is_tp(&self) -> bool {
593        self.0 & Self::TP_FLAG == Self::TP_FLAG
594    }
595
596    /// Returns the mask of all currently enabled flags.
597    ///
598    /// # Examples
599    ///
600    /// ```rust
601    /// use rsomeip_proto::MessageTypeField;
602    ///
603    /// let mask = MessageTypeField::new(MessageTypeField::TP_FLAG).flags();
604    /// assert_eq!(mask, MessageTypeField::TP_FLAG);
605    /// ```
606    #[inline]
607    #[must_use]
608    pub const fn flags(self) -> u8 {
609        self.0 & Self::ALL_FLAGS
610    }
611
612    /// Returns this [`MessageTypeField`] with the given `flags` set to `enabled`.
613    ///
614    /// # Examples
615    ///
616    /// ```rust
617    /// use rsomeip_proto::MessageTypeField;
618    ///
619    /// let field = MessageTypeField::default()
620    ///     .with_flags(MessageTypeField::TP_FLAG, true);
621    /// assert_eq!(field.flags(), MessageTypeField::TP_FLAG);
622    ///
623    /// let field = field.with_flags(MessageTypeField::TP_FLAG, false);
624    /// assert_eq!(field.flags(), 0);
625    /// ```
626    #[inline]
627    #[must_use]
628    pub const fn with_flags(mut self, flags: u8, enabled: bool) -> Self {
629        if enabled {
630            self.0 |= flags;
631        } else {
632            self.0 &= !flags;
633        }
634        self
635    }
636
637    /// Returns the [`MessageType`] representation of this [`MessageTypeField`].
638    ///
639    /// Ignores all flags.
640    ///
641    /// # Examples
642    ///
643    /// ```rust
644    /// use rsomeip_proto::{MessageType, MessageTypeField};
645    ///
646    /// let field = MessageTypeField::new(0x80);
647    /// assert_eq!(field.as_type(), MessageType::Response);
648    /// ```
649    #[inline]
650    #[must_use]
651    pub const fn as_type(self) -> MessageType {
652        MessageType::from_u8(self.0 & !Self::ALL_FLAGS)
653    }
654
655    /// Creates a new [`MessageTypeField`] from the given [`MessageType`].
656    ///
657    /// # Examples
658    ///
659    /// ```rust
660    /// use rsomeip_proto::{MessageType, MessageTypeField};
661    ///
662    /// let field = MessageTypeField::from_type(MessageType::Response);
663    /// assert_eq!(field.as_u8(), 0x80);
664    /// ```
665    #[inline]
666    #[must_use]
667    pub const fn from_type(value: MessageType) -> Self {
668        Self::new(value.as_u8())
669    }
670}
671
672/// Type of a SOME/IP message.
673///
674/// It's used both by servers and clients to specify how the message should be interpreted by the
675/// peer.
676#[non_exhaustive]
677#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
678pub enum MessageType {
679    /// A request expecting a response.
680    #[default]
681    Request,
682    /// A fire-and-forget request.
683    RequestNoReturn,
684    /// A notification or event callback expecting no response.
685    Notification,
686    /// A response message.
687    Response,
688    /// A response containing an error.
689    Error,
690    /// Unknown message type.
691    Unknown(u8),
692}
693
694impl MessageType {
695    /// Creates a new [`MessageType`] from the given `value`.
696    #[inline]
697    #[must_use]
698    pub const fn from_u8(value: u8) -> Self {
699        match value {
700            0x00 => Self::Request,
701            0x01 => Self::RequestNoReturn,
702            0x02 => Self::Notification,
703            0x80 => Self::Response,
704            0x81 => Self::Error,
705            x => Self::Unknown(x),
706        }
707    }
708
709    /// Returns the [`u8`] representation of `self`.
710    #[inline]
711    #[must_use]
712    pub const fn as_u8(self) -> u8 {
713        match self {
714            Self::Request => 0x00,
715            Self::RequestNoReturn => 0x01,
716            Self::Notification => 0x02,
717            Self::Response => 0x80,
718            Self::Error => 0x81,
719            Self::Unknown(x) => x,
720        }
721    }
722}
723
724impl From<u8> for MessageType {
725    fn from(value: u8) -> Self {
726        Self::from_u8(value)
727    }
728}
729
730impl From<MessageType> for u8 {
731    fn from(value: MessageType) -> Self {
732        value.as_u8()
733    }
734}
735
736impl Serialize for MessageType {
737    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
738        u8::from(*self).serialize(buffer)
739    }
740
741    fn size_hint(&self) -> usize {
742        size_of::<u8>()
743    }
744}
745
746impl Deserialize for MessageType {
747    type Output = Self;
748
749    fn deserialize(buffer: &mut impl Buf) -> Result<Self::Output, DeserializeError> {
750        u8::deserialize(buffer).map(Self::from)
751    }
752}
753
754impl std::fmt::Display for MessageType {
755    /// Formats `self` using the given formatter.
756    ///
757    /// # Examples
758    ///
759    /// ```rust
760    /// use rsomeip_proto::MessageType;
761    ///
762    /// assert_eq!(format!("{}", MessageType::Request), "Request");
763    /// ```
764    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
765        write!(f, "{self:?}")
766    }
767}
768
769/// Result of processing a SOME/IP request.
770#[non_exhaustive]
771#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
772pub enum ReturnCode {
773    /// No error occurred.
774    #[default]
775    Ok,
776    /// An unspecified error occurred.
777    NotOk,
778    /// The requested [`ServiceId`] is unknown.
779    UnknownService,
780    /// The requested [`MethodId`] is unknown.
781    UnknownMethod,
782    /// Application not running.
783    NotReady,
784    /// System running the service not reachable (internal only).
785    NotReachable,
786    /// A timeout occurred (internal only).
787    Timeout,
788    /// Version of the SOME/IP protocol not supported.
789    WrongProtocolVersion,
790    /// Interface version mismatch.
791    WrongInterfaceVersion,
792    /// Payload could not be deserialized.
793    MalformedMessage,
794    /// Wrong [`MessageType`] was received.
795    WrongMessageType,
796    /// Repeated E2E calculation error.
797    E2eRepeated,
798    /// Wrong E2E sequence error.
799    E2eWrongSequence,
800    /// Unspecified E2E error.
801    E2e,
802    /// E2E not available.
803    E2eNotAvailable,
804    /// No new data for E2E calculation present.
805    E2eNoNewData,
806    /// Reserved for generic errors to be specified in future versions of SOME/IP.
807    Reserved(u8),
808    /// Reserved for errors specified by the service interface.
809    Other(u8),
810}
811
812impl From<u8> for ReturnCode {
813    fn from(value: u8) -> Self {
814        match value {
815            0x00 => Self::Ok,
816            0x01 => Self::NotOk,
817            0x02 => Self::UnknownService,
818            0x03 => Self::UnknownMethod,
819            0x04 => Self::NotReady,
820            0x05 => Self::NotReachable,
821            0x06 => Self::Timeout,
822            0x07 => Self::WrongProtocolVersion,
823            0x08 => Self::WrongInterfaceVersion,
824            0x09 => Self::MalformedMessage,
825            0x0a => Self::WrongMessageType,
826            0x0b => Self::E2eRepeated,
827            0x0c => Self::E2eWrongSequence,
828            0x0d => Self::E2e,
829            0x0e => Self::E2eNotAvailable,
830            0x0f => Self::E2eNoNewData,
831            n if (0x10..=0x5e).contains(&n) => Self::Reserved(n),
832            n => Self::Other(n),
833        }
834    }
835}
836
837impl From<ReturnCode> for u8 {
838    fn from(value: ReturnCode) -> Self {
839        match value {
840            ReturnCode::Ok => 0x00,
841            ReturnCode::NotOk => 0x01,
842            ReturnCode::UnknownService => 0x02,
843            ReturnCode::UnknownMethod => 0x03,
844            ReturnCode::NotReady => 0x04,
845            ReturnCode::NotReachable => 0x05,
846            ReturnCode::Timeout => 0x06,
847            ReturnCode::WrongProtocolVersion => 0x07,
848            ReturnCode::WrongInterfaceVersion => 0x08,
849            ReturnCode::MalformedMessage => 0x09,
850            ReturnCode::WrongMessageType => 0x0a,
851            ReturnCode::E2eRepeated => 0x0b,
852            ReturnCode::E2eWrongSequence => 0x0c,
853            ReturnCode::E2e => 0x0d,
854            ReturnCode::E2eNotAvailable => 0x0e,
855            ReturnCode::E2eNoNewData => 0x0f,
856            ReturnCode::Reserved(x) | ReturnCode::Other(x) => x,
857        }
858    }
859}
860
861impl Serialize for ReturnCode {
862    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
863        u8::from(*self).serialize(buffer)
864    }
865
866    fn size_hint(&self) -> usize {
867        size_of::<u8>()
868    }
869}
870
871impl Deserialize for ReturnCode {
872    type Output = Self;
873
874    fn deserialize(buffer: &mut impl Buf) -> Result<Self::Output, DeserializeError> {
875        u8::deserialize(buffer).map(Self::from)
876    }
877}
878
879impl std::fmt::Display for ReturnCode {
880    /// Formats `self` using the given formatter.
881    ///
882    /// # Examples
883    ///
884    /// ```rust
885    /// use rsomeip_proto::ReturnCode;
886    ///
887    /// assert_eq!(format!("{}", ReturnCode::Ok), "Ok");
888    /// ```
889    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
890        write!(f, "{self:?}")
891    }
892}
893
894#[cfg(test)]
895mod tests {
896    use super::*;
897    use rsomeip_bytes::{Bytes, BytesMut};
898
899    /// Tests the serialization and deserialization of new-types to and from their internal representation.
900    macro_rules! test_new_type_serialization {
901        ($name:ty, $repr:ty, $ser_test_name:ident, $de_test_name:ident) => {
902            #[test]
903            fn $ser_test_name() {
904                let value = <$name>::from(<$repr>::MAX);
905                let mut buffer = BytesMut::new();
906                assert_eq!(value.size_hint(), size_of::<$repr>());
907                assert_eq!(value.serialize(&mut buffer), Ok(size_of::<$repr>()));
908                assert_eq!(buffer[..], <$repr>::MAX.to_be_bytes()[..]);
909            }
910
911            #[test]
912            fn $de_test_name() {
913                let mut buffer = Bytes::copy_from_slice(&(<$repr>::MAX).to_be_bytes()[..]);
914                let value =
915                    <$name>::deserialize(&mut buffer).expect("should deserialize the value");
916                assert_eq!(<$repr>::from(value), <$repr>::MAX);
917            }
918        };
919    }
920
921    test_new_type_serialization!(
922        ServiceId,
923        u16,
924        service_id_is_serializable,
925        service_id_is_deserializable
926    );
927    test_new_type_serialization!(
928        MethodId,
929        u16,
930        method_id_is_serializable,
931        method_id_is_deserializable
932    );
933    test_new_type_serialization!(
934        MessageId,
935        u32,
936        message_id_is_serializable,
937        message_id_is_deserializable
938    );
939    test_new_type_serialization!(
940        ClientId,
941        u16,
942        client_id_is_serializable,
943        client_id_is_deserializable
944    );
945    test_new_type_serialization!(
946        SessionId,
947        u16,
948        session_id_is_serializable,
949        session_id_is_deserializable
950    );
951    test_new_type_serialization!(
952        RequestId,
953        u32,
954        request_id_is_serializable,
955        request_id_is_deserializable
956    );
957    test_new_type_serialization!(
958        ProtocolVersion,
959        u8,
960        protocol_version_is_serializable,
961        protocol_version_is_deserializable
962    );
963    test_new_type_serialization!(
964        InterfaceVersion,
965        u8,
966        interface_version_is_serializable,
967        interface_version_is_deserializable
968    );
969    test_new_type_serialization!(
970        MessageType,
971        u8,
972        message_type_is_serializable,
973        message_type_is_deserializable
974    );
975    test_new_type_serialization!(
976        MessageTypeField,
977        u8,
978        message_type_field_is_serializable,
979        message_type_field_is_deserializable
980    );
981    test_new_type_serialization!(
982        ReturnCode,
983        u8,
984        return_code_is_serializable,
985        return_code_is_deserializable
986    );
987
988    #[test]
989    fn message_id_converts_from_u32() {
990        let message_id = MessageId::from(0x1234_5678_u32);
991        assert_eq!(message_id.service.as_u16(), 0x1234);
992        assert_eq!(message_id.method.as_u16(), 0x5678);
993    }
994
995    #[test]
996    fn message_id_converts_to_u32() {
997        let service = ServiceId::new(0x1234);
998        let method = MethodId::new(0x5678);
999        assert_eq!(u32::from(MessageId::new(service, method)), 0x1234_5678_u32);
1000    }
1001
1002    #[test]
1003    fn request_id_converts_from_u32() {
1004        let request_id = RequestId::from(0x1234_5678_u32);
1005        assert_eq!(request_id.client.as_u16(), 0x1234);
1006        assert_eq!(request_id.session.as_u16(), 0x5678);
1007    }
1008
1009    #[test]
1010    fn request_id_converts_to_u32() {
1011        let client = ClientId::new(0x1234);
1012        let session = SessionId::new(0x5678);
1013        assert_eq!(u32::from(RequestId::new(client, session)), 0x1234_5678_u32);
1014    }
1015
1016    #[test]
1017    fn is_session_handling_enabled() {
1018        assert!(!SessionId::DISABLED.is_enabled());
1019        assert!(SessionId::ENABLED.is_enabled());
1020    }
1021
1022    #[test]
1023    fn session_id_wraps_to_1() {
1024        let mut session = SessionId::new(0xffff);
1025        assert_eq!(session.increment().as_u16(), 0xffff);
1026        assert_eq!(session.as_u16(), 1);
1027    }
1028
1029    #[test]
1030    fn message_type_converts_from_u8() {
1031        assert_eq!(MessageType::from(0x00), MessageType::Request);
1032        assert_eq!(MessageType::from(0x01), MessageType::RequestNoReturn);
1033        assert_eq!(MessageType::from(0x02), MessageType::Notification);
1034        assert_eq!(MessageType::from(0x80), MessageType::Response);
1035        assert_eq!(MessageType::from(0x81), MessageType::Error);
1036        (u8::MIN..=u8::MAX)
1037            .filter(|x| ![0x00, 0x01, 0x02, 0x80, 0x81, 0x20, 0x21, 0x22, 0xa0, 0xa1].contains(x))
1038            .for_each(|x| {
1039                assert_eq!(MessageType::Unknown(x), MessageType::from(x));
1040            });
1041    }
1042
1043    #[test]
1044    fn message_type_converts_to_u8() {
1045        assert_eq!(0x00, u8::from(MessageType::Request));
1046        assert_eq!(0x01, u8::from(MessageType::RequestNoReturn));
1047        assert_eq!(0x02, u8::from(MessageType::Notification));
1048        assert_eq!(0x80, u8::from(MessageType::Response));
1049        assert_eq!(0x81, u8::from(MessageType::Error));
1050        (u8::MIN..=u8::MAX)
1051            .filter(|x| ![0x00, 0x01, 0x02, 0x80, 0x81, 0x20, 0x21, 0x22, 0xa0, 0xa1].contains(x))
1052            .for_each(|x| {
1053                assert_eq!(u8::from(MessageType::Unknown(x)), x);
1054            });
1055    }
1056
1057    #[test]
1058    fn return_code_converts_from_u8() {
1059        assert_eq!(ReturnCode::from(0x00), ReturnCode::Ok);
1060        assert_eq!(ReturnCode::from(0x01), ReturnCode::NotOk);
1061        assert_eq!(ReturnCode::from(0x02), ReturnCode::UnknownService);
1062        assert_eq!(ReturnCode::from(0x03), ReturnCode::UnknownMethod);
1063        assert_eq!(ReturnCode::from(0x04), ReturnCode::NotReady);
1064        assert_eq!(ReturnCode::from(0x05), ReturnCode::NotReachable);
1065        assert_eq!(ReturnCode::from(0x06), ReturnCode::Timeout);
1066        assert_eq!(ReturnCode::from(0x07), ReturnCode::WrongProtocolVersion);
1067        assert_eq!(ReturnCode::from(0x08), ReturnCode::WrongInterfaceVersion);
1068        assert_eq!(ReturnCode::from(0x09), ReturnCode::MalformedMessage);
1069        assert_eq!(ReturnCode::from(0x0a), ReturnCode::WrongMessageType);
1070        assert_eq!(ReturnCode::from(0x0b), ReturnCode::E2eRepeated);
1071        assert_eq!(ReturnCode::from(0x0c), ReturnCode::E2eWrongSequence);
1072        assert_eq!(ReturnCode::from(0x0d), ReturnCode::E2e);
1073        assert_eq!(ReturnCode::from(0x0e), ReturnCode::E2eNotAvailable);
1074        assert_eq!(ReturnCode::from(0x0f), ReturnCode::E2eNoNewData);
1075        (0x10..=0x5e).for_each(|x| assert_eq!(ReturnCode::Reserved(x), ReturnCode::from(x)));
1076        (0x5f..=u8::MAX).for_each(|x| assert_eq!(ReturnCode::Other(x), ReturnCode::from(x)));
1077    }
1078
1079    #[test]
1080    fn return_code_converts_to_u8() {
1081        assert_eq!(0x00, u8::from(ReturnCode::Ok));
1082        assert_eq!(0x01, u8::from(ReturnCode::NotOk));
1083        assert_eq!(0x02, u8::from(ReturnCode::UnknownService));
1084        assert_eq!(0x03, u8::from(ReturnCode::UnknownMethod));
1085        assert_eq!(0x04, u8::from(ReturnCode::NotReady));
1086        assert_eq!(0x05, u8::from(ReturnCode::NotReachable));
1087        assert_eq!(0x06, u8::from(ReturnCode::Timeout));
1088        assert_eq!(0x07, u8::from(ReturnCode::WrongProtocolVersion));
1089        assert_eq!(0x08, u8::from(ReturnCode::WrongInterfaceVersion));
1090        assert_eq!(0x09, u8::from(ReturnCode::MalformedMessage));
1091        assert_eq!(0x0a, u8::from(ReturnCode::WrongMessageType));
1092        assert_eq!(0x0b, u8::from(ReturnCode::E2eRepeated));
1093        assert_eq!(0x0c, u8::from(ReturnCode::E2eWrongSequence));
1094        assert_eq!(0x0d, u8::from(ReturnCode::E2e));
1095        assert_eq!(0x0e, u8::from(ReturnCode::E2eNotAvailable));
1096        assert_eq!(0x0f, u8::from(ReturnCode::E2eNoNewData));
1097        (0x10..=0x5e).for_each(|x| assert_eq!(u8::from(ReturnCode::Reserved(x)), x));
1098        (0x5f..=u8::MAX).for_each(|x| assert_eq!(u8::from(ReturnCode::Other(x)), x));
1099    }
1100}