wireman_core/features/
grpcurl.rs1use std::collections::HashMap;
2use std::fmt::Write;
3
4use http::Uri;
5use prost_reflect::MethodDescriptor;
6
7#[allow(clippy::implicit_hasher)]
21pub fn grpcurl<T: Into<Uri>>(
22 includes: &[String],
23 uri: T,
24 message: &str,
25 method_desc: &MethodDescriptor,
26 metadata: &HashMap<String, String>,
27) -> String {
28 let imports = includes.iter().fold(String::new(), |mut result, include| {
30 let _ = write!(result, "-import-path {include} ");
31 result
32 });
33
34 let file_desc = method_desc.parent_file();
36 let proto = file_desc.file_descriptor_proto().name();
37
38 let uri = uri.into();
40 let host = uri.host().unwrap_or("");
41 let port = uri.port_u16().unwrap_or(80);
42
43 let method = method_desc.full_name();
45
46 let metadata = metadata
48 .iter()
49 .fold(String::new(), |mut result, (key, val)| {
50 let _ = write!(result, " -H \"{key}: {val}\"");
51 result
52 });
53
54 format!(
55 "grpcurl -d @ {imports}-proto {proto}{metadata} -plaintext {host}:{port} {method} <<EOM\n{message}\nEOM"
56 )
57}
58
59#[cfg(test)]
60mod test {
61 use crate::descriptor::RequestMessage;
62 use crate::ProtoDescriptor;
63
64 use super::*;
65
66 #[test]
67 fn test_request_as_grpcurl() {
68 let includes = vec!["/Users/myworkspace".to_string()];
70 let given_uri = Uri::from_static("http://localhost:50051");
71 let test_message = load_test_message("Simple");
72 let given_method = test_message.method_descriptor();
73 let given_message = "{\n \"number\": 0\n}";
74 let expected = "grpcurl -d @ -import-path /Users/myworkspace -proto test_files/test.proto -plaintext localhost:50051 proto.TestService.Simple <<EOM\n{\n \"number\": 0\n}\nEOM";
75
76 let cmd = grpcurl(
78 &includes,
79 given_uri,
80 given_message,
81 &given_method,
82 &HashMap::new(),
83 );
84
85 assert_eq!(cmd, expected);
87 }
88
89 fn load_test_message(method: &str) -> RequestMessage {
90 let files = vec!["test_files/test.proto"];
91 let includes = vec!["."];
92
93 let desc = ProtoDescriptor::new(includes, files).unwrap();
94
95 let method = desc
96 .get_method_by_name("proto.TestService", method)
97 .unwrap();
98 let request = method.input();
99 RequestMessage::new(request, method)
100 }
101}