use std::{cell::RefCell, collections::HashMap, rc::Rc}; use async_trait::async_trait; use tracing::{error, instrument, trace}; use super::{ common::PresenceState, messaging_interface::{ AccountMessagingConsumerInterface, AccountMessagingProviderInterface, RoomMessagingConsumerInterface, SpaceMessagingConsumerInterface, }, room::{Room, RoomId}, space::{Space, SpaceId}, store_interface::{ AccountStoreProviderInterface, RoomStoreConsumerInterface, SpaceStoreConsumerInterface, }, }; type Rooms = HashMap>; type Spaces = HashMap>; pub struct Account { display_name: RefCell>, avatar: RefCell>>, #[allow(dead_code)] presence_state: RefCell>, by_id_rooms: RefCell, by_id_spaces: RefCell, messaging_provider: Option>, store: &'static dyn AccountStoreProviderInterface, } impl Account { pub fn new(store: &'static dyn AccountStoreProviderInterface) -> Self { Self { display_name: RefCell::new(None), avatar: RefCell::new(None), presence_state: RefCell::new(None), by_id_rooms: RefCell::new(Rooms::new()), by_id_spaces: RefCell::new(Spaces::new()), messaging_provider: None, store, } } pub fn set_messaging_provider(&mut self, provider: Rc) { self.messaging_provider = Some(provider.clone()); } #[allow(dead_code)] pub fn get_room(&self, room_id: &RoomId) -> Option> { self.by_id_rooms.borrow().get(room_id).cloned() } pub async fn get_display_name(&self) -> &RefCell> { if self.display_name.borrow().is_none() { if let Some(requester) = &self.messaging_provider { let resp = requester.get_display_name().await; if let Ok(display_name) = resp { if let Some(display_name) = display_name { self.display_name.borrow_mut().replace(display_name); } else { self.display_name.borrow_mut().take(); } } else { error!("err={:?}", resp); } } } &self.display_name } pub async fn get_avatar(&self) -> &RefCell>> { if self.avatar.borrow().is_none() { if let Some(requester) = &self.messaging_provider { let resp = requester.get_avatar().await; if let Ok(avatar) = resp { if let Some(avatar) = avatar { self.avatar.borrow_mut().replace(avatar); } else { self.avatar.borrow_mut().take(); } } else { error!("err={:?}", resp); } } } &self.avatar } } #[async_trait(?Send)] impl AccountMessagingConsumerInterface for Account { #[instrument(name = "Account", skip_all)] async fn on_new_room(&self, room: Rc) -> Rc { trace!("on_new_room"); let room_id = room.id().clone(); self.by_id_rooms .borrow_mut() .insert(room_id, Rc::clone(&room)); let room_store = self .store .on_new_room(Rc::clone(&room) as Rc); room.set_store(room_store); room } #[instrument(name = "Account", skip_all)] async fn on_new_space(&self, space: Rc) -> Rc { trace!("on_new_space"); let space_id = space.id().clone(); self.by_id_spaces .borrow_mut() .insert(space_id, Rc::clone(&space)); let space_store = self .store .on_new_space(Rc::clone(&space) as Rc); space.set_store(space_store); space } }