botx_api/api/
context.rs

1use std::{env, sync::Arc};
2
3use reqwest::Client;
4
5#[cfg(feature = "anthill-di")]
6use anthill_di::{Constructor, DependencyContext, types::BuildDependencyResult};
7
8use crate::api::utils::url::ApiEndpoints;
9
10pub struct BotXApiContext {
11    pub cts_url: String,
12    pub bot_id: String,
13    pub secret_key: String,
14    pub client: Client,
15    pub api: ApiEndpoints,
16    pub auth_token: Option<String>,
17}
18
19/// При интеграции с anthill-di позволяет переопределить настройки бота (по умолчанию берется информация из переменных среды) <br/>
20/// Чтобы переопределить, зарегистрируйте фабрику на основе замыкания с настройкой необходимой конфигурации
21/// ```rs
22/// ioc.register_closure(|| Ok(BotXApiContextConfiguration { cts_url: "http:xxxx.ru", ... }), LifeTime::Transient).await.unwrap();
23/// ```
24
25pub struct BotXApiContextConfiguration {
26    pub cts_url: String,
27    pub bot_id: String,
28    pub secret_key: String,
29}
30
31impl BotXApiContextConfiguration {
32    pub const DEFAULT_CTS_URL_ENV: &str = "BOTX_API_CTS_URL";
33    pub const DEFAULT_BOT_ID_ENV: &str = "BOTX_API_BOT_ID";
34    pub const DEFAULT_BOT_SECRET_KEY_ENV: &str = "BOTX_API_BOT_SECRET_KEY";
35}
36
37impl Default for BotXApiContextConfiguration {
38    fn default() -> Self {
39        let cts_url = env::var(Self::DEFAULT_CTS_URL_ENV)
40            .expect(&*format!("Env {} not found", Self::DEFAULT_CTS_URL_ENV));
41
42        let bot_id = env::var(Self::DEFAULT_BOT_ID_ENV)
43            .expect(&*format!("Env {} not found", Self::DEFAULT_BOT_ID_ENV));
44
45        let secret_key = env::var(Self::DEFAULT_BOT_SECRET_KEY_ENV)
46            .expect(&*format!("Env {} not found", Self::DEFAULT_BOT_SECRET_KEY_ENV));
47
48        Self { cts_url, bot_id, secret_key }
49    }
50}
51
52#[cfg(feature = "anthill-di")]
53#[async_trait_with_sync::async_trait(Sync)]
54impl Constructor for BotXApiContext {
55    async fn ctor(ctx: DependencyContext) -> BuildDependencyResult<Self> {
56        let configuration = ctx.resolve::<Arc<BotXApiContextConfiguration>>().await.unwrap_or(Arc::new(BotXApiContextConfiguration::default()));
57        
58        Ok(Self {
59            cts_url: configuration.cts_url.clone().into(),
60            bot_id: configuration.bot_id.clone().into(),
61            secret_key: configuration.secret_key.clone().into(),
62            client: ctx.resolve().await.unwrap_or_default(),
63            api: ctx.resolve().await.unwrap_or_default(),
64            auth_token: None,
65        })
66    }
67}
68
69impl BotXApiContext {
70    
71
72    pub fn new(cts_url: impl Into<String>, bot_id: impl Into<String>, secret_key: impl Into<String>) -> Self {
73        Self::from_client(cts_url, bot_id, secret_key, Default::default())
74    }
75
76    pub fn from_client(cts_url: impl Into<String>, bot_id: impl Into<String>, secret_key: impl Into<String>, client: Client) -> Self {
77        Self {
78            cts_url: cts_url.into(),
79            bot_id: bot_id.into(),
80            secret_key: secret_key.into(),
81            client,
82            api: ApiEndpoints::new(),
83            auth_token: None,
84        }
85    }
86
87    pub fn from_env_with_default_client() -> Self {
88        Self::from_env(Default::default())
89    }
90
91    pub fn from_env(client: Client) -> Self {
92        let BotXApiContextConfiguration{ cts_url, bot_id, secret_key } = BotXApiContextConfiguration::default();
93
94        Self {
95            cts_url: cts_url.into(),
96            bot_id: bot_id.into(),
97            secret_key: secret_key.into(),
98            client,
99            api: ApiEndpoints::new(),
100            auth_token: None,
101        }
102    }
103
104    pub fn cts_url(&self) -> &str {
105        self.cts_url.as_ref()
106    }
107
108    pub fn bot_id(&self) -> &str {
109        self.bot_id.as_ref()
110    }
111
112    pub fn secret_key(&self) -> &str {
113        self.secret_key.as_ref()
114    }
115}