use crate::client::AccessTokenCache;
use crate::handlers::{
CallbackHandler, DefaultLifecycleListener, EventHandler, LifecycleListener, SystemHandler,
};
use crate::{ClientConfig, Credential};
use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use tokio::sync::RwLock;
mod access_token;
mod download_resources;
mod upload_resources;
pub use upload_resources::*;
mod handle_message;
mod lifecycle;
mod send_message;
use crate::frames::down_message::MessageTopic;
pub use download_resources::DingtalkResource;
pub struct DingTalkStream {
pub(super) credential: Credential,
config: ClientConfig,
event_handler: Option<Arc<dyn EventHandler>>,
callback_handlers: HashMap<MessageTopic, Arc<dyn CallbackHandler>>,
system_handler: Option<Arc<dyn SystemHandler>>,
connected: AtomicBool,
registered: AtomicBool,
access_token: Arc<RwLock<Option<AccessTokenCache>>>,
http_client: reqwest::Client,
lifecycle_listener: Arc<dyn LifecycleListener>,
}
impl DingTalkStream {
pub fn new(credential: Credential) -> Self {
Self::with_config(credential, ClientConfig::default())
}
pub fn with_config(credential: Credential, config: ClientConfig) -> Self {
Self {
credential,
config,
event_handler: None,
callback_handlers: HashMap::default(),
system_handler: None,
connected: AtomicBool::new(false),
registered: AtomicBool::new(false),
access_token: Default::default(),
http_client: reqwest::Client::default(),
lifecycle_listener: Arc::new(DefaultLifecycleListener::default()),
}
}
}
impl DingTalkStream {
pub async fn register_event_handler<H: EventHandler + 'static>(
mut self,
handler: Arc<H>,
) -> Self {
self.event_handler.replace(handler);
self
}
pub async fn register_callback_handler<H: CallbackHandler + 'static>(
mut self,
handler: Arc<H>,
) -> Self {
let topic = handler.topic().clone();
self.callback_handlers.insert(topic, handler);
self
}
pub async fn register_system_handler<H: SystemHandler + 'static>(
mut self,
handler: Arc<H>,
) -> Self {
self.system_handler.replace(handler);
self
}
pub async fn register_lifecycle_listener<L: LifecycleListener + 'static>(
mut self,
listener: Arc<L>,
) -> Self {
self.lifecycle_listener = listener;
self
}
}
impl DingTalkStream {
pub fn is_connected(&self) -> bool {
self.connected.load(Ordering::Relaxed)
}
pub fn is_registered(&self) -> bool {
self.registered.load(Ordering::Relaxed)
}
pub fn credential(&self) -> &Credential {
&self.credential
}
pub fn config(&self) -> &ClientConfig {
&self.config
}
}