wireman_core/features/
grpcurl.rsuse std::collections::HashMap;
use std::fmt::Write;
use http::Uri;
use prost_reflect::MethodDescriptor;
#[allow(clippy::implicit_hasher)]
pub fn grpcurl<T: Into<Uri>>(
includes: &[String],
uri: T,
message: &str,
method_desc: &MethodDescriptor,
metadata: &HashMap<String, String>,
) -> String {
let imports = includes.iter().fold(String::new(), |mut result, include| {
let _ = write!(result, "-import-path {include} ");
result
});
let file_desc = method_desc.parent_file();
let proto = file_desc.file_descriptor_proto().name();
let uri = uri.into();
let host = uri.host().unwrap_or("");
let port = uri.port_u16().unwrap_or(80);
let method = method_desc.full_name();
let metadata = metadata
.iter()
.fold(String::new(), |mut result, (key, val)| {
let _ = write!(result, " -H \"{key}: {val}\"");
result
});
format!(
"grpcurl -d @ {imports}-proto {proto}{metadata} -plaintext {host}:{port} {method} <<EOM\n{message}\nEOM"
)
}
#[cfg(test)]
mod test {
use crate::descriptor::RequestMessage;
use crate::ProtoDescriptor;
use super::*;
#[test]
fn test_request_as_grpcurl() {
let includes = vec!["/Users/myworkspace".to_string()];
let given_uri = Uri::from_static("http://localhost:50051");
let test_message = load_test_message("Simple");
let given_method = test_message.method_descriptor();
let given_message = "{\n \"number\": 0\n}";
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";
let cmd = grpcurl(
&includes,
given_uri,
given_message,
&given_method,
&HashMap::new(),
);
assert_eq!(cmd, expected);
}
fn load_test_message(method: &str) -> RequestMessage {
let files = vec!["test_files/test.proto"];
let includes = vec!["."];
let desc = ProtoDescriptor::new(includes, files).unwrap();
let method = desc
.get_method_by_name("proto.TestService", method)
.unwrap();
let request = method.input();
RequestMessage::new(request, method)
}
}