alien_bindings/providers/container/
grpc.rs1use crate::error::{ErrorData, Result};
6use crate::traits::{Binding, Container};
7use alien_error::{Context as _, IntoAlienError as _};
8use async_trait::async_trait;
9use std::fmt::{Debug, Formatter};
10use tonic::transport::Channel;
11
12pub mod proto {
14 tonic::include_proto!("alien_bindings.container");
15}
16
17use proto::{
18 container_service_client::ContainerServiceClient, GetContainerNameRequest,
19 GetInternalUrlRequest, GetPublicUrlRequest,
20};
21
22pub struct GrpcContainer {
24 client: ContainerServiceClient<Channel>,
25 binding_name: String,
26 internal_url: String,
28 public_url: Option<String>,
29 container_name: String,
30}
31
32impl Debug for GrpcContainer {
33 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
34 f.debug_struct("GrpcContainer")
35 .field("binding_name", &self.binding_name)
36 .finish()
37 }
38}
39
40impl GrpcContainer {
41 pub async fn new(binding_name: String, grpc_endpoint: String) -> Result<Self> {
43 let channel = crate::providers::grpc_provider::create_grpc_channel(grpc_endpoint).await?;
44 Self::new_from_channel(channel, binding_name).await
45 }
46
47 pub async fn new_from_channel(channel: Channel, binding_name: String) -> Result<Self> {
49 let mut client = ContainerServiceClient::new(channel);
50
51 let internal_url = {
53 let request = tonic::Request::new(GetInternalUrlRequest {
54 binding_name: binding_name.clone(),
55 });
56 client
57 .get_internal_url(request)
58 .await
59 .into_alien_error()
60 .context(ErrorData::GrpcRequestFailed {
61 service: "ContainerService".to_string(),
62 method: "get_internal_url".to_string(),
63 details: "Failed to get internal URL".to_string(),
64 })?
65 .into_inner()
66 .url
67 };
68
69 let public_url = {
70 let request = tonic::Request::new(GetPublicUrlRequest {
71 binding_name: binding_name.clone(),
72 });
73 client
74 .get_public_url(request)
75 .await
76 .into_alien_error()
77 .context(ErrorData::GrpcRequestFailed {
78 service: "ContainerService".to_string(),
79 method: "get_public_url".to_string(),
80 details: "Failed to get public URL".to_string(),
81 })?
82 .into_inner()
83 .url
84 };
85
86 let container_name = {
87 let request = tonic::Request::new(GetContainerNameRequest {
88 binding_name: binding_name.clone(),
89 });
90 client
91 .get_container_name(request)
92 .await
93 .into_alien_error()
94 .context(ErrorData::GrpcRequestFailed {
95 service: "ContainerService".to_string(),
96 method: "get_container_name".to_string(),
97 details: "Failed to get container name".to_string(),
98 })?
99 .into_inner()
100 .name
101 };
102
103 Ok(Self {
104 client,
105 binding_name,
106 internal_url,
107 public_url,
108 container_name,
109 })
110 }
111}
112
113impl Binding for GrpcContainer {}
114
115#[async_trait]
116impl Container for GrpcContainer {
117 fn get_internal_url(&self) -> &str {
118 &self.internal_url
119 }
120
121 fn get_public_url(&self) -> Option<&str> {
122 self.public_url.as_deref()
123 }
124
125 fn get_container_name(&self) -> &str {
126 &self.container_name
127 }
128
129 fn as_any(&self) -> &dyn std::any::Any {
130 self
131 }
132}