rseip_cip/
message.rs

1// rseip
2//
3// rseip - Ethernet/IP (CIP) in pure Rust.
4// Copyright: 2021, Joylei <leingliu@gmail.com>
5// License: MIT
6
7use super::Status;
8use crate::error::cip_error_reply;
9use rseip_core::{codec::Encode, Error};
10
11/// Message request
12#[derive(Debug, Default, PartialEq, Eq)]
13pub struct MessageRequest<P, D> {
14    /// service request code
15    pub service_code: u8,
16    /// service request path
17    pub path: P,
18    /// service request data
19    pub data: D,
20}
21
22impl<P, D> MessageRequest<P, D>
23where
24    P: Encode,
25    D: Encode,
26{
27    #[inline]
28    pub fn new(service_code: u8, path: P, data: D) -> Self {
29        Self {
30            service_code,
31            path,
32            data,
33        }
34    }
35}
36
37/// message reply
38#[derive(Debug)]
39pub struct MessageReply<D> {
40    /// reply service code
41    pub reply_service: u8,
42    /// general status and extended status
43    pub status: Status,
44    /// only present with routing type errors
45    pub remaining_path_size: Option<u8>,
46    pub data: D,
47}
48
49impl<D> MessageReply<D> {
50    #[inline]
51    pub fn new(reply_service: u8, status: Status, data: D) -> Self {
52        Self {
53            reply_service,
54            status,
55            remaining_path_size: None,
56            data,
57        }
58    }
59}
60
61impl<D> MessageReplyInterface for MessageReply<D> {
62    type Value = D;
63
64    #[inline]
65    fn reply_service(&self) -> u8 {
66        self.reply_service
67    }
68
69    #[inline]
70    fn status(&self) -> &Status {
71        &self.status
72    }
73
74    #[inline]
75    fn value(&self) -> &Self::Value {
76        &self.data
77    }
78
79    #[inline]
80    fn into_value(self) -> Self::Value {
81        self.data
82    }
83}
84
85/// CIP message reply abstraction
86pub trait MessageReplyInterface {
87    type Value;
88
89    fn reply_service(&self) -> u8;
90
91    fn status(&self) -> &Status;
92
93    fn value(&self) -> &Self::Value;
94
95    fn into_value(self) -> Self::Value;
96
97    #[inline]
98    fn expect_service<E: Error>(&self, expected_service: u8) -> Result<(), E> {
99        if self.reply_service() != expected_service {
100            Err(cip_error_reply(self.reply_service(), expected_service))
101        } else {
102            Ok(())
103        }
104    }
105}