1use std::time::Duration;
2use tonic::transport::{Channel, Endpoint};
3
4use crate::anytype::ClientCommandsClient;
5use crate::auth::{create_session_token_from_account_key, create_session_token_from_app_key};
6use crate::error::AnytypeGrpcError;
7
8const ANYTYPE_GRPC_ENDPOINT_ENV: &str = "ANYTYPE_GRPC_ENDPOINT";
10const ANYTYPE_GRPC_ENDPOINT: &str = "http://127.0.0.1:31010"; pub fn default_grpc_endpoint() -> String {
14 std::env::var(ANYTYPE_GRPC_ENDPOINT_ENV).unwrap_or_else(|_| ANYTYPE_GRPC_ENDPOINT.to_string())
15}
16
17#[derive(Debug, Clone)]
19pub struct AnytypeGrpcConfig {
20 endpoint: String,
21}
22
23impl Default for AnytypeGrpcConfig {
24 fn default() -> Self {
25 Self {
26 endpoint: default_grpc_endpoint(),
27 }
28 }
29}
30
31impl AnytypeGrpcConfig {
32 pub fn new(endpoint: impl Into<String>) -> Self {
33 Self {
34 endpoint: endpoint.into(),
35 }
36 }
37
38 pub fn endpoint(&self) -> &str {
39 &self.endpoint
40 }
41}
42
43#[derive(Debug, Clone)]
45pub struct AnytypeGrpcClient {
46 channel: Channel,
47 token: String,
48 endpoint: String,
49}
50
51impl AnytypeGrpcClient {
52 pub fn get_endpoint(&self) -> &str {
54 &self.endpoint
55 }
56
57 pub async fn connect_channel(config: &AnytypeGrpcConfig) -> Result<Channel, AnytypeGrpcError> {
58 let endpoint = Endpoint::from_shared(config.endpoint.clone())?
59 .connect_timeout(Duration::from_secs(30))
60 .tcp_keepalive(Some(Duration::from_secs(60)))
61 .http2_keep_alive_interval(Duration::from_secs(30))
62 .keep_alive_timeout(Duration::from_secs(10))
63 .keep_alive_while_idle(true);
64 Ok(endpoint.connect().await?)
65 }
66
67 pub async fn from_account_key(
70 config: &AnytypeGrpcConfig,
71 account_key: impl AsRef<str>,
72 ) -> Result<Self, AnytypeGrpcError> {
73 let channel = Self::connect_channel(config).await?;
74 let token = create_session_token_from_account_key(channel.clone(), account_key).await?;
75 Ok(Self {
76 channel,
77 token,
78 endpoint: config.endpoint.clone(),
79 })
80 }
81
82 pub async fn from_app_key(
84 config: &AnytypeGrpcConfig,
85 app_key: impl AsRef<str>,
86 ) -> Result<Self, AnytypeGrpcError> {
87 let channel = Self::connect_channel(config).await?;
88 let token = create_session_token_from_app_key(channel.clone(), app_key).await?;
89 Ok(Self {
90 channel,
91 token,
92 endpoint: config.endpoint.clone(),
93 })
94 }
95
96 pub async fn from_token(
97 config: &AnytypeGrpcConfig,
98 token: impl Into<String>,
99 ) -> Result<Self, AnytypeGrpcError> {
100 let channel = Self::connect_channel(config).await?;
101 Ok(Self {
102 channel,
103 token: token.into(),
104 endpoint: config.endpoint.clone(),
105 })
106 }
107
108 pub fn client_commands(&self) -> ClientCommandsClient<Channel> {
109 ClientCommandsClient::new(self.channel.clone())
110 }
111
112 pub fn token(&self) -> &str {
113 &self.token
114 }
115
116 pub fn channel(&self) -> Channel {
117 self.channel.clone()
118 }
119}