Initial commit

This commit is contained in:
Aleksandr 2024-11-17 14:58:34 +03:00
commit 8ecea67e6b
31 changed files with 3297 additions and 0 deletions

105
src/post_queue.rs Normal file
View file

@ -0,0 +1,105 @@
use std::{
cmp::{Ordering, Reverse},
ops::Deref,
};
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
pub struct Item {
pub novel: String,
pub post_at: jiff::Zoned,
}
pub struct Closest<'a> {
queue: &'a mut Queue,
}
impl<'a> Closest<'a> {
pub fn try_pop(self, now: &jiff::Zoned) -> Option<Item> {
let last = self.queue.entries.pop().unwrap();
if now >= &last.post_at {
Some(last)
} else {
self.queue.entries.push(last);
None
}
}
}
impl<'a> Deref for Closest<'a> {
type Target = Item;
fn deref(&self) -> &Self::Target {
let len = self.queue.entries.len() - 1;
&self.queue.entries[len]
}
}
fn cmp_items(lhs: &Item, rhs: &Item) -> Ordering {
Reverse(&lhs.post_at).cmp(&Reverse(&rhs.post_at))
}
#[derive(Debug, Default)]
pub struct Queue {
entries: Vec<Item>,
}
impl FromIterator<Item> for Queue {
fn from_iter<T: IntoIterator<Item = Item>>(iter: T) -> Self {
let mut entries: Vec<Item> = iter.into_iter().collect();
entries.sort_unstable_by(cmp_items);
#[cfg(debug_assertions)]
if entries.len() >= 2 {
let first = &entries[0].post_at;
let second = &entries[1].post_at;
assert!(first >= second);
}
Self { entries }
}
}
impl Queue {
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn closest(&self) -> Option<&Item> {
self.entries.last()
}
pub fn closest_mut(&mut self) -> Option<Closest<'_>> {
if self.entries.is_empty() {
None
} else {
Some(Closest { queue: self })
}
}
pub fn add(&mut self, item: Item) {
// This could be:
// let Ok(idx) | Err(idx) = ..;
// But fuck rust, it's not allowed.
let res = self
.entries
.binary_search_by(|probe| cmp_items(probe, &item));
// The why блядь?
let idx = match res {
Ok(i) => i,
Err(i) => i,
};
self.entries.insert(idx, item);
}
pub const fn new() -> Self {
Self {
entries: Vec::new(),
}
}
}