volt_client_grpc/
grpc_utils.rs1use crate::credential::VoltCredential;
4use crate::error::{Result, VoltError};
5use tonic::transport::{Certificate, Channel, ClientTlsConfig, Identity};
6
7pub async fn create_channel(
9 address: &str,
10 credential: &VoltCredential,
11 relaying: bool,
12) -> Result<Channel> {
13 let endpoint = format!("https://{}", address);
14
15 let ca_pem = if relaying {
17 credential
18 .config()
19 .volt
20 .relay
21 .as_ref()
22 .and_then(|r| r.ca_pem.as_deref())
23 } else {
24 credential
25 .cache()
26 .and_then(|c| c.ca.as_deref())
27 .or_else(|| credential.config().volt.ca_pem.as_deref())
28 };
29
30 let ca_pem =
31 ca_pem.ok_or_else(|| VoltError::CertificateError("No CA certificate available".into()))?;
32
33 let ca = Certificate::from_pem(ca_pem);
34
35 let mut tls_config = ClientTlsConfig::new().ca_certificate(ca);
37
38 if !relaying {
40 if let Some(cache) = credential.cache() {
41 if let (Some(cert), Some(key)) = (cache.cert.as_ref(), cache.key.as_ref()) {
42 let identity = Identity::from_pem(cert, key);
43 tls_config = tls_config.identity(identity);
44 }
45 }
46 }
47
48 Channel::from_shared(endpoint)
50 .map_err(|e| VoltError::ConnectionError(e.to_string()))?
51 .tls_config(tls_config)
52 .map_err(VoltError::TransportError)?
53 .connect()
54 .await
55 .map_err(VoltError::from)
56}
57
58#[derive(Debug, Clone, Default)]
60pub struct CallOptions {
61 pub timeout_ms: Option<u64>,
63 pub wait_for_ready: bool,
65}
66
67impl CallOptions {
68 pub fn with_timeout(mut self, timeout_ms: u64) -> Self {
69 self.timeout_ms = Some(timeout_ms);
70 self
71 }
72
73 pub fn with_wait_for_ready(mut self) -> Self {
74 self.wait_for_ready = true;
75 self
76 }
77}