notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

message_store.rs (2216B)


      1 use enostr::Pubkey;
      2 use hashbrown::HashSet;
      3 use nostrdb::NoteKey;
      4 use notedeck::NoteRef;
      5 use std::cmp::Ordering;
      6 
      7 /// Maintains a strictly ordered list of message references for a single
      8 /// conversation. It mirrors the lightweight ordering guarantees that
      9 /// `TimelineCache` and `Threads` rely on so UI code can assume the
     10 /// backing data is already sorted from newest to oldest.
     11 #[derive(Default)]
     12 pub struct MessageStore {
     13     pub messages_ordered: Vec<NotePkg>,
     14     seen: HashSet<NoteKey>,
     15 }
     16 
     17 impl MessageStore {
     18     pub fn new() -> Self {
     19         Self::default()
     20     }
     21 
     22     /// Inserts a new `NoteRef` while keeping the store sorted. Returns
     23     /// `true` when the reference was new to the conversation.
     24     pub fn insert(&mut self, note: NotePkg) -> bool {
     25         if !self.seen.insert(note.note_ref.key) {
     26             return false;
     27         }
     28 
     29         match self.messages_ordered.binary_search(&note) {
     30             Ok(_) => {
     31                 debug_assert!(
     32                     false,
     33                     "MessageStore::insert was asked to insert a duplicate NoteRef"
     34                 );
     35                 false
     36             }
     37             Err(idx) => {
     38                 self.messages_ordered.insert(idx, note);
     39                 true
     40             }
     41         }
     42     }
     43 
     44     pub fn is_empty(&self) -> bool {
     45         self.messages_ordered.is_empty()
     46     }
     47 
     48     pub fn len(&self) -> usize {
     49         self.messages_ordered.len()
     50     }
     51 
     52     pub fn latest(&self) -> Option<&NoteRef> {
     53         self.messages_ordered.first().map(|p| &p.note_ref)
     54     }
     55 
     56     pub fn newest_timestamp(&self) -> Option<u64> {
     57         self.latest().map(|n| n.created_at)
     58     }
     59 }
     60 
     61 pub struct NotePkg {
     62     pub note_ref: NoteRef,
     63     pub author: Pubkey,
     64 }
     65 
     66 impl Ord for NotePkg {
     67     fn cmp(&self, other: &Self) -> Ordering {
     68         self.note_ref
     69             .cmp(&other.note_ref)
     70             .then_with(|| self.author.cmp(&other.author))
     71     }
     72 }
     73 
     74 impl PartialOrd for NotePkg {
     75     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
     76         Some(self.cmp(other))
     77     }
     78 }
     79 
     80 impl PartialEq for NotePkg {
     81     fn eq(&self, other: &Self) -> bool {
     82         self.note_ref == other.note_ref && self.author == other.author
     83     }
     84 }
     85 
     86 impl Eq for NotePkg {}