1mod api_keys;
19mod branches;
20mod change;
21mod commits;
22mod content;
23mod org;
24mod repo;
25mod repos;
26mod webhooks;
27
28mod pagination;
29
30pub use api_keys::ApiKeysClient;
31pub use branches::BranchesClient;
32pub use change::ChangeClient;
33pub use commits::CommitsClient;
34pub use content::ContentClient;
35pub use org::OrgClient;
36pub use repo::RepoClient;
37pub use repos::ReposClient;
38pub use webhooks::WebhooksClient;
39
40use crate::low_level::apis::configuration::Configuration;
41
42pub const DEFAULT_GRPC_ENDPOINT: &str = "https://vcs.depot.mesa.dev";
44
45#[derive(Debug)]
47pub enum BuildError {
48 InvalidGrpcEndpoint(tonic::codegen::http::uri::InvalidUri),
50 TlsConfig(tonic::transport::Error),
52}
53
54impl std::fmt::Display for BuildError {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 match self {
57 Self::InvalidGrpcEndpoint(e) => write!(f, "invalid gRPC endpoint: {e}"),
58 Self::TlsConfig(e) => write!(f, "gRPC TLS configuration failed: {e}"),
59 }
60 }
61}
62
63impl std::error::Error for BuildError {
64 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
65 match self {
66 Self::InvalidGrpcEndpoint(e) => Some(e),
67 Self::TlsConfig(e) => Some(e),
68 }
69 }
70}
71
72#[derive(Clone, Debug, Default)]
74pub struct MesaClientBuilder {
75 base_path: Option<String>,
76 user_agent: Option<String>,
77 client: Option<reqwest_middleware::ClientWithMiddleware>,
78 api_key: Option<String>,
79 grpc_endpoint: Option<String>,
80}
81
82impl MesaClientBuilder {
83 #[must_use]
85 pub fn with_base_path(mut self, base_path: impl Into<String>) -> Self {
86 self.base_path = Some(base_path.into());
87 self
88 }
89
90 #[must_use]
92 pub fn with_user_agent(mut self, user_agent: impl Into<String>) -> Self {
93 self.user_agent = Some(user_agent.into());
94 self
95 }
96
97 #[must_use]
99 pub fn with_client(mut self, client: reqwest_middleware::ClientWithMiddleware) -> Self {
100 self.client = Some(client);
101 self
102 }
103
104 #[must_use]
106 pub fn with_api_key(mut self, api_key: impl Into<String>) -> Self {
107 self.api_key = Some(api_key.into());
108 self
109 }
110
111 #[must_use]
115 pub fn with_grpc_endpoint(mut self, endpoint: impl Into<String>) -> Self {
116 self.grpc_endpoint = Some(endpoint.into());
117 self
118 }
119
120 pub fn build(self) -> Result<MesaClient, BuildError> {
126 let mut config = Configuration::default();
127
128 if let Some(base_path) = self.base_path {
129 config.base_path = base_path;
130 }
131
132 config.user_agent = self.user_agent.clone().or(Some(Self::default_user_agent()));
133 if let Some(client) = self.client {
134 config.client = client;
135 }
136
137 if let Some(api_key) = self.api_key {
138 config.bearer_access_token = Some(api_key);
139 }
140
141 let endpoint_str = self
142 .grpc_endpoint
143 .unwrap_or_else(|| DEFAULT_GRPC_ENDPOINT.to_owned());
144 let mut endpoint = tonic::transport::Channel::from_shared(endpoint_str)
145 .map_err(BuildError::InvalidGrpcEndpoint)?
146 .http2_adaptive_window(true);
147
148 if endpoint
150 .uri()
151 .scheme_str()
152 .is_some_and(|s| s.eq_ignore_ascii_case("https"))
153 {
154 endpoint = endpoint
155 .tls_config(
156 tonic::transport::ClientTlsConfig::new()
157 .with_native_roots()
158 .with_enabled_roots(),
159 )
160 .map_err(BuildError::TlsConfig)?;
161 }
162
163 let grpc_channel = endpoint.connect_lazy();
164
165 Ok(MesaClient {
166 config,
167 grpc_channel,
168 })
169 }
170
171 fn default_user_agent() -> String {
172 format!(
173 "mesa-dev/{} (rust/{})",
174 env!("CARGO_PKG_VERSION"),
175 env!("MESA_RUSTC_VERSION"),
176 )
177 }
178}
179
180#[derive(Clone, Debug)]
185pub struct MesaClient {
186 pub(crate) config: Configuration,
187 pub(crate) grpc_channel: tonic::transport::Channel,
188}
189
190impl MesaClient {
191 #[must_use]
193 pub fn builder() -> MesaClientBuilder {
194 MesaClientBuilder::default()
195 }
196
197 #[must_use]
199 pub fn from_configuration(
200 config: Configuration,
201 grpc_channel: tonic::transport::Channel,
202 ) -> Self {
203 Self {
204 config,
205 grpc_channel,
206 }
207 }
208
209 #[must_use]
211 pub fn org<'a>(&'a self, name: &'a str) -> OrgClient<'a> {
212 OrgClient {
213 client: self,
214 org: name,
215 }
216 }
217}