Skip to main content

rsomeip_proto/
message.rs

1//! SOME/IP message.
2//!
3//! This module provides the definition for the SOME/IP message.
4
5use crate::{
6    ClientId, InterfaceVersion, MessageId, MessageType, MessageTypeField, MethodId,
7    ProtocolVersion, RequestId, ReturnCode, ServiceId, SessionId,
8};
9use rsomeip_bytes::{
10    Buf, BufMut, Bytes, Deserialize, DeserializeError, Serialize, SerializeError, deserialize_from,
11    serialize_into, size_hint,
12};
13
14/// Message addressed to a service instance.
15///
16/// This is used to identify the contents of the payload so that it can be correctly serialized.
17///
18/// Has room for a header to include additional information about the body of the message.
19///
20/// # Notes
21///
22/// This is the generic implementation. You probably want to use [`Message<T>`] instead.
23///
24/// [`Message<T>`]: crate::Message<T>
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub struct GenericMessage<H, B> {
27    /// Identifier of the service interface.
28    pub service: ServiceId,
29    /// Identifier of the method or event.
30    pub method: MethodId,
31    /// Additional information about the message.
32    pub header: H,
33    /// Contents of the message.
34    pub body: B,
35}
36
37// Constructor and accessors.
38impl<H, B> GenericMessage<H, B> {
39    /// Creates a new [`GenericMessage<H, B>`].
40    ///
41    /// # Examples
42    ///
43    /// ```rust
44    /// use rsomeip_proto::GenericMessage;
45    ///
46    /// let message = GenericMessage::new("header", "body");
47    /// assert_eq!(message.header, "header");
48    /// assert_eq!(message.body, "body");
49    /// ```
50    #[inline]
51    #[must_use]
52    pub const fn new(header: H, body: B) -> Self {
53        Self {
54            service: ServiceId::new(0),
55            method: MethodId::new(0),
56            header,
57            body,
58        }
59    }
60
61    /// Returns the [`MessageId`] portion of this message.
62    ///
63    /// # Examples
64    ///
65    /// ```rust
66    /// use rsomeip_proto::{GenericMessage, ServiceId, MethodId};
67    ///
68    /// let message = GenericMessage::new("header", "body")
69    ///     .with_service(ServiceId::new(0x1234))
70    ///     .with_method(MethodId::new(0x5678));
71    /// assert_eq!(message.id().as_u32(), 0x1234_5678);
72    /// ```
73    #[inline]
74    #[must_use]
75    pub const fn id(&self) -> MessageId {
76        MessageId::new(self.service, self.method)
77    }
78
79    /// Returns `self` with the given [`MessageId`].
80    ///
81    /// # Examples
82    ///
83    /// ```rust
84    /// use rsomeip_proto::{GenericMessage, MessageId};
85    ///
86    /// let message = GenericMessage::new("header", "body").with_id(MessageId::from(0x1234_5678));
87    /// assert_eq!(message.service.as_u16(), 0x1234);
88    /// assert_eq!(message.method.as_u16(), 0x5678);
89    /// ```
90    #[inline]
91    #[must_use]
92    pub const fn with_id(mut self, id: MessageId) -> Self {
93        self.service = id.service;
94        self.method = id.method;
95        self
96    }
97
98    /// Returns `self` with the given [`ServiceId`].
99    ///
100    /// # Examples
101    ///
102    /// ```rust
103    /// use rsomeip_proto::{GenericMessage, ServiceId};
104    ///
105    /// let message = GenericMessage::new("header", "body").with_service(ServiceId::new(0x1234));
106    /// assert_eq!(message.service.as_u16(), 0x1234);
107    /// ```
108    #[inline]
109    #[must_use]
110    pub const fn with_service(mut self, service: ServiceId) -> Self {
111        self.service = service;
112        self
113    }
114
115    /// Returns `self` with the given [`MethodId`].
116    ///
117    /// # Examples
118    ///
119    /// ```rust
120    /// use rsomeip_proto::{GenericMessage, MethodId};
121    ///
122    /// let message = GenericMessage::new("header", "body").with_method(MethodId::new(0x1234));
123    /// assert_eq!(message.method.as_u16(), 0x1234);
124    /// ```
125    #[inline]
126    #[must_use]
127    pub const fn with_method(mut self, method: MethodId) -> Self {
128        self.method = method;
129        self
130    }
131
132    /// Maps a [`GenericMessage<H, B>`] to a [`GenericMessage<T, B>`] by replacing the header of the message
133    /// with the given value.
134    ///
135    /// # Examples
136    ///
137    /// ```rust
138    /// use rsomeip_proto::GenericMessage;
139    ///
140    /// let message = GenericMessage::new("header", "body").with_header(0x1234_u16);
141    /// assert_eq!(message.header, 0x1234_u16);
142    /// ```
143    #[inline]
144    #[must_use]
145    pub fn with_header<T>(self, header: T) -> GenericMessage<T, B> {
146        GenericMessage::new(header, self.body)
147            .with_service(self.service)
148            .with_method(self.method)
149    }
150
151    /// Maps a [`GenericMessage<H, B>`] to a [`GenericMessage<H, T>`] by replacing the body of the message with the
152    /// given value.
153    ///
154    /// # Examples
155    ///
156    /// ```rust
157    /// use rsomeip_proto::GenericMessage;
158    ///
159    /// let message = GenericMessage::new("header", "body").with_body(0x1234_u16);
160    /// assert_eq!(message.body, 0x1234_u16);
161    /// ```
162    #[inline]
163    #[must_use]
164    pub fn with_body<T>(self, body: T) -> GenericMessage<H, T> {
165        GenericMessage::new(self.header, body)
166            .with_service(self.service)
167            .with_method(self.method)
168    }
169
170    /// Maps a [`GenericMessage<H, B>`] to a [`GenericMessage<T, U>`] by applying a function to the header and body
171    /// of the message.
172    ///
173    /// # Examples
174    ///
175    /// ```rust
176    /// use rsomeip_proto::GenericMessage;
177    ///
178    /// let message = GenericMessage::new(1u8, 2u8)
179    ///     .map(|header, body| (header + 1, body + 1));
180    /// assert_eq!(message.header, 2);
181    /// assert_eq!(message.body, 3);
182    /// ```
183    #[inline]
184    #[must_use]
185    pub fn map<T, U, F>(self, f: F) -> GenericMessage<T, U>
186    where
187        F: FnOnce(H, B) -> (T, U),
188    {
189        let (header, body) = f(self.header, self.body);
190        GenericMessage::new(header, body)
191            .with_service(self.service)
192            .with_method(self.method)
193    }
194
195    /// Maps a [`GenericMessage<H, B>`] to a [`GenericMessage<T, B>`] by applying a function to the header of the
196    /// message.
197    ///
198    /// # Examples
199    ///
200    /// ```rust
201    /// use rsomeip_proto::GenericMessage;
202    ///
203    /// let message = GenericMessage::new(1u8, "body").map_header(|header| header + 1);
204    /// assert_eq!(message.header, 2);
205    /// ```
206    #[inline]
207    #[must_use]
208    pub fn map_header<T, F>(self, f: F) -> GenericMessage<T, B>
209    where
210        F: FnOnce(H) -> T,
211    {
212        GenericMessage::new(f(self.header), self.body)
213            .with_service(self.service)
214            .with_method(self.method)
215    }
216
217    /// Maps a [`GenericMessage<H, B>`] to a [`GenericMessage<H, T>`] by applying a function to the body of the
218    /// message.
219    ///
220    /// # Examples
221    ///
222    /// ```rust
223    /// use rsomeip_proto::GenericMessage;
224    ///
225    /// let message = GenericMessage::new("header", 2u8).map_body(|body| body + 1);
226    /// assert_eq!(message.body, 3);
227    /// ```
228    #[inline]
229    #[must_use]
230    pub fn map_body<T, F>(self, f: F) -> GenericMessage<H, T>
231    where
232        F: FnOnce(B) -> T,
233    {
234        GenericMessage::new(self.header, f(self.body))
235            .with_service(self.service)
236            .with_method(self.method)
237    }
238
239    /// Replaces the header of the message with the given `value`.
240    ///
241    /// Returns the old value.
242    ///
243    /// # Examples
244    ///
245    /// ```rust
246    /// use rsomeip_proto::GenericMessage;
247    ///
248    /// let mut message = GenericMessage::new("header", "body");
249    /// assert_eq!(message.replace_header("new_header"), "header");
250    /// assert_eq!(message.header, "new_header");
251    /// ```
252    #[inline]
253    #[must_use]
254    pub const fn replace_header(&mut self, value: H) -> H {
255        std::mem::replace(&mut self.header, value)
256    }
257
258    /// Replaces the body of the message with the given `value`.
259    ///
260    /// Returns the old value.
261    ///
262    /// # Examples
263    ///
264    /// ```rust
265    /// use rsomeip_proto::GenericMessage;
266    ///
267    /// let mut message = GenericMessage::new("header", "body");
268    /// assert_eq!(message.replace_body("new_body"), "body");
269    /// assert_eq!(message.body, "new_body");
270    /// ```
271    #[inline]
272    #[must_use]
273    pub const fn replace_body(&mut self, value: B) -> B {
274        std::mem::replace(&mut self.body, value)
275    }
276}
277
278/// Specialization for the [`Header`] type.
279impl<B> GenericMessage<Header, B> {
280    /// Returns `self` as a response message with the given `return_code`.
281    ///
282    /// # Examples
283    ///
284    /// ```rust
285    /// use rsomeip_proto::{GenericMessage, Header, MessageType, ReturnCode};
286    ///
287    /// let message = GenericMessage::new(Header::new(), "body")
288    ///     .into_response(ReturnCode::NotOk);
289    /// assert_eq!(message.header.message_type.as_type(), MessageType::Response);
290    /// assert_eq!(message.header.return_code, ReturnCode::NotOk);
291    /// assert_eq!(message.body, "body");
292    /// ```
293    #[inline]
294    #[must_use]
295    pub fn into_response(self, return_code: ReturnCode) -> Self {
296        self.map_header(|header| {
297            header
298                .with_message_type(MessageType::Response)
299                .with_return_code(return_code)
300        })
301    }
302
303    /// Returns `self` as an error message with the given `return_code`.
304    ///
305    /// # Examples
306    ///
307    /// ```rust
308    /// use rsomeip_proto::{GenericMessage, Header, MessageType, ReturnCode};
309    ///
310    /// let message = GenericMessage::new(Header::new(), "body")
311    ///     .into_error(ReturnCode::NotOk);
312    /// assert_eq!(message.header.message_type.as_type(), MessageType::Error);
313    /// assert_eq!(message.header.return_code, ReturnCode::NotOk);
314    /// assert_eq!(message.body, "body");
315    /// ```
316    #[inline]
317    #[must_use]
318    pub fn into_error(self, return_code: ReturnCode) -> Self {
319        self.map_header(|header| {
320            header
321                .with_message_type(MessageType::Error)
322                .with_return_code(return_code)
323        })
324    }
325
326    /// Returns the [`ClientId`] portion of the [`Header`].
327    ///
328    /// # Examples
329    ///
330    /// ```rust
331    /// use rsomeip_proto::{GenericMessage, Header, ClientId};
332    ///
333    /// let message = GenericMessage::new(Header::new(), "body")
334    ///     .with_client(ClientId::new(0x1234));
335    /// assert_eq!(message.client().as_u16(), 0x1234);
336    /// ```
337    #[inline]
338    #[must_use]
339    pub const fn client(&self) -> ClientId {
340        self.header.client
341    }
342
343    /// Returns `self` with the given [`ClientId`].
344    ///
345    /// # Examples
346    ///
347    /// ```rust
348    /// use rsomeip_proto::{GenericMessage, Header, ClientId};
349    ///
350    /// let message = GenericMessage::new(Header::new(), "body")
351    ///     .with_client(ClientId::new(0x1234));
352    /// assert_eq!(message.client().as_u16(), 0x1234);
353    /// ```
354    #[inline]
355    #[must_use]
356    pub const fn with_client(mut self, client: ClientId) -> Self {
357        self.header.client = client;
358        self
359    }
360
361    /// Returns the [`SessionId`] portion of the [`Header`].
362    ///
363    /// # Examples
364    ///
365    /// ```rust
366    /// use rsomeip_proto::{GenericMessage, Header, SessionId};
367    ///
368    /// let message = GenericMessage::new(Header::new(), "body")
369    ///     .with_session(SessionId::new(0x1234));
370    /// assert_eq!(message.session().as_u16(), 0x1234);
371    /// ```
372    #[inline]
373    #[must_use]
374    pub const fn session(&self) -> SessionId {
375        self.header.session
376    }
377
378    /// Returns `self` with the given [`SessionId`].
379    ///
380    /// # Examples
381    ///
382    /// ```rust
383    /// use rsomeip_proto::{GenericMessage, Header, SessionId};
384    ///
385    /// let message = GenericMessage::new(Header::new(), "body")
386    ///     .with_session(SessionId::new(0x1234));
387    /// assert_eq!(message.session().as_u16(), 0x1234);
388    /// ```
389    #[inline]
390    #[must_use]
391    pub const fn with_session(mut self, session: SessionId) -> Self {
392        self.header.session = session;
393        self
394    }
395
396    /// Returns the [`ProtocolVersion`] portion of the [`Header`].
397    ///
398    /// # Examples
399    ///
400    /// ```rust
401    /// use rsomeip_proto::{GenericMessage, Header, ProtocolVersion};
402    ///
403    /// let message = GenericMessage::new(Header::new(), "body")
404    ///     .with_protocol(ProtocolVersion::new(0x12));
405    /// assert_eq!(message.protocol().as_u8(), 0x12);
406    /// ```
407    #[inline]
408    #[must_use]
409    pub const fn protocol(&self) -> ProtocolVersion {
410        self.header.protocol
411    }
412
413    /// Returns `self` with the given [`ProtocolVersion`].
414    ///
415    /// # Examples
416    ///
417    /// ```rust
418    /// use rsomeip_proto::{GenericMessage, Header, ProtocolVersion};
419    ///
420    /// let message = GenericMessage::new(Header::new(), "body")
421    ///     .with_protocol(ProtocolVersion::new(0x12));
422    /// assert_eq!(message.protocol().as_u8(), 0x12);
423    /// ```
424    #[inline]
425    #[must_use]
426    pub const fn with_protocol(mut self, protocol: ProtocolVersion) -> Self {
427        self.header.protocol = protocol;
428        self
429    }
430
431    /// Returns the [`InterfaceVersion`] portion of the [`Header`].
432    ///
433    /// # Examples
434    ///
435    /// ```rust
436    /// use rsomeip_proto::{GenericMessage, Header, InterfaceVersion};
437    ///
438    /// let message = GenericMessage::new(Header::new(), "body")
439    ///     .with_interface(InterfaceVersion::new(0x12));
440    /// assert_eq!(message.interface().as_u8(), 0x12);
441    /// ```
442    #[inline]
443    #[must_use]
444    pub const fn interface(&self) -> InterfaceVersion {
445        self.header.interface
446    }
447
448    /// Returns `self` with the given [`InterfaceVersion`].
449    ///
450    /// # Examples
451    ///
452    /// ```rust
453    /// use rsomeip_proto::{GenericMessage, Header, InterfaceVersion};
454    ///
455    /// let message = GenericMessage::new(Header::new(), "body")
456    ///     .with_interface(InterfaceVersion::new(0x12));
457    /// assert_eq!(message.interface().as_u8(), 0x12);
458    /// ```
459    #[inline]
460    #[must_use]
461    pub const fn with_interface(mut self, interface: InterfaceVersion) -> Self {
462        self.header.interface = interface;
463        self
464    }
465
466    /// Returns the [`MessageType`] of this [`GenericMessage<Header, B>`].
467    ///
468    /// # Examples
469    ///
470    /// ```rust
471    /// use rsomeip_proto::{GenericMessage, Header, MessageType};
472    ///
473    /// let message = GenericMessage::new(Header::new(), "body")
474    ///     .with_message_type(MessageType::Notification);
475    /// assert_eq!(message.message_type(), MessageType::Notification);
476    /// ```
477    #[inline]
478    #[must_use]
479    pub const fn message_type(&self) -> MessageType {
480        self.header.message_type.as_type()
481    }
482
483    /// Returns `self` with the given [`MessageType`].
484    ///
485    /// # Examples
486    ///
487    /// ```rust
488    /// use rsomeip_proto::{GenericMessage, Header, MessageType};
489    ///
490    /// let message = GenericMessage::new(Header::new(), "body")
491    ///     .with_message_type(MessageType::Notification);
492    /// assert_eq!(message.message_type(), MessageType::Notification);
493    /// ```
494    #[inline]
495    #[must_use]
496    pub const fn with_message_type(mut self, message_type: MessageType) -> Self {
497        self.header.message_type = MessageTypeField::from_type(message_type);
498        self
499    }
500
501    /// Returns the [`ReturnCode`] portion of the [`Header`].
502    ///
503    /// # Examples
504    ///
505    /// ```rust
506    /// use rsomeip_proto::{GenericMessage, Header, ReturnCode};
507    ///
508    /// let message = GenericMessage::new(Header::new(), "body")
509    ///     .with_return_code(ReturnCode::E2e);
510    /// assert_eq!(message.return_code(), ReturnCode::E2e);
511    /// ```
512    #[inline]
513    #[must_use]
514    pub const fn return_code(&self) -> ReturnCode {
515        self.header.return_code
516    }
517
518    /// Returns `self` with the given [`ReturnCode`].
519    ///
520    /// # Examples
521    ///
522    /// ```rust
523    /// use rsomeip_proto::{GenericMessage, Header, ReturnCode};
524    ///
525    /// let message = GenericMessage::new(Header::new(), "body")
526    ///     .with_return_code(ReturnCode::E2e);
527    /// assert_eq!(message.return_code(), ReturnCode::E2e);
528    /// ```
529    #[inline]
530    #[must_use]
531    pub const fn with_return_code(mut self, return_code: ReturnCode) -> Self {
532        self.header.return_code = return_code;
533        self
534    }
535}
536
537impl<H, B> Serialize for GenericMessage<H, B>
538where
539    H: Serialize,
540    B: Serialize,
541{
542    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
543        let mut size = 0;
544        size += serialize_into!(buffer, self.service, self.method)?;
545        size += serialize_into!(buffer, length = U32, &self.header, &self.body)?;
546        Ok(size)
547    }
548
549    fn size_hint(&self) -> usize {
550        let mut size = 0;
551        size += size_hint!(self.service, self.method);
552        size += size_hint!(length = U32, &self.header, &self.body);
553        size
554    }
555}
556
557impl<H, B> Deserialize for GenericMessage<H, B>
558where
559    H: Deserialize<Output = H>,
560    B: Deserialize<Output = B>,
561{
562    type Output = Self;
563
564    fn deserialize(buffer: &mut impl Buf) -> Result<Self::Output, DeserializeError> {
565        let (service, method) = deserialize_from!(buffer, ServiceId, MethodId)?;
566        let (header, body) = deserialize_from!(buffer, length = U32, H, B)?;
567        Ok(Self {
568            service,
569            method,
570            header,
571            body,
572        })
573    }
574}
575
576impl<H, B> GenericMessage<H, B>
577where
578    H: Serialize + Deserialize<Output = H>,
579    B: Serialize + Deserialize<Output = B>,
580{
581    /// Returns a buffer containing the serialized message.
582    ///
583    /// # Errors
584    ///
585    /// Returns a [`SerializeError`] if the message could not be serialized.
586    pub fn to_bytes(&self) -> Result<Bytes, SerializeError> {
587        let mut buffer = rsomeip_bytes::BytesMut::new();
588        self.serialize(&mut buffer)?;
589        Ok(buffer.freeze())
590    }
591
592    /// Returns a [`GenericMessage<H, B>`] deserialized from the `buffer`.
593    ///
594    /// # Errors
595    ///
596    /// Returns a [`DeserializeError`] if the message could not be deserialized.
597    pub fn from_bytes(buffer: &mut impl Buf) -> Result<Self, DeserializeError> {
598        Self::deserialize(buffer)
599    }
600}
601
602impl<H, B> Default for GenericMessage<H, B>
603where
604    H: Default,
605    B: Default,
606{
607    fn default() -> Self {
608        Self {
609            service: ServiceId::default(),
610            method: MethodId::default(),
611            header: H::default(),
612            body: B::default(),
613        }
614    }
615}
616
617impl<H, B> std::fmt::Display for GenericMessage<H, B>
618where
619    H: std::fmt::Display,
620{
621    /// Formats `self` into a string.
622    ///
623    /// # Examples
624    ///
625    /// ```rust
626    /// use rsomeip_proto::{GenericMessage, ServiceId, MethodId};
627    ///
628    /// let message = GenericMessage::new("header", "body")
629    ///     .with_service(ServiceId::new(0x1234))
630    ///     .with_method(MethodId::new(0x5678));
631    /// assert_eq!(message.to_string(), "1234.5678.header")
632    /// ```
633    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
634        write!(f, "{}.{}.{}", self.service, self.method, self.header)
635    }
636}
637
638/// Header of a SOME/IP message.
639///
640/// Contains additional information about the message itself.
641#[derive(Debug, Clone, Copy, PartialEq, Eq)]
642pub struct Header {
643    /// Client that sent the message.
644    pub client: ClientId,
645    /// Order of the message in a sequence.
646    pub session: SessionId,
647    /// Major version of the SOME/IP protocol.
648    pub protocol: ProtocolVersion,
649    /// Major version of the service interface.
650    pub interface: InterfaceVersion,
651    /// Message type and associated flags.
652    pub message_type: MessageTypeField,
653    /// Result of processing the message.
654    pub return_code: ReturnCode,
655}
656
657impl Header {
658    /// Creates a new [`Header`].
659    #[inline]
660    #[must_use]
661    pub const fn new() -> Self {
662        Self {
663            client: ClientId::new(0),
664            session: SessionId::DISABLED,
665            protocol: ProtocolVersion::new(1),
666            interface: InterfaceVersion::new(0),
667            message_type: MessageTypeField::new(0),
668            return_code: ReturnCode::Ok,
669        }
670    }
671
672    /// Returns the [`RequestId`] portion of `self`.
673    ///
674    /// # Examples
675    ///
676    /// ```rust
677    /// use rsomeip_proto::{Header, ClientId, SessionId};
678    ///
679    /// let header = Header::new()
680    ///     .with_client(ClientId::new(0x1234))
681    ///     .with_session(SessionId::new(0x5678));
682    /// assert_eq!(header.id().as_u32(), 0x1234_5678);
683    /// ```
684    #[inline]
685    #[must_use]
686    pub const fn id(&self) -> RequestId {
687        RequestId::new(self.client, self.session)
688    }
689
690    /// Returns `self` with the given [`RequestId`].
691    ///
692    /// # Examples
693    ///
694    /// ```rust
695    /// use rsomeip_proto::{Header, RequestId};
696    ///
697    /// let header = Header::new().with_id(RequestId::from(0x1234_5678));
698    /// assert_eq!(header.client.as_u16(), 0x1234);
699    /// assert_eq!(header.session.as_u16(), 0x5678);
700    /// ```
701    #[inline]
702    #[must_use]
703    pub const fn with_id(mut self, id: RequestId) -> Self {
704        self.client = id.client;
705        self.session = id.session;
706        self
707    }
708
709    /// Returns `self` with the given [`ClientId`].
710    ///
711    /// # Examples
712    ///
713    /// ```rust
714    /// use rsomeip_proto::{Header, ClientId};
715    ///
716    /// let header = Header::new().with_client(ClientId::new(0x1234));
717    /// assert_eq!(header.client.as_u16(), 0x1234);
718    /// ```
719    #[inline]
720    #[must_use]
721    pub const fn with_client(mut self, client: ClientId) -> Self {
722        self.client = client;
723        self
724    }
725
726    /// Returns `self` with the given [`SessionId`].
727    ///
728    /// # Examples
729    ///
730    /// ```rust
731    /// use rsomeip_proto::{Header, SessionId};
732    ///
733    /// let header = Header::new().with_session(SessionId::new(0x1234));
734    /// assert_eq!(header.session.as_u16(), 0x1234);
735    /// ```
736    #[inline]
737    #[must_use]
738    pub const fn with_session(mut self, session: SessionId) -> Self {
739        self.session = session;
740        self
741    }
742
743    /// Returns `self` with the given [`ProtocolVersion`].
744    ///
745    /// # Examples
746    ///
747    /// ```rust
748    /// use rsomeip_proto::{Header, ProtocolVersion};
749    ///
750    /// let header = Header::new().with_protocol(ProtocolVersion::new(0x12));
751    /// assert_eq!(header.protocol.as_u8(), 0x12);
752    /// ```
753    #[inline]
754    #[must_use]
755    pub const fn with_protocol(mut self, protocol: ProtocolVersion) -> Self {
756        self.protocol = protocol;
757        self
758    }
759
760    /// Returns `self` with the given [`InterfaceVersion`].
761    ///
762    /// # Examples
763    ///
764    /// ```rust
765    /// use rsomeip_proto::{Header, InterfaceVersion};
766    ///
767    /// let header = Header::new().with_interface(InterfaceVersion::new(0x12));
768    /// assert_eq!(header.interface.as_u8(), 0x12);
769    /// ```
770    #[inline]
771    #[must_use]
772    pub const fn with_interface(mut self, interface: InterfaceVersion) -> Self {
773        self.interface = interface;
774        self
775    }
776
777    /// Returns `self` with the given [`MessageType`].
778    ///
779    /// # Examples
780    ///
781    /// ```rust
782    /// use rsomeip_proto::{Header, MessageType};
783    ///
784    /// let header = Header::new().with_message_type(MessageType::Notification);
785    /// assert_eq!(header.message_type.as_type(), MessageType::Notification);
786    /// ```
787    #[inline]
788    #[must_use]
789    pub const fn with_message_type(mut self, message_type: MessageType) -> Self {
790        self.message_type = MessageTypeField::from_type(message_type);
791        self
792    }
793
794    /// Returns `self` with the given [`ReturnCode`].
795    ///
796    /// # Examples
797    ///
798    /// ```rust
799    /// use rsomeip_proto::{Header, ReturnCode};
800    ///
801    /// let header = Header::new().with_return_code(ReturnCode::NotOk);
802    /// assert_eq!(header.return_code, ReturnCode::NotOk);
803    /// ```
804    #[inline]
805    #[must_use]
806    pub const fn with_return_code(mut self, return_code: ReturnCode) -> Self {
807        self.return_code = return_code;
808        self
809    }
810}
811
812impl Default for Header {
813    fn default() -> Self {
814        Self::new()
815    }
816}
817
818impl Serialize for Header {
819    fn serialize(&self, buffer: &mut impl BufMut) -> Result<usize, SerializeError> {
820        serialize_into!(
821            buffer,
822            self.client,
823            self.session,
824            self.protocol,
825            self.interface,
826            self.message_type,
827            self.return_code
828        )
829    }
830
831    fn size_hint(&self) -> usize {
832        size_hint!(
833            self.client,
834            self.session,
835            self.protocol,
836            self.interface,
837            self.message_type,
838            self.return_code
839        )
840    }
841}
842
843impl Deserialize for Header {
844    type Output = Self;
845
846    fn deserialize(buffer: &mut impl Buf) -> Result<Self::Output, DeserializeError> {
847        Ok(Self {
848            client: ClientId::deserialize(buffer)?,
849            session: SessionId::deserialize(buffer)?,
850            protocol: ProtocolVersion::deserialize(buffer)?,
851            interface: InterfaceVersion::deserialize(buffer)?,
852            message_type: MessageTypeField::deserialize(buffer)?,
853            return_code: ReturnCode::deserialize(buffer)?,
854        })
855    }
856}
857
858impl std::fmt::Display for Header {
859    /// Formats `self` using the given formatter.
860    ///
861    /// # Examples
862    ///
863    /// ```rust
864    /// use rsomeip_proto::{Header, ClientId, SessionId, MessageType, ReturnCode};
865    ///
866    /// let header = Header::default()
867    ///     .with_client(ClientId::new(0x1234))
868    ///     .with_session(SessionId::new(0x5678))
869    ///     .with_message_type(MessageType::Notification)
870    ///     .with_return_code(ReturnCode::Ok);
871    /// assert_eq!(header.to_string(), "1234.5678.02.00")
872    /// ```
873    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
874        write!(
875            f,
876            "{}.{}.{:02x?}.{:02x?}",
877            self.client,
878            self.session,
879            u8::from(self.message_type),
880            u8::from(self.return_code)
881        )
882    }
883}
884
885#[cfg(test)]
886mod tests {
887    use super::*;
888    use rsomeip_bytes::BytesMut;
889
890    const DESERIALIZED_MESSAGE: GenericMessage<u8, u8> = GenericMessage::new(1u8, 2u8)
891        .with_service(ServiceId::new(0x1234_u16))
892        .with_method(MethodId::new(0x5678_u16));
893
894    const SERIALIZED_MESSAGE: [u8; 10] = [
895        0x12, 0x34, // ServiceId
896        0x56, 0x78, // MethodId
897        0x00, 0x00, 0x00, 0x02, // Length
898        0x01, // Header
899        0x02, // Body
900    ];
901
902    #[test]
903    fn message_is_serializable() {
904        let mut buffer = BytesMut::new();
905        assert_eq!(DESERIALIZED_MESSAGE.size_hint(), SERIALIZED_MESSAGE.len());
906        assert_eq!(
907            DESERIALIZED_MESSAGE.serialize(&mut buffer),
908            Ok(SERIALIZED_MESSAGE.len())
909        );
910        assert_eq!(buffer[..], SERIALIZED_MESSAGE[..]);
911    }
912
913    #[test]
914    fn message_is_deserializable() {
915        let mut buffer = Bytes::copy_from_slice(&SERIALIZED_MESSAGE[..]);
916        let message = GenericMessage::<u8, u8>::deserialize(&mut buffer)
917            .expect("should deserialize the message");
918        assert_eq!(message, DESERIALIZED_MESSAGE);
919    }
920
921    const DESERIALIZED_HEADER: Header = Header::new()
922        .with_client(ClientId::new(0x1234))
923        .with_session(SessionId::new(0x5678))
924        .with_protocol(ProtocolVersion::new(0x9a))
925        .with_interface(InterfaceVersion::new(0xbc))
926        .with_message_type(MessageType::Error)
927        .with_return_code(ReturnCode::E2e);
928
929    const SERIALIZED_HEADER: [u8; 8] = [
930        0x12, 0x34, // ClientId
931        0x56, 0x78, // SessionId
932        0x9a, // ProtocolVersion
933        0xbc, // InterfaceVersion
934        0x81, // MessageType
935        0x0d, // ReturnCode
936    ];
937
938    #[test]
939    fn header_is_serializable() {
940        let mut buffer = BytesMut::new();
941        assert_eq!(DESERIALIZED_HEADER.size_hint(), SERIALIZED_HEADER.len());
942        assert_eq!(
943            DESERIALIZED_HEADER.serialize(&mut buffer),
944            Ok(SERIALIZED_HEADER.len())
945        );
946        assert_eq!(buffer[..], SERIALIZED_HEADER[..]);
947    }
948
949    #[test]
950    fn header_is_deserializable() {
951        let mut buffer = Bytes::copy_from_slice(&SERIALIZED_HEADER[..]);
952        let header = Header::deserialize(&mut buffer).expect("should deserialize the HEADER");
953        assert_eq!(header, DESERIALIZED_HEADER);
954    }
955}