Move functions to EuphVault and add EuphRoomVault
This commit moves all euph_* functions from Vault to EuphVault. The previous EuphVault is now called EuphRoomVault and re-exports all room-based functions from the EuphVault. It also implements MsgStore.
This commit is contained in:
parent
ff56bb2678
commit
da2c3d86f5
9 changed files with 148 additions and 163 deletions
|
|
@ -20,7 +20,7 @@ use tokio_tungstenite::tungstenite::handshake::client::Response;
|
||||||
use tokio_tungstenite::tungstenite::http::{header, HeaderValue};
|
use tokio_tungstenite::tungstenite::http::{header, HeaderValue};
|
||||||
|
|
||||||
use crate::macros::ok_or_return;
|
use crate::macros::ok_or_return;
|
||||||
use crate::vault::{EuphVault, Vault};
|
use crate::vault::{EuphRoomVault, EuphVault};
|
||||||
|
|
||||||
const TIMEOUT: Duration = Duration::from_secs(30);
|
const TIMEOUT: Duration = Duration::from_secs(30);
|
||||||
const RECONNECT_INTERVAL: Duration = Duration::from_secs(5);
|
const RECONNECT_INTERVAL: Duration = Duration::from_secs(5);
|
||||||
|
|
@ -61,7 +61,7 @@ struct State {
|
||||||
username: Option<String>,
|
username: Option<String>,
|
||||||
force_username: bool,
|
force_username: bool,
|
||||||
password: Option<String>,
|
password: Option<String>,
|
||||||
vault: EuphVault,
|
vault: EuphRoomVault,
|
||||||
|
|
||||||
conn_tx: Option<ConnTx>,
|
conn_tx: Option<ConnTx>,
|
||||||
/// `None` before any `snapshot-event`, then either `Some(None)` or
|
/// `None` before any `snapshot-event`, then either `Some(None)` or
|
||||||
|
|
@ -107,7 +107,7 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn reconnect(
|
async fn reconnect(
|
||||||
vault: &EuphVault,
|
vault: &EuphRoomVault,
|
||||||
name: &str,
|
name: &str,
|
||||||
event_tx: &mpsc::UnboundedSender<Event>,
|
event_tx: &mpsc::UnboundedSender<Event>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
|
@ -140,8 +140,8 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_cookies(vault: &Vault) -> String {
|
async fn get_cookies(vault: &EuphVault) -> String {
|
||||||
let cookie_jar = vault.euph_cookies().await;
|
let cookie_jar = vault.cookies().await;
|
||||||
let cookies = cookie_jar
|
let cookies = cookie_jar
|
||||||
.iter()
|
.iter()
|
||||||
.map(|c| format!("{}", c.stripped()))
|
.map(|c| format!("{}", c.stripped()))
|
||||||
|
|
@ -149,7 +149,7 @@ impl State {
|
||||||
cookies.join("; ")
|
cookies.join("; ")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cookies(vault: &Vault, response: &Response) {
|
fn update_cookies(vault: &EuphVault, response: &Response) {
|
||||||
let mut cookie_jar = CookieJar::new();
|
let mut cookie_jar = CookieJar::new();
|
||||||
|
|
||||||
for (name, value) in response.headers() {
|
for (name, value) in response.headers() {
|
||||||
|
|
@ -160,10 +160,13 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vault.euph_set_cookies(cookie_jar);
|
vault.set_cookies(cookie_jar);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn connect(vault: &EuphVault, name: &str) -> anyhow::Result<Option<(ConnTx, ConnRx)>> {
|
async fn connect(
|
||||||
|
vault: &EuphRoomVault,
|
||||||
|
name: &str,
|
||||||
|
) -> anyhow::Result<Option<(ConnTx, ConnRx)>> {
|
||||||
let uri = format!("wss://euphoria.io/room/{name}/ws?h=1");
|
let uri = format!("wss://euphoria.io/room/{name}/ws?h=1");
|
||||||
let mut request = uri.into_client_request().expect("valid request");
|
let mut request = uri.into_client_request().expect("valid request");
|
||||||
let cookies = Self::get_cookies(vault.vault()).await;
|
let cookies = Self::get_cookies(vault.vault()).await;
|
||||||
|
|
@ -304,7 +307,7 @@ impl State {
|
||||||
if let Some(last_msg_id) = &mut self.last_msg_id {
|
if let Some(last_msg_id) = &mut self.last_msg_id {
|
||||||
let id = d.0.id;
|
let id = d.0.id;
|
||||||
self.vault
|
self.vault
|
||||||
.add_message(d.0.clone(), *last_msg_id, own_user_id);
|
.add_msg(Box::new(d.0.clone()), *last_msg_id, own_user_id);
|
||||||
*last_msg_id = Some(id);
|
*last_msg_id = Some(id);
|
||||||
} else {
|
} else {
|
||||||
bail!("send event before snapshot event");
|
bail!("send event before snapshot event");
|
||||||
|
|
@ -315,7 +318,7 @@ impl State {
|
||||||
self.vault.join(Time::now());
|
self.vault.join(Time::now());
|
||||||
self.last_msg_id = Some(d.log.last().map(|m| m.id));
|
self.last_msg_id = Some(d.log.last().map(|m| m.id));
|
||||||
let own_user_id = self.own_user_id().await;
|
let own_user_id = self.own_user_id().await;
|
||||||
self.vault.add_messages(d.log.clone(), None, own_user_id);
|
self.vault.add_msgs(d.log.clone(), None, own_user_id);
|
||||||
|
|
||||||
if let Some(username) = &self.username {
|
if let Some(username) = &self.username {
|
||||||
if self.force_username || d.nick.is_none() {
|
if self.force_username || d.nick.is_none() {
|
||||||
|
|
@ -325,15 +328,14 @@ impl State {
|
||||||
}
|
}
|
||||||
Data::LogReply(d) => {
|
Data::LogReply(d) => {
|
||||||
let own_user_id = self.own_user_id().await;
|
let own_user_id = self.own_user_id().await;
|
||||||
self.vault
|
self.vault.add_msgs(d.log.clone(), d.before, own_user_id);
|
||||||
.add_messages(d.log.clone(), d.before, own_user_id);
|
|
||||||
}
|
}
|
||||||
Data::SendReply(d) => {
|
Data::SendReply(d) => {
|
||||||
let own_user_id = self.own_user_id().await;
|
let own_user_id = self.own_user_id().await;
|
||||||
if let Some(last_msg_id) = &mut self.last_msg_id {
|
if let Some(last_msg_id) = &mut self.last_msg_id {
|
||||||
let id = d.0.id;
|
let id = d.0.id;
|
||||||
self.vault
|
self.vault
|
||||||
.add_message(d.0.clone(), *last_msg_id, own_user_id);
|
.add_msg(Box::new(d.0.clone()), *last_msg_id, own_user_id);
|
||||||
*last_msg_id = Some(id);
|
*last_msg_id = Some(id);
|
||||||
} else {
|
} else {
|
||||||
bail!("send reply before snapshot event");
|
bail!("send reply before snapshot event");
|
||||||
|
|
@ -378,7 +380,7 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn request_logs(vault: EuphVault, conn_tx: ConnTx) -> anyhow::Result<()> {
|
async fn request_logs(vault: EuphRoomVault, conn_tx: ConnTx) -> anyhow::Result<()> {
|
||||||
let before = match vault.last_span().await {
|
let before = match vault.last_span().await {
|
||||||
Some((None, _)) => return Ok(()), // Already at top of room history
|
Some((None, _)) => return Ok(()), // Already at top of room history
|
||||||
Some((Some(before), _)) => Some(before),
|
Some((Some(before), _)) => Some(before),
|
||||||
|
|
@ -457,7 +459,7 @@ pub struct Room {
|
||||||
|
|
||||||
impl Room {
|
impl Room {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
vault: EuphVault,
|
vault: EuphRoomVault,
|
||||||
username: Option<String>,
|
username: Option<String>,
|
||||||
force_username: bool,
|
force_username: bool,
|
||||||
password: Option<String>,
|
password: Option<String>,
|
||||||
|
|
@ -465,7 +467,7 @@ impl Room {
|
||||||
let (canary_tx, canary_rx) = oneshot::channel();
|
let (canary_tx, canary_rx) = oneshot::channel();
|
||||||
let (event_tx, event_rx) = mpsc::unbounded_channel();
|
let (event_tx, event_rx) = mpsc::unbounded_channel();
|
||||||
let (euph_room_event_tx, euph_room_event_rx) = mpsc::unbounded_channel();
|
let (euph_room_event_tx, euph_room_event_rx) = mpsc::unbounded_channel();
|
||||||
let ephemeral = vault.vault().ephemeral();
|
let ephemeral = vault.vault().vault().ephemeral();
|
||||||
|
|
||||||
let state = State {
|
let state = State {
|
||||||
name: vault.room().to_string(),
|
name: vault.room().to_string(),
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ mod text;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufWriter, Write};
|
use std::io::{BufWriter, Write};
|
||||||
|
|
||||||
use crate::vault::Vault;
|
use crate::vault::EuphVault;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, clap::ValueEnum)]
|
#[derive(Debug, Clone, Copy, clap::ValueEnum)]
|
||||||
pub enum Format {
|
pub enum Format {
|
||||||
|
|
@ -60,13 +60,13 @@ pub struct Args {
|
||||||
out: String,
|
out: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn export(vault: &Vault, mut args: Args) -> anyhow::Result<()> {
|
pub async fn export(vault: &EuphVault, mut args: Args) -> anyhow::Result<()> {
|
||||||
if args.out.ends_with('/') {
|
if args.out.ends_with('/') {
|
||||||
args.out.push_str("%r.%e");
|
args.out.push_str("%r.%e");
|
||||||
}
|
}
|
||||||
|
|
||||||
let rooms = if args.all {
|
let rooms = if args.all {
|
||||||
let mut rooms = vault.euph_rooms().await;
|
let mut rooms = vault.rooms().await;
|
||||||
rooms.sort_unstable();
|
rooms.sort_unstable();
|
||||||
rooms
|
rooms
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -83,10 +83,11 @@ pub async fn export(vault: &Vault, mut args: Args) -> anyhow::Result<()> {
|
||||||
let out = format_out(&args.out, &room, args.format);
|
let out = format_out(&args.out, &room, args.format);
|
||||||
println!("Exporting &{room} as {} to {out}", args.format.name());
|
println!("Exporting &{room} as {} to {out}", args.format.name());
|
||||||
|
|
||||||
|
let vault = vault.room(room);
|
||||||
let mut file = BufWriter::new(File::create(out)?);
|
let mut file = BufWriter::new(File::create(out)?);
|
||||||
match args.format {
|
match args.format {
|
||||||
Format::Text => text::export_to_file(vault, room, &mut file).await?,
|
Format::Text => text::export_to_file(&vault, &mut file).await?,
|
||||||
Format::Json => json::export_to_file(vault, room, &mut file).await?,
|
Format::Json => json::export_to_file(&vault, &mut file).await?,
|
||||||
}
|
}
|
||||||
file.flush()?;
|
file.flush()?;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,14 @@
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufWriter, Write};
|
use std::io::{BufWriter, Write};
|
||||||
|
|
||||||
use crate::vault::Vault;
|
use crate::vault::EuphRoomVault;
|
||||||
|
|
||||||
const CHUNK_SIZE: usize = 10000;
|
const CHUNK_SIZE: usize = 10000;
|
||||||
|
|
||||||
pub async fn export_to_file(
|
pub async fn export_to_file(
|
||||||
vault: &Vault,
|
vault: &EuphRoomVault,
|
||||||
room: String,
|
|
||||||
file: &mut BufWriter<File>,
|
file: &mut BufWriter<File>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let vault = vault.euph(room);
|
|
||||||
|
|
||||||
write!(file, "[")?;
|
write!(file, "[")?;
|
||||||
|
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
|
|
|
||||||
|
|
@ -7,27 +7,24 @@ use time::macros::format_description;
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use crate::euph::SmallMessage;
|
use crate::euph::SmallMessage;
|
||||||
use crate::store::{MsgStore, Tree};
|
use crate::store::Tree;
|
||||||
use crate::vault::Vault;
|
use crate::vault::EuphRoomVault;
|
||||||
|
|
||||||
const TIME_FORMAT: &[FormatItem<'_>] =
|
const TIME_FORMAT: &[FormatItem<'_>] =
|
||||||
format_description!("[year]-[month]-[day] [hour]:[minute]:[second]");
|
format_description!("[year]-[month]-[day] [hour]:[minute]:[second]");
|
||||||
const TIME_EMPTY: &str = " ";
|
const TIME_EMPTY: &str = " ";
|
||||||
|
|
||||||
pub async fn export_to_file(
|
pub async fn export_to_file(
|
||||||
vault: &Vault,
|
vault: &EuphRoomVault,
|
||||||
room: String,
|
|
||||||
file: &mut BufWriter<File>,
|
file: &mut BufWriter<File>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let vault = vault.euph(room);
|
|
||||||
|
|
||||||
let mut exported_trees = 0;
|
let mut exported_trees = 0;
|
||||||
let mut exported_msgs = 0;
|
let mut exported_msgs = 0;
|
||||||
let mut tree_id = vault.first_tree_id().await;
|
let mut tree_id = vault.first_tree_id().await;
|
||||||
while let Some(some_tree_id) = tree_id {
|
while let Some(some_tree_id) = tree_id {
|
||||||
let tree = vault.tree(&some_tree_id).await;
|
let tree = vault.tree(some_tree_id).await;
|
||||||
write_tree(file, &tree, some_tree_id, 0)?;
|
write_tree(file, &tree, some_tree_id, 0)?;
|
||||||
tree_id = vault.next_tree_id(&some_tree_id).await;
|
tree_id = vault.next_tree_id(some_tree_id).await;
|
||||||
|
|
||||||
exported_trees += 1;
|
exported_trees += 1;
|
||||||
exported_msgs += tree.len();
|
exported_msgs += tree.len();
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
match args.command.unwrap_or_default() {
|
match args.command.unwrap_or_default() {
|
||||||
Command::Run => run(config, &vault, args.measure_widths).await?,
|
Command::Run => run(config, &vault, args.measure_widths).await?,
|
||||||
Command::Export(args) => export::export(&vault, args).await?,
|
Command::Export(args) => export::export(&vault.euph(), args).await?,
|
||||||
Command::Gc => {
|
Command::Gc => {
|
||||||
println!("Cleaning up and compacting vault");
|
println!("Cleaning up and compacting vault");
|
||||||
println!("This may take a while...");
|
println!("This may take a while...");
|
||||||
|
|
@ -151,7 +151,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
Command::ClearCookies => {
|
Command::ClearCookies => {
|
||||||
println!("Clearing cookies");
|
println!("Clearing cookies");
|
||||||
vault.euph_set_cookies(CookieJar::new());
|
vault.euph().set_cookies(CookieJar::new());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ use toss::terminal::Terminal;
|
||||||
use crate::config;
|
use crate::config;
|
||||||
use crate::euph::{self, EuphRoomEvent};
|
use crate::euph::{self, EuphRoomEvent};
|
||||||
use crate::macros::{ok_or_return, some_or_return};
|
use crate::macros::{ok_or_return, some_or_return};
|
||||||
use crate::store::MsgStore;
|
|
||||||
use crate::ui::chat::{ChatState, Reaction};
|
use crate::ui::chat::{ChatState, Reaction};
|
||||||
use crate::ui::input::{key, InputEvent, KeyBindingsList};
|
use crate::ui::input::{key, InputEvent, KeyBindingsList};
|
||||||
use crate::ui::widgets::border::Border;
|
use crate::ui::widgets::border::Border;
|
||||||
|
|
@ -25,7 +24,7 @@ use crate::ui::widgets::padding::Padding;
|
||||||
use crate::ui::widgets::text::Text;
|
use crate::ui::widgets::text::Text;
|
||||||
use crate::ui::widgets::BoxedWidget;
|
use crate::ui::widgets::BoxedWidget;
|
||||||
use crate::ui::UiEvent;
|
use crate::ui::UiEvent;
|
||||||
use crate::vault::EuphVault;
|
use crate::vault::EuphRoomVault;
|
||||||
|
|
||||||
use super::account::{self, AccountUiState};
|
use super::account::{self, AccountUiState};
|
||||||
use super::links::{self, LinksState};
|
use super::links::{self, LinksState};
|
||||||
|
|
@ -65,13 +64,13 @@ pub struct EuphRoom {
|
||||||
|
|
||||||
ui_event_tx: mpsc::UnboundedSender<UiEvent>,
|
ui_event_tx: mpsc::UnboundedSender<UiEvent>,
|
||||||
|
|
||||||
vault: EuphVault,
|
vault: EuphRoomVault,
|
||||||
room: Option<euph::Room>,
|
room: Option<euph::Room>,
|
||||||
|
|
||||||
state: State,
|
state: State,
|
||||||
popups: VecDeque<RoomPopup>,
|
popups: VecDeque<RoomPopup>,
|
||||||
|
|
||||||
chat: ChatState<euph::SmallMessage, EuphVault>,
|
chat: ChatState<euph::SmallMessage, EuphRoomVault>,
|
||||||
last_msg_sent: Option<oneshot::Receiver<Snowflake>>,
|
last_msg_sent: Option<oneshot::Receiver<Snowflake>>,
|
||||||
|
|
||||||
nick_list: ListState<String>,
|
nick_list: ListState<String>,
|
||||||
|
|
@ -80,7 +79,7 @@ pub struct EuphRoom {
|
||||||
impl EuphRoom {
|
impl EuphRoom {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
config: config::EuphRoom,
|
config: config::EuphRoom,
|
||||||
vault: EuphVault,
|
vault: EuphRoomVault,
|
||||||
ui_event_tx: mpsc::UnboundedSender<UiEvent>,
|
ui_event_tx: mpsc::UnboundedSender<UiEvent>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -368,7 +367,7 @@ impl EuphRoom {
|
||||||
}
|
}
|
||||||
key!('I') => {
|
key!('I') => {
|
||||||
if let Some(id) = self.chat.cursor().await {
|
if let Some(id) = self.chat.cursor().await {
|
||||||
if let Some(msg) = self.vault.msg(&id).await {
|
if let Some(msg) = self.vault.msg(id).await {
|
||||||
self.state = State::Links(LinksState::new(&msg.content));
|
self.state = State::Links(LinksState::new(&msg.content));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -415,7 +414,7 @@ impl EuphRoom {
|
||||||
|
|
||||||
if let key!('I') = event {
|
if let key!('I') = event {
|
||||||
if let Some(id) = self.chat.cursor().await {
|
if let Some(id) = self.chat.cursor().await {
|
||||||
if let Some(msg) = self.vault.msg(&id).await {
|
if let Some(msg) = self.vault.msg(id).await {
|
||||||
self.state = State::Links(LinksState::new(&msg.content));
|
self.state = State::Links(LinksState::new(&msg.content));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ impl Rooms {
|
||||||
self.euph_rooms.entry(name.clone()).or_insert_with(|| {
|
self.euph_rooms.entry(name.clone()).or_insert_with(|| {
|
||||||
EuphRoom::new(
|
EuphRoom::new(
|
||||||
self.config.euph_room(&name),
|
self.config.euph_room(&name),
|
||||||
self.vault.euph(name),
|
self.vault.euph().room(name),
|
||||||
self.ui_event_tx.clone(),
|
self.ui_event_tx.clone(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
@ -97,7 +97,8 @@ impl Rooms {
|
||||||
async fn stabilize_rooms(&mut self) {
|
async fn stabilize_rooms(&mut self) {
|
||||||
let mut rooms_set = self
|
let mut rooms_set = self
|
||||||
.vault
|
.vault
|
||||||
.euph_rooms()
|
.euph()
|
||||||
|
.rooms()
|
||||||
.await
|
.await
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
|
|
@ -484,7 +485,7 @@ impl Rooms {
|
||||||
key!(Esc) => self.state = State::ShowList,
|
key!(Esc) => self.state = State::ShowList,
|
||||||
key!(Enter) if editor.text() == *name => {
|
key!(Enter) if editor.text() == *name => {
|
||||||
self.euph_rooms.remove(name);
|
self.euph_rooms.remove(name);
|
||||||
self.vault.euph(name.clone()).delete();
|
self.vault.euph().room(name.clone()).delete();
|
||||||
self.state = State::ShowList;
|
self.state = State::ShowList;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use rusqlite::Connection;
|
||||||
use tokio::sync::{mpsc, oneshot};
|
use tokio::sync::{mpsc, oneshot};
|
||||||
|
|
||||||
use self::euph::EuphRequest;
|
use self::euph::EuphRequest;
|
||||||
pub use self::euph::EuphVault;
|
pub use self::euph::{EuphRoomVault, EuphVault};
|
||||||
|
|
||||||
enum Request {
|
enum Request {
|
||||||
Close(oneshot::Sender<()>),
|
Close(oneshot::Sender<()>),
|
||||||
|
|
@ -40,11 +40,8 @@ impl Vault {
|
||||||
let _ = rx.await;
|
let _ = rx.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn euph(&self, room: String) -> EuphVault {
|
pub fn euph(&self) -> EuphVault {
|
||||||
EuphVault {
|
EuphVault::new(self.clone())
|
||||||
vault: self.clone(),
|
|
||||||
room,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,146 +54,114 @@ impl From<EuphRequest> for super::Request {
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct EuphVault {
|
pub struct EuphVault {
|
||||||
pub(super) vault: super::Vault,
|
vault: super::Vault,
|
||||||
pub(super) room: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EuphVault {
|
impl EuphVault {
|
||||||
|
pub(crate) fn new(vault: super::Vault) -> Self {
|
||||||
|
Self { vault }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn vault(&self) -> &super::Vault {
|
pub fn vault(&self) -> &super::Vault {
|
||||||
&self.vault
|
&self.vault
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn room(&self, name: String) -> EuphRoomVault {
|
||||||
|
EuphRoomVault {
|
||||||
|
vault: self.clone(),
|
||||||
|
room: name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct EuphRoomVault {
|
||||||
|
vault: EuphVault,
|
||||||
|
room: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EuphRoomVault {
|
||||||
|
pub fn vault(&self) -> &EuphVault {
|
||||||
|
&self.vault
|
||||||
|
}
|
||||||
|
|
||||||
pub fn room(&self) -> &str {
|
pub fn room(&self) -> &str {
|
||||||
&self.room
|
&self.room
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn join(&self, time: Time) {
|
|
||||||
self.vault.euph_join(self.room.clone(), time);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn delete(self) {
|
|
||||||
self.vault.euph_delete(self.room.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_message(
|
|
||||||
&self,
|
|
||||||
msg: Message,
|
|
||||||
prev_msg_id: Option<Snowflake>,
|
|
||||||
own_user_id: Option<UserId>,
|
|
||||||
) {
|
|
||||||
self.vault
|
|
||||||
.euph_add_msg(self.room.clone(), Box::new(msg), prev_msg_id, own_user_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_messages(
|
|
||||||
&self,
|
|
||||||
msgs: Vec<Message>,
|
|
||||||
next_msg_id: Option<Snowflake>,
|
|
||||||
own_user_id: Option<UserId>,
|
|
||||||
) {
|
|
||||||
self.vault
|
|
||||||
.euph_add_msgs(self.room.clone(), msgs, next_msg_id, own_user_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn last_span(&self) -> Option<(Option<Snowflake>, Option<Snowflake>)> {
|
|
||||||
self.vault.euph_last_span(self.room.clone()).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn full_msg(&self, id: Snowflake) -> Option<Message> {
|
|
||||||
self.vault.euph_full_msg(self.room.clone(), id).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn chunk_at_offset(&self, amount: usize, offset: usize) -> Vec<Message> {
|
|
||||||
self.vault
|
|
||||||
.euph_chunk_at_offset(self.room.clone(), amount, offset)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl MsgStore<SmallMessage> for EuphVault {
|
impl MsgStore<SmallMessage> for EuphRoomVault {
|
||||||
async fn path(&self, id: &Snowflake) -> Path<Snowflake> {
|
async fn path(&self, id: &Snowflake) -> Path<Snowflake> {
|
||||||
self.vault.euph_path(self.room.clone(), *id).await
|
self.path(*id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn msg(&self, id: &Snowflake) -> Option<SmallMessage> {
|
async fn msg(&self, id: &Snowflake) -> Option<SmallMessage> {
|
||||||
self.vault.euph_msg(self.room.clone(), *id).await
|
self.msg(*id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn tree(&self, tree_id: &Snowflake) -> Tree<SmallMessage> {
|
async fn tree(&self, tree_id: &Snowflake) -> Tree<SmallMessage> {
|
||||||
self.vault.euph_tree(self.room.clone(), *tree_id).await
|
self.tree(*tree_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn first_tree_id(&self) -> Option<Snowflake> {
|
async fn first_tree_id(&self) -> Option<Snowflake> {
|
||||||
self.vault.euph_first_tree_id(self.room.clone()).await
|
self.first_tree_id().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn last_tree_id(&self) -> Option<Snowflake> {
|
async fn last_tree_id(&self) -> Option<Snowflake> {
|
||||||
self.vault.euph_last_tree_id(self.room.clone()).await
|
self.last_tree_id().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn prev_tree_id(&self, tree_id: &Snowflake) -> Option<Snowflake> {
|
async fn prev_tree_id(&self, tree_id: &Snowflake) -> Option<Snowflake> {
|
||||||
self.vault
|
self.prev_tree_id(*tree_id).await
|
||||||
.euph_prev_tree_id(self.room.clone(), *tree_id)
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn next_tree_id(&self, tree_id: &Snowflake) -> Option<Snowflake> {
|
async fn next_tree_id(&self, tree_id: &Snowflake) -> Option<Snowflake> {
|
||||||
self.vault
|
self.next_tree_id(*tree_id).await
|
||||||
.euph_next_tree_id(self.room.clone(), *tree_id)
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn oldest_msg_id(&self) -> Option<Snowflake> {
|
async fn oldest_msg_id(&self) -> Option<Snowflake> {
|
||||||
self.vault.euph_oldest_msg_id(self.room.clone()).await
|
self.oldest_msg_id().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn newest_msg_id(&self) -> Option<Snowflake> {
|
async fn newest_msg_id(&self) -> Option<Snowflake> {
|
||||||
self.vault.euph_newest_msg_id(self.room.clone()).await
|
self.newest_msg_id().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn older_msg_id(&self, id: &Snowflake) -> Option<Snowflake> {
|
async fn older_msg_id(&self, id: &Snowflake) -> Option<Snowflake> {
|
||||||
self.vault.euph_older_msg_id(self.room.clone(), *id).await
|
self.older_msg_id(*id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn newer_msg_id(&self, id: &Snowflake) -> Option<Snowflake> {
|
async fn newer_msg_id(&self, id: &Snowflake) -> Option<Snowflake> {
|
||||||
self.vault.euph_newer_msg_id(self.room.clone(), *id).await
|
self.newer_msg_id(*id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn oldest_unseen_msg_id(&self) -> Option<Snowflake> {
|
async fn oldest_unseen_msg_id(&self) -> Option<Snowflake> {
|
||||||
self.vault
|
self.oldest_unseen_msg_id().await
|
||||||
.euph_oldest_unseen_msg_id(self.room.clone())
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn newest_unseen_msg_id(&self) -> Option<Snowflake> {
|
async fn newest_unseen_msg_id(&self) -> Option<Snowflake> {
|
||||||
self.vault
|
self.newest_unseen_msg_id().await
|
||||||
.euph_newest_unseen_msg_id(self.room.clone())
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn older_unseen_msg_id(&self, id: &Snowflake) -> Option<Snowflake> {
|
async fn older_unseen_msg_id(&self, id: &Snowflake) -> Option<Snowflake> {
|
||||||
self.vault
|
self.older_unseen_msg_id(*id).await
|
||||||
.euph_older_unseen_msg_id(self.room.clone(), *id)
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn newer_unseen_msg_id(&self, id: &Snowflake) -> Option<Snowflake> {
|
async fn newer_unseen_msg_id(&self, id: &Snowflake) -> Option<Snowflake> {
|
||||||
self.vault
|
self.newer_unseen_msg_id(*id).await
|
||||||
.euph_newer_unseen_msg_id(self.room.clone(), *id)
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn unseen_msgs_count(&self) -> usize {
|
async fn unseen_msgs_count(&self) -> usize {
|
||||||
self.vault.euph_unseen_msgs_count(self.room.clone()).await
|
self.unseen_msgs_count().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_seen(&self, id: &Snowflake, seen: bool) {
|
async fn set_seen(&self, id: &Snowflake, seen: bool) {
|
||||||
self.vault.euph_set_seen(self.room.clone(), *id, seen);
|
self.set_seen(*id, seen);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_older_seen(&self, id: &Snowflake, seen: bool) {
|
async fn set_older_seen(&self, id: &Snowflake, seen: bool) {
|
||||||
self.vault.euph_set_older_seen(self.room.clone(), *id, seen);
|
self.set_older_seen(*id, seen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,29 +169,47 @@ trait Request {
|
||||||
fn perform(self, conn: &mut Connection) -> rusqlite::Result<()>;
|
fn perform(self, conn: &mut Connection) -> rusqlite::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! requests_helper {
|
macro_rules! requests_vault_fn {
|
||||||
( $var:ident : $fn:ident( $( $arg:ident : $ty:ty ),* ) ) => {
|
( $var:ident : $fn:ident( $( $arg:ident : $ty:ty ),* ) ) => {
|
||||||
pub fn $fn(&self, $( $arg: $ty ),* ) {
|
pub fn $fn(&self $( , $arg: $ty )* ) {
|
||||||
let request = EuphRequest::$var($var { $( $arg, )* });
|
let request = EuphRequest::$var($var { $( $arg, )* });
|
||||||
let _ = self.tx.send(request.into());
|
let _ = self.vault.tx.send(request.into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
( $var:ident : $fn:ident( $( $arg:ident : $ty:ty ),* ) -> $res:ty ) => {
|
( $var:ident : $fn:ident( $( $arg:ident : $ty:ty ),* ) -> $res:ty ) => {
|
||||||
pub async fn $fn(&self, $( $arg: $ty ),* ) -> $res {
|
pub async fn $fn(&self $( , $arg: $ty )* ) -> $res {
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
let request = EuphRequest::$var($var {
|
let request = EuphRequest::$var($var {
|
||||||
$( $arg, )*
|
$( $arg, )*
|
||||||
result: tx,
|
result: tx,
|
||||||
});
|
});
|
||||||
let _ = self.tx.send(request.into());
|
let _ = self.vault.tx.send(request.into());
|
||||||
rx.await.unwrap()
|
rx.await.unwrap()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This doesn't match the type of the `room` argument because that's apparently
|
||||||
|
// impossible to match to `String`. See also the readme of
|
||||||
|
// https://github.com/danielhenrymantilla/rust-defile for a description of this
|
||||||
|
// phenomenon and some examples.
|
||||||
|
macro_rules! requests_room_vault_fn {
|
||||||
|
( $fn:ident ( room: $mustbestring:ty $( , $arg:ident : $ty:ty )* ) ) => {
|
||||||
|
pub fn $fn(&self $( , $arg: $ty )* ) {
|
||||||
|
self.vault.$fn(self.room.clone() $( , $arg )* );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
( $fn:ident ( room: $mustbestring:ty $( , $arg:ident : $ty:ty )* ) -> $res:ty ) => {
|
||||||
|
pub async fn $fn(&self $( , $arg: $ty )* ) -> $res {
|
||||||
|
self.vault.$fn(self.room.clone() $( , $arg )* ).await
|
||||||
|
}
|
||||||
|
};
|
||||||
|
( $( $tt:tt )* ) => { };
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! requests {
|
macro_rules! requests {
|
||||||
( $(
|
( $(
|
||||||
$var:ident : $fn:ident( $( $arg:ident : $ty:ty ),* ) $( -> $res:ty )? ;
|
$var:ident : $fn:ident ( $( $arg:ident : $ty:ty ),* ) $( -> $res:ty )? ;
|
||||||
)* ) => {
|
)* ) => {
|
||||||
$(
|
$(
|
||||||
pub(super) struct $var {
|
pub(super) struct $var {
|
||||||
|
|
@ -245,46 +231,51 @@ macro_rules! requests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl super::Vault {
|
impl EuphVault {
|
||||||
$( requests_helper!($var : $fn( $( $arg: $ty ),* ) $( -> $res )? );)*
|
$( requests_vault_fn!($var : $fn( $( $arg: $ty ),* ) $( -> $res )? ); )*
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EuphRoomVault {
|
||||||
|
$( requests_room_vault_fn!($fn( $( $arg: $ty ),* ) $( -> $res )? ); )*
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Rename `root` to `root_id` or `tree_id`
|
||||||
requests! {
|
requests! {
|
||||||
// Cookies
|
// Cookies
|
||||||
GetCookies : euph_cookies() -> CookieJar;
|
GetCookies : cookies() -> CookieJar;
|
||||||
SetCookies : euph_set_cookies(cookies: CookieJar);
|
SetCookies : set_cookies(cookies: CookieJar);
|
||||||
|
|
||||||
// Rooms
|
// Rooms
|
||||||
GetRooms : euph_rooms() -> Vec<String>;
|
GetRooms : rooms() -> Vec<String>;
|
||||||
Join : euph_join(room: String, time: Time);
|
Join : join(room: String, time: Time);
|
||||||
Delete : euph_delete(room: String);
|
Delete : delete(room: String);
|
||||||
|
|
||||||
// Message
|
// Message
|
||||||
AddMsg : euph_add_msg(room: String, msg: Box<Message>, prev_msg_id: Option<Snowflake>, own_user_id: Option<UserId>);
|
AddMsg : add_msg(room: String, msg: Box<Message>, prev_msg_id: Option<Snowflake>, own_user_id: Option<UserId>);
|
||||||
AddMsgs : euph_add_msgs(room: String, msgs: Vec<Message>, next_msg_id: Option<Snowflake>, own_user_id: Option<UserId>);
|
AddMsgs : add_msgs(room: String, msgs: Vec<Message>, next_msg_id: Option<Snowflake>, own_user_id: Option<UserId>);
|
||||||
GetLastSpan : euph_last_span(room: String) -> Option<(Option<Snowflake>, Option<Snowflake>)>;
|
GetLastSpan : last_span(room: String) -> Option<(Option<Snowflake>, Option<Snowflake>)>;
|
||||||
GetPath : euph_path(room: String, id: Snowflake) -> Path<Snowflake>;
|
GetPath : path(room: String, id: Snowflake) -> Path<Snowflake>;
|
||||||
GetMsg : euph_msg(room: String, id: Snowflake) -> Option<SmallMessage>;
|
GetMsg : msg(room: String, id: Snowflake) -> Option<SmallMessage>;
|
||||||
GetFullMsg : euph_full_msg(room: String, id: Snowflake) -> Option<Message>;
|
GetFullMsg : full_msg(room: String, id: Snowflake) -> Option<Message>;
|
||||||
GetTree : euph_tree(room: String, root: Snowflake) -> Tree<SmallMessage>;
|
GetTree : tree(room: String, root: Snowflake) -> Tree<SmallMessage>;
|
||||||
GetFirstTreeId : euph_first_tree_id(room: String) -> Option<Snowflake>;
|
GetFirstTreeId : first_tree_id(room: String) -> Option<Snowflake>;
|
||||||
GetLastTreeId : euph_last_tree_id(room: String) -> Option<Snowflake>;
|
GetLastTreeId : last_tree_id(room: String) -> Option<Snowflake>;
|
||||||
GetPrevTreeId : euph_prev_tree_id(room: String, root: Snowflake) -> Option<Snowflake>;
|
GetPrevTreeId : prev_tree_id(room: String, root: Snowflake) -> Option<Snowflake>;
|
||||||
GetNextTreeId : euph_next_tree_id(room: String, root: Snowflake) -> Option<Snowflake>;
|
GetNextTreeId : next_tree_id(room: String, root: Snowflake) -> Option<Snowflake>;
|
||||||
GetOldestMsgId : euph_oldest_msg_id(room: String) -> Option<Snowflake>;
|
GetOldestMsgId : oldest_msg_id(room: String) -> Option<Snowflake>;
|
||||||
GetNewestMsgId : euph_newest_msg_id(room: String) -> Option<Snowflake>;
|
GetNewestMsgId : newest_msg_id(room: String) -> Option<Snowflake>;
|
||||||
GetOlderMsgId : euph_older_msg_id(room: String, id: Snowflake) -> Option<Snowflake>;
|
GetOlderMsgId : older_msg_id(room: String, id: Snowflake) -> Option<Snowflake>;
|
||||||
GetNewerMsgId : euph_newer_msg_id(room: String, id: Snowflake) -> Option<Snowflake>;
|
GetNewerMsgId : newer_msg_id(room: String, id: Snowflake) -> Option<Snowflake>;
|
||||||
GetOldestUnseenMsgId : euph_oldest_unseen_msg_id(room: String) -> Option<Snowflake>;
|
GetOldestUnseenMsgId : oldest_unseen_msg_id(room: String) -> Option<Snowflake>;
|
||||||
GetNewestUnseenMsgId : euph_newest_unseen_msg_id(room: String) -> Option<Snowflake>;
|
GetNewestUnseenMsgId : newest_unseen_msg_id(room: String) -> Option<Snowflake>;
|
||||||
GetOlderUnseenMsgId : euph_older_unseen_msg_id(room: String, id: Snowflake) -> Option<Snowflake>;
|
GetOlderUnseenMsgId : older_unseen_msg_id(room: String, id: Snowflake) -> Option<Snowflake>;
|
||||||
GetNewerUnseenMsgId : euph_newer_unseen_msg_id(room: String, id: Snowflake) -> Option<Snowflake>;
|
GetNewerUnseenMsgId : newer_unseen_msg_id(room: String, id: Snowflake) -> Option<Snowflake>;
|
||||||
GetUnseenMsgsCount : euph_unseen_msgs_count(room: String) -> usize;
|
GetUnseenMsgsCount : unseen_msgs_count(room: String) -> usize;
|
||||||
SetSeen : euph_set_seen(room: String, id: Snowflake, seen: bool);
|
SetSeen : set_seen(room: String, id: Snowflake, seen: bool);
|
||||||
SetOlderSeen : euph_set_older_seen(room: String, id: Snowflake, seen: bool);
|
SetOlderSeen : set_older_seen(room: String, id: Snowflake, seen: bool);
|
||||||
GetChunkAtOffset : euph_chunk_at_offset(room: String, amount: usize, offset: usize) -> Vec<Message>;
|
GetChunkAtOffset : chunk_at_offset(room: String, amount: usize, offset: usize) -> Vec<Message>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Request for GetCookies {
|
impl Request for GetCookies {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue