// pub struct State<'a> {
// // open_chat: Option<OpenChat<'a>>,
// chats: Vec<BorrowedChat<'a>>,
// roster: Vec<BorrowedContact<'a>>,
// }
// 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<RefCell<User>>,
// user: BorrowedUser<'a>,
// }
// pub struct BorrowedContact<'a> {
// inner: &'a OwnedContact,
// user: BorrowedUser<'a>,
// }
// pub struct BorrowedChat<'a> {
// inner: &'a OwnedChat,
// // user: Rc<RefCell<OwnedUser>>,
// user: BorrowedUser<'a>,
// // latest_message: Option<Rc<RefCell<OwnedMessage>>>,
// latest_message: Option<BorrowedMessage<'a>>,
// }
// pub struct OpenChat<'a> {
// chat: BorrowedChat<'a>,
// messages: Vec<BorrowedMessage<'a>>,
// }
// 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<OpenChat<'a>>,
// chats: Vec<BorrowedChat<'a>>,
// roster: Vec<BorrowedContact<'a>>,
// }
// pub struct AState {
// open_chat: Option<OwnedOpenChat>,
// chats: HashMap<JID, (Chat, (User, Option<Contact>), Option<ChatMessage>)>,
// roster: HashMap<JID, (Contact, User)>,
// }
// pub struct OwnedOpenChat {
// chat: (Chat, (User, Option<Contact>)),
// messages: IndexMap<Uuid, (ChatMessage, (User, Option<Contact>))>,
// }
// pub struct MacawUser {
// inner: User,
// contact: Option<Contact>,
// }
// 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<DatabaseError>> {
// 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<Contact> {
// 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<K: Clone, V: Clone>(HashMap<K, (usize, V)>);
impl<K: Clone, V: Clone> DroppableStore<K, V> {
pub fn capacity(&self) -> usize {
self.0.capacity()
}
pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
where
Q: std::hash::Hash + Eq,
K: Borrow<Q> + std::hash::Hash + Eq,
{
self.0.contains_key(k)
}
pub fn get<Q>(&self, k: &Q) -> Option<&V>
where
Q: std::hash::Hash + Eq,
K: Borrow<Q> + std::hash::Hash + Eq,
{
self.0.get(k).map(|(_, v)| v)
}
pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
where
Q: std::hash::Hash + Eq + ?Sized,
K: Borrow<Q> + std::hash::Hash + Eq,
{
self.0.get_key_value(k).map(|(k, (_, v))| (k, v))
}
pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
where
Q: std::hash::Hash + Eq + ?Sized,
K: Borrow<Q> + std::hash::Hash + Eq,
{
self.0.get_mut(k).map(|(_, v)| v)
}
pub fn insert(&mut self, k: K, v: V) -> Option<V>
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<Item = (&K, &V)> {
self.0.iter().map(|(k, (_, v))| (k, v))
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
self.0.iter_mut().map(|(k, (_, v))| (k, v))
}
pub fn keys(&self) -> impl Iterator<Item = &K> {
self.0.keys()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn new() -> Self {
Self(HashMap::new())
}
pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
where
K: Borrow<Q> + 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<Q>(&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<Item = &V> {
self.0.values().map(|(_, v)| v)
}
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
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<Mutex<Chat>>,
// jid: JID,
// latest_message: Option<MacawChatMessage>,
// 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::<Mutex<Chat>>::strong_count(&self.inner) == 2 {
// store.shift_remove(&self.jid);
// }
// }
// }
// #[derive(Debug, Clone)]
// pub struct MacawChatStore(Arc<Mutex<IndexMap<JID, MacawChat>>>);
// #[derive(Debug, Clone)]
// pub struct MacawChatMessage {
// inner: Arc<Mutex<ChatMessage>>,
// 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::<ChatMessage>::strong_count(&self.inner) == 1 {
// store.shift_remove(&self.id)
// }
// }
// }
// #[derive(Debug, Clone)]
// pub struct MacawChatMessageStore(HashMap<Uuid, MacawChatMessage>);
// impl Deref for MacawChatMessageStore {
// type Target = HashMap<Uuid, (ChatMessage, BorrowedUser)>;
// 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<User>,
// contact: Option<Box<BorrowedContact>>,
// store: Rc<RefCell<MacawUserStore>>,
// }
// impl Drop for BorrowedUser {
// fn drop(&mut self) {
// if Rc::<User>::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<JID, (User, Option<BorrowedContact>)>);
// impl Deref for MacawUserStore {
// type Target = HashMap<JID, (User, Option<BorrowedContact>)>;
// 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<Contact>,
// user: Box<BorrowedUser>,
// store: Rc<RefCell<MacawRosterStore>>,
// }
// impl Drop for BorrowedContact {
// fn drop(&mut self) {
// if Rc::<Contact>::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<JID, (Contact, BorrowedUser)>);
// impl Deref for MacawRosterStore {
// type Target = HashMap<JID, (Contact, BorrowedUser)>;
// fn deref(&self) -> &Self::Target {
// &self.0
// }
// }
// impl DerefMut for MacawRosterStore {
// fn deref_mut(&mut self) -> &mut Self::Target {
// &mut self.0
// }
// }