1use crate::{NanoRosError, types::RosService};
7
8pub struct ServiceServer<S: RosService> {
12 pub name: &'static str,
14 _marker: core::marker::PhantomData<S>,
16}
17
18impl<S: RosService> ServiceServer<S> {
19 pub fn new(name: &'static str) -> Self {
21 Self {
22 name,
23 _marker: core::marker::PhantomData,
24 }
25 }
26
27 pub fn name(&self) -> &str {
29 self.name
30 }
31
32 pub fn service_type(&self) -> &'static str {
34 S::SERVICE_NAME
35 }
36
37 pub fn service_hash(&self) -> &'static str {
39 S::SERVICE_HASH
40 }
41}
42
43pub struct ServiceClient<S: RosService> {
47 pub name: &'static str,
49 _marker: core::marker::PhantomData<S>,
51}
52
53impl<S: RosService> ServiceClient<S> {
54 pub fn new(name: &'static str) -> Self {
56 Self {
57 name,
58 _marker: core::marker::PhantomData,
59 }
60 }
61
62 pub fn name(&self) -> &str {
64 self.name
65 }
66
67 pub fn service_type(&self) -> &'static str {
69 S::SERVICE_NAME
70 }
71
72 pub fn service_hash(&self) -> &'static str {
74 S::SERVICE_HASH
75 }
76}
77
78pub struct ServiceRequest<'a, S: RosService> {
82 pub request: S::Request,
84 pub raw_data: &'a [u8],
86}
87
88pub type ServiceResult<T> = Result<T, NanoRosError>;
92
93pub type ServiceCallback<S> = fn(&<S as RosService>::Request) -> <S as RosService>::Reply;
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 struct MockService;
105
106 #[derive(Debug, Clone)]
109 struct MockRequest {
110 #[allow(dead_code)]
111 pub a: i32,
112 #[allow(dead_code)]
113 pub b: i32,
114 }
115
116 #[derive(Debug, Clone)]
117 struct MockReply {
118 #[allow(dead_code)]
119 pub sum: i32,
120 }
121
122 impl nros_serdes::Serialize for MockRequest {
124 fn serialize(
125 &self,
126 _writer: &mut nros_serdes::CdrWriter,
127 ) -> Result<(), nros_serdes::SerError> {
128 Ok(())
129 }
130 }
131
132 impl nros_serdes::Deserialize for MockRequest {
133 fn deserialize(
134 _reader: &mut nros_serdes::CdrReader,
135 ) -> Result<Self, nros_serdes::DeserError> {
136 Ok(MockRequest { a: 0, b: 0 })
137 }
138 }
139
140 impl crate::RosMessage for MockRequest {
141 const TYPE_NAME: &'static str = "test_msgs::srv::dds_::AddTwoInts_Request_";
142 const TYPE_HASH: &'static str =
143 "0000000000000000000000000000000000000000000000000000000000000000";
144 }
145
146 impl nros_serdes::Serialize for MockReply {
147 fn serialize(
148 &self,
149 _writer: &mut nros_serdes::CdrWriter,
150 ) -> Result<(), nros_serdes::SerError> {
151 Ok(())
152 }
153 }
154
155 impl nros_serdes::Deserialize for MockReply {
156 fn deserialize(
157 _reader: &mut nros_serdes::CdrReader,
158 ) -> Result<Self, nros_serdes::DeserError> {
159 Ok(MockReply { sum: 0 })
160 }
161 }
162
163 impl crate::RosMessage for MockReply {
164 const TYPE_NAME: &'static str = "test_msgs::srv::dds_::AddTwoInts_Reply_";
165 const TYPE_HASH: &'static str =
166 "0000000000000000000000000000000000000000000000000000000000000000";
167 }
168
169 impl RosService for MockService {
170 type Request = MockRequest;
171 type Reply = MockReply;
172 const SERVICE_NAME: &'static str = "test_msgs::srv::dds_::AddTwoInts_";
173 const SERVICE_HASH: &'static str =
174 "0000000000000000000000000000000000000000000000000000000000000000";
175 }
176
177 #[test]
178 fn test_service_server_creation() {
179 let server = ServiceServer::<MockService>::new("/add_two_ints");
180 assert_eq!(server.name(), "/add_two_ints");
181 assert_eq!(server.service_type(), "test_msgs::srv::dds_::AddTwoInts_");
182 }
183
184 #[test]
185 fn test_service_client_creation() {
186 let client = ServiceClient::<MockService>::new("/add_two_ints");
187 assert_eq!(client.name(), "/add_two_ints");
188 assert_eq!(client.service_type(), "test_msgs::srv::dds_::AddTwoInts_");
189 }
190}