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