// pub struct State<'a> { // // open_chat: Option>, // chats: Vec>, // roster: Vec>, // } // impl Macaw { // pub fn state(&self) -> State { // let chats = self // .chats // .iter() // .map(|(_, chat)| { // let user = chat.user.as_ref().borrow(); // let contact = self.roster.get(&user.inner.jid); // let latest_message = match &chat.message { // Some(the_message) => { // let message: Ref<'_, OwnedMessage> = the_message.as_ref().borrow(); // let user = { // let user = message.user.as_ref().borrow(); // let contact = self.roster.get(&user.inner.jid); // BorrowedUser { // inner: user, // contact, // } // }; // Some(BorrowedMessage { // inner: message, // user, // }) // } // None => None, // }; // BorrowedChat { // inner: &chat, // user: BorrowedUser { // inner: user, // contact, // }, // latest_message, // } // }) // .collect(); // State { // // open_chat: todo!(), // chats, // roster: todo!(), // } // } // } // pub enum Node<'a> { // User(BorrowedUser<'a>), // Message(BorrowedMessage<'a>), // Contact(BorrowedContact<'a>), // Chat(BorrowedChat<'a>), // OpenChat(OpenChat<'a>), // } // pub enum Orphan { // User(JID), // Message(Uuid), // } // pub struct BorrowedUser<'a> { // inner: Ref<'a, OwnedUser>, // // inner: &'a OwnedUser, // contact: Option<&'a OwnedContact>, // } // pub struct BorrowedMessage<'a> { // inner: Ref<'a, OwnedMessage>, // // user: Rc>, // user: BorrowedUser<'a>, // } // pub struct BorrowedContact<'a> { // inner: &'a OwnedContact, // user: BorrowedUser<'a>, // } // pub struct BorrowedChat<'a> { // inner: &'a OwnedChat, // // user: Rc>, // user: BorrowedUser<'a>, // // latest_message: Option>>, // latest_message: Option>, // } // pub struct OpenChat<'a> { // chat: BorrowedChat<'a>, // messages: Vec>, // } // there are two states: an editing state and a reading state. // because the state is self-referential, each time there is a change, the state needs to be recalculated. // pub struct State<'a> { // // open_chat: Option>, // chats: Vec>, // roster: Vec>, // } // pub struct AState { // open_chat: Option, // chats: HashMap), Option)>, // roster: HashMap, // } // pub struct OwnedOpenChat { // chat: (Chat, (User, Option)), // messages: IndexMap))>, // } // pub struct MacawUser { // inner: User, // contact: Option, // } // impl Deref for MacawUser { // } // other option is forget about all this bullshit and just build the relations graph again after each update? // impl Macaw { // pub async fn insert_contact( // &mut self, // contact: Contact, // ) -> Result<(), CommandError> { // let user_jid = contact.user_jid.clone(); // if !self.users.contains_key(&user_jid) { // // TODO: all methods only on logged-in client // match &self.client { // Account::LoggedIn(client) => { // let user = client.get_user(user_jid.clone()).await?; // self.users.insert(user_jid, user); // } // Account::LoggedOut(login_modal) => todo!(), // } // } else { // // up the dependency count // } // self.roster.insert(contact.user_jid.clone(), contact); // Ok(()) // } // pub fn get_contact(&self, jid: &JID) -> Option<(&Contact, &User)> {} // pub fn get_contact_mut(&mut self, jid: &JID) -> Option<&mut Contact> {} // pub fn remove_contact(&mut self, jid: JID) -> Option { // self.roster. // } // // updating is fine to do directly on any part of the store. // // if a contact is retrieved, it is guaranteed that there is a user in the store, because when the contact was inserted, a user was added to the user store, and the userstore is a droppable store that does not allow you to remove items if there are other things depending on it. // } // pub struct MacawContact<'a> { // inner: Contact, // user: &'a User, // } // messages must be tombstoned because of this // items are never directly added to or removed from a droppablestore // remove can only be called from a store that called insert // if a store calls insert it must call remove if something is removed from that store pub struct DroppableStore(HashMap); impl DroppableStore { pub fn capacity(&self) -> usize { self.0.capacity() } pub fn contains_key(&self, k: &Q) -> bool where Q: std::hash::Hash + Eq, K: Borrow + std::hash::Hash + Eq, { self.0.contains_key(k) } pub fn get(&self, k: &Q) -> Option<&V> where Q: std::hash::Hash + Eq, K: Borrow + std::hash::Hash + Eq, { self.0.get(k).map(|(_, v)| v) } pub fn get_key_value(&self, k: &Q) -> Option<(&K, &V)> where Q: std::hash::Hash + Eq + ?Sized, K: Borrow + std::hash::Hash + Eq, { self.0.get_key_value(k).map(|(k, (_, v))| (k, v)) } pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> where Q: std::hash::Hash + Eq + ?Sized, K: Borrow + std::hash::Hash + Eq, { self.0.get_mut(k).map(|(_, v)| v) } pub fn insert(&mut self, k: K, v: V) -> Option where K: std::hash::Hash + Eq, { if let Some((count, old_v)) = self.0.get_mut(&k) { *count += 1; let output = std::mem::replace(old_v, v); Some(output) } else { self.0.insert(k, (1, v)); None } } pub fn is_empty(&self) -> bool { self.0.is_empty() } pub fn iter(&self) -> impl Iterator { self.0.iter().map(|(k, (_, v))| (k, v)) } pub fn iter_mut(&mut self) -> impl Iterator { self.0.iter_mut().map(|(k, (_, v))| (k, v)) } pub fn keys(&self) -> impl Iterator { self.0.keys() } pub fn len(&self) -> usize { self.0.len() } pub fn new() -> Self { Self(HashMap::new()) } pub fn remove(&mut self, k: &Q) -> Option where K: Borrow + std::hash::Hash + Eq, Q: std::hash::Hash + Eq + ?Sized, { if let Some((count, old_v)) = self.0.get_mut(&k) { if *count == 1 { self.0.remove(&k).map(|(_, v)| v) } else { *count = *count - 1; Some(old_v.clone()) } } else { None } } pub fn remove_entry(&mut self, k: &K) -> Option<(K, V)> where K: std::hash::Hash + Eq, { if let Some((count, old_v)) = self.0.get_mut(&k) { if *count == 1 { self.0.remove_entry(&k).map(|(k, (_, v))| (k, v)) } else { *count = *count - 1; Some((k.clone(), old_v.clone())) } } else { None } } pub fn reserve(&mut self, additional: usize) where K: std::hash::Hash + Eq, { self.0.reserve(additional) } pub fn shrink_to(&mut self, min_capacity: usize) where K: std::hash::Hash + Eq, { self.0.shrink_to(min_capacity) } pub fn shrink_to_fit(&mut self) where K: std::hash::Hash + Eq, { self.0.shrink_to_fit() } pub fn try_reserve( &mut self, additional: usize, ) -> Result<(), std::collections::TryReserveError> where K: std::hash::Hash + Eq, { self.0.try_reserve(additional) } pub fn values(&self) -> impl Iterator { self.0.values().map(|(_, v)| v) } pub fn values_mut(&mut self) -> impl Iterator { self.0.values_mut().map(|(_, v)| v) } pub fn with_capacity(capacity: usize) -> Self { Self(HashMap::with_capacity(capacity)) } } // #[derive(Debug, Clone)] // pub struct MacawChat { // inner: Arc>, // jid: JID, // latest_message: Option, // store: MacawChatStore, // } // impl Drop for MacawChat { // fn drop(&mut self) { // let mut store = match self.store.0.lock() { // Ok(s) => s, // Err(s) => s.into_inner(), // }; // if Arc::>::strong_count(&self.inner) == 2 { // store.shift_remove(&self.jid); // } // } // } // #[derive(Debug, Clone)] // pub struct MacawChatStore(Arc>>); // #[derive(Debug, Clone)] // pub struct MacawChatMessage { // inner: Arc>, // id: Uuid, // user: BorrowedUser, // store: MacawChatMessageStore, // } // impl Drop for MacawChatMessage { // fn drop(&mut self) { // let mut store = match self.store.0.lock() { // Ok(s) => s, // Err(s) => s.into_inner(), // }; // if Rc::::strong_count(&self.inner) == 1 { // store.shift_remove(&self.id) // } // } // } // #[derive(Debug, Clone)] // pub struct MacawChatMessageStore(HashMap); // impl Deref for MacawChatMessageStore { // type Target = HashMap; // fn deref(&self) -> &Self::Target { // &self.0 // } // } // impl DerefMut for MacawChatMessageStore { // fn deref_mut(&mut self) -> &mut Self::Target { // &mut self.0 // } // } // #[derive(Debug, Clone)] // pub struct BorrowedUser { // inner: Rc, // contact: Option>, // store: Rc>, // } // impl Drop for BorrowedUser { // fn drop(&mut self) { // if Rc::::strong_count(&self.inner) == 1 { // self.store.borrow_mut().remove(&self.inner.jid); // } // } // } // impl Deref for BorrowedUser { // type Target = User; // fn deref(&self) -> &Self::Target { // self.inner.as_ref() // } // } // #[derive(Debug)] // pub struct MacawUserStore(HashMap)>); // impl Deref for MacawUserStore { // type Target = HashMap)>; // fn deref(&self) -> &Self::Target { // &self.0 // } // } // impl DerefMut for MacawUserStore { // fn deref_mut(&mut self) -> &mut Self::Target { // &mut self.0 // } // } // #[derive(Debug, Clone)] // pub struct BorrowedContact { // inner: Rc, // user: Box, // store: Rc>, // } // impl Drop for BorrowedContact { // fn drop(&mut self) { // if Rc::::strong_count(&self.inner) == 1 { // self.store.borrow_mut().remove(&self.inner.user_jid); // } // } // } // impl Deref for BorrowedContact { // type Target = Contact; // fn deref(&self) -> &Self::Target { // self.inner.as_ref() // } // } // #[derive(Debug)] // pub struct MacawRosterStore(HashMap); // impl Deref for MacawRosterStore { // type Target = HashMap; // fn deref(&self) -> &Self::Target { // &self.0 // } // } // impl DerefMut for MacawRosterStore { // fn deref_mut(&mut self) -> &mut Self::Target { // &mut self.0 // } // }