wireman_core/descriptor/
request.rs1use super::{metadata::Metadata, DynamicMessage};
2use crate::client::codec::DynamicCodec;
3use crate::{
4 error::{Error, FROM_UTF8},
5 Result,
6};
7use http::{uri::PathAndQuery, Uri};
8use prost_reflect::{MessageDescriptor, MethodDescriptor};
9use serde::{ser::SerializeStruct, Serialize, Serializer};
10use std::str::FromStr;
11use tonic::{
12 metadata::{Ascii, MetadataKey, MetadataValue},
13 Request,
14};
15
16#[derive(Debug, Clone)]
19pub struct RequestMessage {
20 message: DynamicMessage,
22 method_desc: MethodDescriptor,
24 metadata: Option<Metadata>,
26 address: String,
28}
29
30impl RequestMessage {
31 #[must_use]
34 pub fn new(message_desc: MessageDescriptor, method_desc: MethodDescriptor) -> Self {
35 let message = DynamicMessage::new(message_desc);
36 Self {
37 message,
38 method_desc,
39 metadata: None,
40 address: String::new(),
41 }
42 }
43
44 #[must_use]
46 pub fn message_name(&self) -> String {
47 self.message_descriptor().name().to_string()
48 }
49
50 #[must_use]
52 pub fn message_descriptor(&self) -> MessageDescriptor {
53 self.message.descriptor()
54 }
55
56 #[must_use]
58 pub fn method_descriptor(&self) -> MethodDescriptor {
59 self.method_desc.clone()
60 }
61
62 #[must_use]
64 pub fn message(&self) -> &DynamicMessage {
65 &self.message
66 }
67
68 #[must_use]
70 pub fn message_mut(&mut self) -> &mut DynamicMessage {
71 &mut self.message
72 }
73
74 pub fn set_message(&mut self, message: DynamicMessage) {
76 self.message = message;
77 }
78
79 #[must_use]
81 pub fn address(&self) -> &str {
82 &self.address
83 }
84
85 pub fn uri(&self) -> Result<Uri> {
90 Uri::try_from(self.address())
91 .map_err(|_| Error::Internal(String::from("Failed to parse address")))
92 }
93
94 pub fn set_address(&mut self, address: &str) {
96 self.address = address.to_string();
97 }
98
99 #[must_use]
101 pub fn metadata(&self) -> &Option<Metadata> {
102 &self.metadata
103 }
104
105 pub fn insert_metadata(&mut self, key: &str, val: &str) -> Result<()> {
111 let key: MetadataKey<Ascii> = key.parse().map_err(|_| Error::ParseToAsciiError)?;
112 let val: MetadataValue<Ascii> = val.parse().map_err(|_| Error::ParseToAsciiError)?;
113 let map = self.metadata.get_or_insert(Metadata::new());
114 map.insert(key, val);
115 Ok(())
116 }
117
118 #[must_use]
124 pub fn path(&self) -> PathAndQuery {
125 let path = format!(
126 "/{}/{}",
127 self.method_desc.parent_service().full_name(),
128 self.method_desc.name()
129 );
130 PathAndQuery::from_str(&path).unwrap()
131 }
132
133 #[must_use]
135 pub fn codec(&self) -> DynamicCodec {
136 DynamicCodec::new(self.method_descriptor())
137 }
138
139 pub fn to_json(&self) -> Result<String> {
145 let mut s = serde_json::Serializer::new(Vec::new());
146 self.serialize(&mut s)
147 .map_err(|_| Error::Internal(String::from("failed to serialize message")))?;
148 String::from_utf8(s.into_inner()).map_err(|_| Error::Internal(FROM_UTF8.to_string()))
149 }
150}
151
152impl From<RequestMessage> for Request<RequestMessage> {
153 fn from(value: RequestMessage) -> Self {
154 let metadata = value.metadata().clone();
155 let mut req = Request::new(value);
156 if let Some(meta) = metadata {
157 *req.metadata_mut() = meta.inner;
158 }
159 req
160 }
161}
162
163impl Serialize for RequestMessage {
164 fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
165 where
166 S: Serializer,
167 {
168 let mut state = serializer.serialize_struct("RequestMessage", 3)?;
169 state.serialize_field("message", &self.message)?;
170 if let Some(metadata) = &self.metadata {
171 state.serialize_field("metadata", &metadata)?;
172 }
173 state.serialize_field("address", &self.address)?;
174 state.end()
175 }
176}
177
178#[cfg(test)]
179mod test {
180 use crate::ProtoDescriptor;
181
182 use super::*;
183
184 fn load_test_message(method: &str) -> RequestMessage {
185 let files = vec!["test_files/test.proto"];
187 let includes = vec!["."];
188
189 let desc = ProtoDescriptor::new(includes, files).unwrap();
191
192 let method = desc
194 .get_method_by_name("proto.TestService", method)
195 .unwrap();
196 let request = method.input();
197 RequestMessage::new(request, method)
198 }
199
200 #[test]
201 fn test_into_request() {
202 let mut given_message = load_test_message("Simple");
204 given_message
205 .insert_metadata("metadata-key", "metadata-value")
206 .unwrap();
207 let method_descriptor = given_message.method_descriptor().clone();
208 let message_descriptor = given_message.message_descriptor().clone();
209
210 let given_req: Request<RequestMessage> = given_message.into();
212
213 let metadata = given_req.metadata();
215 assert!(metadata.contains_key("metadata-key"));
216 assert_eq!(metadata.get("metadata-key").unwrap(), "metadata-value");
217 assert_eq!(given_req.get_ref().method_descriptor(), method_descriptor);
218 assert_eq!(given_req.get_ref().message_descriptor(), message_descriptor);
219 }
220
221 #[test]
222 fn test_to_json() {
223 let mut given_message = load_test_message("Simple");
225 given_message.insert_metadata("key", "value").unwrap();
226 given_message.set_address("localhost:50051");
227
228 let json = given_message.to_json().unwrap();
230
231 let expected_json = "{\"message\":{\"number\":0},\"metadata\":{\"key\":\"value\"},\"address\":\"localhost:50051\"}";
233 assert_eq!(json, expected_json);
234 }
235}