use std::time::Duration;
use serde::Serialize;
use crate::{
bson::{oid::ObjectId, Document},
error::Error,
serde_util,
};
pub use crate::cmap::ConnectionInfo;
#[derive(Clone, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct CommandStartedEvent {
pub command: Document,
pub db: String,
pub command_name: String,
pub request_id: i32,
pub connection: ConnectionInfo,
pub service_id: Option<ObjectId>,
}
#[derive(Clone, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct CommandSucceededEvent {
pub duration: Duration,
pub reply: Document,
pub command_name: String,
pub request_id: i32,
pub connection: ConnectionInfo,
pub service_id: Option<ObjectId>,
}
#[derive(Clone, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct CommandFailedEvent {
pub duration: Duration,
pub command_name: String,
#[serde(serialize_with = "serde_util::serialize_error_as_string")]
pub failure: Error,
pub request_id: i32,
pub connection: ConnectionInfo,
pub service_id: Option<ObjectId>,
}
pub trait CommandEventHandler: Send + Sync {
fn handle_command_started_event(&self, _event: CommandStartedEvent) {}
fn handle_command_succeeded_event(&self, _event: CommandSucceededEvent) {}
fn handle_command_failed_event(&self, _event: CommandFailedEvent) {}
}
#[derive(Clone, Debug, Serialize)]
#[serde(untagged)]
pub(crate) enum CommandEvent {
Started(CommandStartedEvent),
Succeeded(CommandSucceededEvent),
Failed(CommandFailedEvent),
}
pub(crate) fn handle_command_event(handler: &dyn CommandEventHandler, event: CommandEvent) {
match event {
CommandEvent::Started(event) => handler.handle_command_started_event(event),
CommandEvent::Succeeded(event) => handler.handle_command_succeeded_event(event),
CommandEvent::Failed(event) => handler.handle_command_failed_event(event),
}
}