use automerge::{Automerge, transaction::CommitOptions};
use crate::{
ConnectionId, DialerId, DocumentActorId, DocumentId, ListenerId,
actors::{
DocToHubMsg,
hub::{Command, CommandId},
},
io::IoResult,
network::{DialerConfig, ListenerConfig},
};
use super::{DispatchedCommand, HubEventPayload, HubInput, io::HubIoResult};
#[derive(Debug, Clone)]
pub struct HubEvent {
pub(crate) payload: HubEventPayload,
}
impl HubEvent {
pub fn io_complete(result: IoResult<HubIoResult>) -> Self {
HubEvent {
payload: HubEventPayload::IoComplete(result),
}
}
pub fn tick() -> Self {
HubEvent {
payload: HubEventPayload::Input(HubInput::Tick),
}
}
pub fn actor_message(actor_id: DocumentActorId, message: DocToHubMsg) -> Self {
HubEvent {
payload: HubEventPayload::Input(HubInput::ActorMessage {
actor_id,
message: message.0,
}),
}
}
pub fn receive(connection_id: ConnectionId, msg: Vec<u8>) -> DispatchedCommand {
Self::dispatch_command(Command::Receive { connection_id, msg })
}
pub fn actor_ready(document_id: DocumentId) -> DispatchedCommand {
Self::dispatch_command(Command::ActorReady { document_id })
}
pub fn create_document(mut initial_content: Automerge) -> DispatchedCommand {
if initial_content.is_empty() {
initial_content.empty_commit(CommitOptions::default());
}
Self::dispatch_command(Command::CreateDocument {
content: Box::new(initial_content),
})
}
pub fn search_for_doc(document_id: DocumentId) -> DispatchedCommand {
Self::dispatch_command(Command::SearchForDoc { document_id })
}
pub fn connection_lost(connection_id: ConnectionId) -> Self {
HubEvent {
payload: HubEventPayload::Input(HubInput::ConnectionLost { connection_id }),
}
}
pub fn add_dialer(config: DialerConfig) -> DispatchedCommand {
let command_id = CommandId::new();
DispatchedCommand {
command_id,
event: HubEvent {
payload: HubEventPayload::Input(HubInput::AddDialer { command_id, config }),
},
}
}
pub fn add_listener(config: ListenerConfig) -> DispatchedCommand {
let command_id = CommandId::new();
DispatchedCommand {
command_id,
event: HubEvent {
payload: HubEventPayload::Input(HubInput::AddListener { command_id, config }),
},
}
}
pub fn create_dialer_connection(dialer_id: DialerId) -> DispatchedCommand {
let command_id = CommandId::new();
DispatchedCommand {
command_id,
event: HubEvent {
payload: HubEventPayload::Input(HubInput::CreateDialerConnection {
command_id,
dialer_id,
}),
},
}
}
pub fn create_listener_connection(listener_id: ListenerId) -> DispatchedCommand {
let command_id = CommandId::new();
DispatchedCommand {
command_id,
event: HubEvent {
payload: HubEventPayload::Input(HubInput::CreateListenerConnection {
command_id,
listener_id,
}),
},
}
}
pub fn dial_failed(dialer_id: DialerId, error: String) -> HubEvent {
HubEvent {
payload: HubEventPayload::Input(HubInput::DialFailed { dialer_id, error }),
}
}
pub fn remove_dialer(dialer_id: DialerId) -> HubEvent {
HubEvent {
payload: HubEventPayload::Input(HubInput::RemoveDialer { dialer_id }),
}
}
pub fn remove_listener(listener_id: ListenerId) -> HubEvent {
HubEvent {
payload: HubEventPayload::Input(HubInput::RemoveListener { listener_id }),
}
}
pub fn stop() -> HubEvent {
HubEvent {
payload: HubEventPayload::Input(HubInput::Stop),
}
}
fn dispatch_command(command: Command) -> DispatchedCommand {
let command_id = CommandId::new();
DispatchedCommand {
command_id,
event: HubEvent {
payload: HubEventPayload::Input(HubInput::Command {
command_id,
command: Box::new(command),
}),
},
}
}
pub(crate) fn event_type_for_metrics(&self) -> &'static str {
match &self.payload {
HubEventPayload::IoComplete(io_completion) => match &io_completion.payload {
HubIoResult::Send => "io_complete_send",
HubIoResult::Disconnect => "io_complete_disconnect",
},
HubEventPayload::Input(input) => match input {
HubInput::Stop => "stop",
HubInput::Command { command, .. } => match command.as_ref() {
Command::Receive { .. } => "receive",
Command::ActorReady { .. } => "actor_ready",
Command::CreateDocument { .. } => "create_document",
Command::SearchForDoc { .. } => "search_for_doc",
},
HubInput::Tick => "tick",
HubInput::ActorMessage { .. } => "actor_message",
HubInput::ConnectionLost { .. } => "connection_lost",
HubInput::AddDialer { .. } => "add_dialer",
HubInput::AddListener { .. } => "add_listener",
HubInput::CreateDialerConnection { .. } => "create_dialer_connection",
HubInput::CreateListenerConnection { .. } => "create_listener_connection",
HubInput::DialFailed { .. } => "dial_failed",
HubInput::RemoveDialer { .. } => "remove_dialer",
HubInput::RemoveListener { .. } => "remove_listener",
},
}
}
}
impl std::fmt::Display for HubEvent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.payload)
}
}