grapevine/src/cli/get_room_states.rs
Charles Hall b1e14fad5c
add option to recompute room state
Hopefully we can make use of this state resolution code for more stuff
in the future.
2024-11-29 13:58:32 -08:00

76 lines
1.9 KiB
Rust

#![warn(clippy::missing_docs_in_private_items)]
//! Implementation of the `get-room-states` command
use std::{cmp::Ordering, sync::Arc};
use ruma::events::StateEventType;
use serde::Serialize;
use super::GetRoomStatesArgs;
use crate::{
config, database::KeyValueDatabase, error, services, PduEvent, Services,
};
mod cache;
mod recompute;
/// Serializable information about a state event
#[derive(Serialize, PartialEq, Eq)]
struct StateEvent {
/// The kind of state event
kind: StateEventType,
/// The `state_key` of the event
key: String,
/// The event itself
event: Arc<PduEvent>,
}
impl Ord for StateEvent {
fn cmp(&self, other: &Self) -> Ordering {
Ordering::Equal
.then_with(|| self.event.room_id.cmp(&other.event.room_id))
.then_with(|| self.kind.cmp(&other.kind))
.then_with(|| self.key.cmp(&other.key))
.then_with(|| self.event.event_id.cmp(&other.event.event_id))
}
}
impl PartialOrd for StateEvent {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
/// Subcommand entrypoint
pub(crate) async fn run(
args: GetRoomStatesArgs,
) -> Result<(), error::DumpStateCommand> {
use error::DumpStateCommand as Error;
let config = config::load(args.config.config.as_ref()).await?;
let db = Box::leak(Box::new(
KeyValueDatabase::load_or_create(&config).map_err(Error::Database)?,
));
Services::new(db, config, None)
.map_err(Error::InitializeServices)?
.install();
services().globals.err_if_server_name_changed()?;
db.apply_migrations().await.map_err(Error::Database)?;
let room_states = if args.recompute {
recompute::get_room_states(db)
} else {
cache::get_room_states().await
};
serde_json::to_writer(std::io::stdout(), &room_states)?;
Ok(())
}