1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
use async_trait::async_trait;
use std::fmt::Debug;
use std::sync::Arc;
/// An event pertaining to a client's login and logout actions in order to allow detection of the
/// presence of a client. Instances of these will be passed to an [`PresenceListener`](crate::notification::PresenceListener).
/// To identify the corresponding user or session see the [`EventMeta`](crate::notification::EventMeta) struct.
#[derive(Debug, Clone)]
pub enum PresenceEvent {
/// The user logged in successfully
LoggedIn,
/// The user logged out
LoggedOut,
}
/// An event signalling a change in data on the storage back-end. To identify the corresponding user
/// or session see the [`EventMeta`](crate::notification::EventMeta) struct.
#[derive(Debug, Clone)]
pub enum DataEvent {
/// A RETR command finished successfully
Got {
/// The path to the file that was obtained
path: String,
/// The amount of bytes transferred to the client
bytes: u64,
},
/// A STOR command finished successfully
Put {
/// The path to the file that was obtained
path: String,
/// The amount of bytes stored
bytes: u64,
},
/// A DEL command finished successfully
Deleted {
/// The path to the file that was deleted.
path: String,
},
/// A MKD command finished successfully
MadeDir {
/// The path to the directory that was created
path: String,
},
/// A RMD command finished successfully
RemovedDir {
/// The path to the directory that was removed
path: String,
},
/// A RNFR & RNTO command sequence finished successfully. This can be for a file or a directory.
Renamed {
/// The original path
from: String,
/// The new path
to: String,
},
}
/// Metadata relating to an event that can be used to to identify the user and session. A sequence
/// number is also included to allow ordering in systems where event ordering is not guaranteed.
#[derive(Debug, Clone)]
pub struct EventMeta {
/// The user this event pertains to. A user may have more than one connection or session.
pub username: String,
/// Identifies a single session pertaining to a connected client.
pub trace_id: String,
/// The event sequence number as incremented per session.
pub sequence_number: u64,
}
/// An listener for [`DataEvent`](crate::notification::DataEvent)s. Implementations can
/// be passed to [`ServerBuilder::notify_data`](crate::ServerBuilder::notify_data)
/// in order to receive notifications.
#[async_trait]
pub trait DataListener: Sync + Send + Debug {
/// Called after the event happened. Event metadata is also passed to allow pinpointing the user
/// session for which it happened.
async fn receive_data_event(&self, e: DataEvent, m: EventMeta);
}
/// A listener for [`PresenceEvent`](crate::notification::PresenceEvent)s. Implementations can
/// be passed to [`ServerBuilder::notify_presence`](crate::ServerBuilder::notify_presence)
/// in order to receive notifications.
#[async_trait]
pub trait PresenceListener: Sync + Send + Debug {
/// Called after the event happened. Event metadata is also passed to allow pinpointing the user
/// session for which it happened.
async fn receive_presence_event(&self, e: PresenceEvent, m: EventMeta);
}
#[async_trait]
impl DataListener for Box<dyn DataListener> {
async fn receive_data_event(&self, e: DataEvent, m: EventMeta) {
self.as_ref().receive_data_event(e, m).await
}
}
#[async_trait]
impl PresenceListener for Box<dyn PresenceListener> {
async fn receive_presence_event(&self, e: PresenceEvent, m: EventMeta) {
self.as_ref().receive_presence_event(e, m).await
}
}
#[async_trait]
impl DataListener for Arc<dyn DataListener> {
async fn receive_data_event(&self, e: DataEvent, m: EventMeta) {
self.as_ref().receive_data_event(e, m).await
}
}
#[async_trait]
impl PresenceListener for Arc<dyn PresenceListener> {
async fn receive_presence_event(&self, e: PresenceEvent, m: EventMeta) {
self.as_ref().receive_presence_event(e, m).await
}
}