pub enum Event {
Show 75 variants
MessageSent {
message_id: String,
sender: String,
recipient: String,
content: String,
priority: String,
requires_ack: bool,
timestamp: i64,
lamport_clock: u64,
forward_info: Option<ForwardInfoEvent>,
},
MessageReceived {Show 15 fields
message_id: String,
sender: String,
recipient: String,
content: String,
hop_count: u8,
transport: String,
timestamp: i64,
lamport_clock: u64,
reply_to_msg: Option<String>,
reply_context: Option<Box<ReplyContextEvent>>,
content_type: String,
media_metadata: Option<MediaMetadata>,
forward_info: Option<ForwardInfoEvent>,
encrypted: bool,
app_id: String,
},
MessageDelivered {
message_id: String,
latency_ms: u64,
hop_count: u8,
transport: String,
},
MessageFailed {
message_id: String,
reason: String,
retry_count: u32,
},
MessageDecryptionFailed {
message_id: String,
sender: String,
code: DecryptionFailureCode,
reason: String,
sealed_at_ms: Option<u64>,
session_established_at_ms: Option<u64>,
},
TransportSwitched {
from: Option<String>,
to: String,
reason: String,
},
RelayPromoted {
connection_count: usize,
battery_level: Option<u8>,
},
RelayDemoted {
reason: String,
},
NeighborDiscovered {
peer_id: String,
transport: String,
rssi: Option<i16>,
},
NeighborLost {
peer_id: String,
},
IdentityReady {
address: String,
},
NetworkMetrics {
neighbor_count: usize,
relay_count: usize,
delivery_ratio: f32,
avg_latency_ms: u64,
},
FileProgress {
file_id: String,
chunks_sent: u32,
total_chunks: u32,
percentage: u8,
},
FileReceived {Show 13 fields
file_id: String,
file_name: String,
file_size: u64,
sender: String,
content_type: String,
media_metadata: Option<MediaMetadata>,
file_data: String,
timestamp: Option<i64>,
caption: Option<String>,
reply_to_msg: Option<String>,
reply_context: Option<Box<ReplyContextEvent>>,
forward_info: Option<ForwardInfoEvent>,
app_id: Option<String>,
},
FileReceiveFailed {
file_id: String,
file_name: String,
sender: String,
reason: String,
},
MediaSent {
file_id: String,
content_type: String,
recipient: String,
},
MediaSendFailed {
file_id: String,
recipient: String,
reason: String,
},
MessageDeferred {
message_id: String,
recipient: String,
reason: String,
retry_count: u32,
next_retry_at: Option<i64>,
},
MessageRetrying {
message_id: String,
recipient: String,
retry_count: u32,
next_retry_at: i64,
},
MessageUndeliverable {
message_id: String,
recipient: String,
reason: String,
file_id: Option<String>,
},
MediaResendRequired {
file_id: String,
recipient: String,
file_name: String,
file_size: u64,
app_id: Option<String>,
},
AckEvicted {
message_id: String,
priority: String,
reason: String,
},
FragmentAssemblyEvicted {
message_id: String,
completion_percent: u8,
reason: String,
},
RelayDemotedBattery {
battery_level: u8,
min_required: u8,
},
SecureSessionEstablished {
peer_id: String,
group_id: String,
is_session: bool,
initiated_by_local: bool,
},
SecureSessionFailed {
peer_id: String,
reason: String,
},
ConvergenceDiag {
stage: String,
peer_id: String,
detail: String,
},
WelcomeSendAttempted {
peer_id: String,
message_id: String,
group_id: String,
attempt: u32,
},
WelcomeSendSucceeded {
peer_id: String,
message_id: String,
group_id: String,
attempt: u32,
},
WelcomeSendFailed {
peer_id: String,
message_id: String,
group_id: String,
attempt: u32,
reason_code: WelcomeReasonCode,
transport_error: Option<String>,
retryable: bool,
next_retry_at: Option<i64>,
},
WelcomeSendExpired {
peer_id: String,
message_id: String,
attempt: u32,
reason_code: WelcomeReasonCode,
},
ConnectionRequestReceived {
sender: String,
sender_name: String,
timestamp: i64,
key_package: Option<Vec<u8>>,
initial_message: Option<String>,
},
ConnectionRequestUndeliverable {
recipient: String,
message_id: String,
reason: String,
},
ConnectionAccepted {
accepted_by: String,
accepted_by_name: String,
timestamp: i64,
key_package: Option<Vec<u8>>,
},
ConnectionRejected {
rejected_by: String,
},
ConnectionRequestCancelled {
cancelled_by: String,
},
GroupCreated {
group_id: String,
name: String,
},
GroupMessageReceived {
group_id: String,
sender: String,
content: String,
timestamp: String,
message_id: String,
reply_to_msg: Option<String>,
forward_info: Option<ForwardInfoEvent>,
media_metadata: Option<MediaMetadata>,
content_type: Option<String>,
},
GroupMemberAdded {
group_id: String,
user_id: String,
added_by: String,
group_name: Option<String>,
authorized: Option<bool>,
},
GroupMemberRemoved {
group_id: String,
user_id: String,
removed_by: String,
authorized: Option<bool>,
},
GroupInfo {
group_id: String,
name: String,
created_by: String,
created_at: String,
members: Vec<GroupInfoMember>,
},
UserGroups {
groups: Vec<UserGroupSummary>,
},
GroupError {
reason: String,
group_id: Option<String>,
},
GroupRelaySyncChanged {
group_id: String,
synced: bool,
reason: String,
},
UsernameResolved {
username: String,
claims: Vec<UsernameClaim>,
rejected: u32,
truncated: u32,
},
GroupMessageSent {
group_id: String,
message_ids: Vec<String>,
member_count: u32,
},
GroupMessagePartialFailure {
group_id: String,
failed_members: Vec<String>,
succeeded_members: Vec<String>,
},
GroupMessageDeliveryReport {
group_id: String,
message_id: String,
delivered: Vec<String>,
pushed: Vec<String>,
missed_reissued: Vec<String>,
},
GroupRichExtrasDropped {
group_id: String,
unknown_members: Vec<String>,
},
GroupUnauthorizedMembershipChange {
group_id: String,
committer: String,
added: Vec<String>,
removed: Vec<String>,
reason: String,
enforced: bool,
},
GroupEpochForkDetected {
group_id: String,
local_epoch: Option<u64>,
},
GroupEpochForkResolved {
group_id: String,
resolved_epoch: u64,
failed_members: Vec<String>,
},
GroupRoleChanged {
group_id: String,
user_id: String,
new_role: String,
changed_by: String,
},
GroupRenamed {
group_id: String,
new_name: String,
old_name: Option<String>,
renamed_by: String,
},
ServiceDiscovered {
query_id: String,
service_id: String,
version: String,
provider_peer_id: String,
capabilities: HashMap<String, String>,
hop_count: u8,
},
ServiceRequestReceived {
request_id: String,
service_id: String,
method: String,
body: String,
sender: String,
encrypted: bool,
},
ServiceResponseReceived {
request_id: String,
service_id: String,
status: String,
body: String,
provider_peer_id: String,
encrypted: bool,
},
PresenceUpdated {
peer_id: String,
status: PresenceStatus,
timestamp: i64,
last_seen_ms: Option<i64>,
source: PresenceSource,
},
TypingIndicatorReceived {
sender: String,
conversation_id: String,
is_typing: bool,
timestamp: i64,
},
ReadReceiptReceived {
sender: String,
message_ids: Vec<String>,
timestamp: i64,
},
DorsScoreUpdated {
scores: Vec<(String, f32)>,
},
DorsTransportSelected {
from: Option<String>,
transport: String,
reason_code: DorsReasonCode,
score: f32,
},
DorsTransportSwitched {
from: Option<String>,
to: String,
reason_code: DorsReasonCode,
reason_detail: Option<String>,
},
DorsEscalationTriggered {
phase: DorsEscalationPhase,
from: String,
to: String,
reason_code: DorsEscalationReasonCode,
reason_detail: Option<String>,
},
SecurityWarning {
peer_id: String,
reason_code: SecurityWarningCode,
reason: String,
},
MessageRelayed {
message_id: String,
sender: String,
recipient: String,
hop_count: u8,
remaining_ttl: u8,
},
UserBlocked {
user_id: String,
},
UserUnblocked {
user_id: String,
},
DataChanged {
space_id: String,
doc_id: String,
delta_bytes: u64,
},
DataDocRemoved {
space_id: String,
doc_id: String,
by: DocRemovedBy,
},
DataDocSizeWarning {
space_id: String,
doc_id: String,
compacted_bytes: u64,
cap_bytes: u64,
},
DataAttachmentRequested {
space_id: String,
peer_id: String,
hash: String,
},
DataAttachmentReceived {
space_id: String,
peer_id: String,
hash: String,
data: String,
},
DataAttachmentUnavailable {
space_id: String,
peer_id: String,
hash: String,
reason: String,
},
DataDocUnsyncable {
space_id: String,
doc_id: String,
bytes: u64,
reason: String,
},
}Expand description
Events that can occur in the protocol.
Note: This type implements a custom Debug that redacts sensitive fields (message content) to prevent accidental logging of sensitive data.
Variants§
MessageSent
A message was sent (queued for delivery).
Fields
forward_info: Option<ForwardInfoEvent>Forwarding attribution (present when this is a forwarded message).
MessageReceived
A message was received.
Fields
reply_context: Option<Box<ReplyContextEvent>>Quoted-reply context (present when this message quotes another).
Boxed to keep the Event enum’s by-value size in check.
media_metadata: Option<MediaMetadata>Media metadata (present for non-text content).
forward_info: Option<ForwardInfoEvent>Forwarding attribution (present when this is a forwarded message).
encrypted: booltrue when the content arrived MLS-encrypted and was decrypted by
this node; false for plaintext accepted under the
require_encryption = false opt-out.
app_id: StringApplication id the sender stamped on this message: its configured id, or the per-send id of a rich send.
For an instance serving several local applications, this is what routes the message to the right client. It is cleartext and unsigned on the wire, so any carrier could have rewritten it (threat model R17): route on it, never authorize on it. The engine delivers every message whatever this says.
MessageDelivered
A message was successfully delivered (ACK received).
Fields
MessageFailed
A message failed to deliver.
Fields
MessageDecryptionFailed
An inbound encrypted message failed to decrypt on this attempt.
Advisory, not terminal, and emitted once per failed attempt. While
EncryptionConfig::crypto_recovery_enabled is on (the default) a
message that fails to decrypt is not delivery-ACKed, so the sender keeps
retrying — and each resend of a DM is re-sealed against the peer’s
current session, so a resend can actually land. Every failing attempt
reports again, bounded by the sender’s ACK retry budget. Read this as
“this attempt did not decrypt”; the terminal signals are
Event::MessageFailed on the sender and FileReceiveFailed for
media.
Fields
code: DecryptionFailureCodeMachine-readable decryption failure code.
sealed_at_ms: Option<u64>When the sender sealed the frame (sender clock, ms), read from the
cleartext envelope. Unauthenticated: a hint for local heuristics,
never for security decisions. None when the failure is not a 1:1
decrypt attempt (pending-queue drop, unparseable envelope, group).
session_established_at_ms: Option<u64>When this device’s current session with sender was created or
adopted (local clock, ms). None when there is no session, or it
was established by an SDK that did not record the time. A frame
sealed before this cannot have been sealed under this session, so
its failure says nothing about whether the two sides agree now.
TransportSwitched
Transport was switched by DORS.
Fields
RelayPromoted
This device started acting as a relay — carrying traffic for other devices that cannot reach each other directly.
Reports observed behaviour, not capability: it fires because this device has been forwarding, so it needs no battery feed and can fire on a device that has never reported a level.
Fields
RelayDemoted
This device was demoted from relay role.
NeighborDiscovered
A new neighbor was discovered.
Fields
NeighborLost
A neighbor was lost (disconnected).
IdentityReady
This device’s own address is known: MLS storage was opened and the
identity key in it derived to address.
Fires once per successful initialize_mls, before any frame can be
sent. address is this device’s Message.sender from here on, and what
peers must be given to reach it. It is stable across restarts of the
same profile, so an app that already stored it will be handed the same
value rather than a new one.
NetworkMetrics
Network metrics update.
Fields
FileProgress
File transfer progress update.
Fields
FileReceived
File was completely received.
Fields
media_metadata: Option<MediaMetadata>Media metadata from the first chunk (present for typed media).
timestamp: Option<i64>When the sender queued the transfer (chunk-0 outer message
timestamp, wall-clock ms) — for display ordering alongside
MessageReceived.timestamp. Absent only if the chunk-0 record
was evicted before completion.
reply_context: Option<Box<ReplyContextEvent>>Quoted-reply context (sealed chunk-0 extras). Boxed to keep the
Event enum’s by-value size in check.
forward_info: Option<ForwardInfoEvent>Forwarding attribution (sealed chunk-0 extras).
FileReceiveFailed
An inbound file transfer was dropped before completion — the receiver
hit a resource limit (too many concurrent transfers, per-sender
quota, or the buffered-bytes budget), the reassembled file failed
its integrity checks, or the transfer went stale (no chunks within
the stale timeout). Terminal and fired at most once per transfer:
the failed transfer’s remaining in-flight chunks are dropped
silently. No FileReceived will follow for this file_id; the
sender must re-send the file (under a fresh file_id) to retry.
Fields
MediaSent
All chunks of a media attachment were ACK-delivered.
Fields
MediaSendFailed
An outbound media transfer was aborted before all chunks were
delivered — a chunk failed to encrypt, or a chunk failed terminally
in the outbox. No MediaSent will follow for this file_id; retry
with a new send_media call.
Fields
MessageDeferred
A message was deferred due to network conditions. The message will be retried automatically.
Fields
recipient: StringRecipient’s user ID.
Added when reason stopped rendering the transport error: the
counterparty used to reach apps only inside that prose, which put an
unhashed address on every telemetry record for a routine send
failure. Carried as a field so the scrubber hashes it like any
other actor id.
reason: StringStable classification of the deferral, not a rendered error.
One of a fixed local vocabulary (peer_not_reachable,
transport_not_connected, transport_send_failed, …). Branch on it
if you must, but do not parse it for detail: the underlying error —
which renders the peer — stays in the device log.
MessageRetrying
A retry for a previously deferred/unacked message was scheduled.
Emitted each time the retry machinery re-queues a message after a
failed attempt (transport send error or ACK timeout). Non-terminal:
MessageDelivered or MessageFailed still settles the message.
Fields
MessageUndeliverable
The transport layer reported the recipient unreachable for an in-flight message (e.g. the internet relay’s DeliveryError).
Non-terminal: the message stays in the outbox. A plain DM is
parked — its ACK retry budget stops burning while the peer is
provably offline — and is re-driven on reachability edges (transport
reconnect, peer discovery, presence-online; the SDK adds parked
recipients to the presence watchlist). It settles only via
MessageDelivered or, at outbox-lifetime expiry, MessageFailed.
Media chunks are not parked and keep the normal retry machinery.
May fire multiple times for the same message_id while the
recipient remains offline: a parked DM keeps an escalating
reachability probe on every carrier (15s → 600s cap), and each probe
that reaches the relay while the peer is still offline earns a fresh
verdict and re-emits this event. Apps must treat it as a repeatable
status signal, never as a terminal one. file_id is set when the
message is a chunk of an outbound media transfer.
Fields
reason: StringStable classification of the failure — recipient_unreachable on
the relay-verdict path this event is normally reached by.
The transport’s own wording used to be appended here verbatim, and
on the relay path that wording is written by the relay: unbounded
remote text, shipped beside a recipient the telemetry scrubber
hashes. It is now dropped at the boundary — kept in the device log,
and on the internet path still delivered raw to apps on the
bridges’ diagnostic channel.
MediaResendRequired
An outbound media transfer was in flight when the previous process
died. The SDK persists only the transfer descriptor (never chunk
bytes), so it cannot resume the transfer itself: the app must
re-supply the file bytes via send_media with this file_id —
they are checksum-validated against the original transfer.
Fields
AckEvicted
A pending ACK was evicted due to capacity constraints.
Fields
FragmentAssemblyEvicted
A fragment assembly was evicted to make room for new fragments.
Fields
RelayDemotedBattery
Relay role was demoted due to battery constraints.
Fields
SecureSessionEstablished
A secure MLS session was successfully established.
Fields
SecureSessionFailed
Failed to establish a secure MLS session.
Reports a failed handshake attempt, which is not the same as “the
session with this peer is gone”. One case makes the difference visible:
a Welcome refused for carrying an unprovable identity
(SecurityWarningCode::GroupLeafIdentityUnproven, emitted alongside)
is refused non-destructively, so any session already held with that peer
stays live and usable. Apps must not tear down session state on this
event alone.
reason is diagnostic text and must not be parsed. It carries no
identifier, of this peer or of anyone else: the telemetry scrubber
hashes peer_id and ships reason verbatim, so every arm that fills it
contributes either a fixed string or
MlsError::privacy_safe_reason,
never a rendered error. The full error stays in the device log at the
refusal site. This is a classification, so apps get the failure class
here and must look to the log for the specifics.
ConvergenceDiag
Diagnostic breadcrumb for the 1:1 MLS convergence (Welcome receive / adopt / confirm) path. Emitted so the receiver side — which otherwise produces no event until it fully establishes or loudly fails — is observable in Metro. Pure instrumentation; carries no protocol effect.
Fields
WelcomeSendAttempted
Welcome send lifecycle entered attempted state.
Fields
WelcomeSendSucceeded
Welcome send lifecycle reached successful sent state.
Fields
WelcomeSendFailed
Welcome send attempt failed and may be retried.
Fields
reason_code: WelcomeReasonCodeMachine-readable reason code.
transport_error: Option<String>Stable classification of the transport failure, when one was recorded — never the rendered error.
Both feeders named an identifier: the platform-supplied string is
the relay’s own DeliveryError prose, and the locally raised one
renders a transport error that interpolates the peer. peer_id and
group_id beside it are hashed, so either would have undone that.
Classified at the boundary, so the persisted record holds the token
too — and again at each emit as a backstop. The second pass is
unreachable today (every writer overwrites the field before its
emit, so no record restored from an older build can carry raw text
into an event) and kept because the field is persisted and has five
writers: it holds the invariant if one of them ever becomes
conditional.
WelcomeSendExpired
Welcome send lifecycle reached terminal expiry.
Fields
reason_code: WelcomeReasonCodeTerminal machine-readable reason code.
ConnectionRequestReceived
A connection request was received from another user.
Fields
ConnectionRequestUndeliverable
An outbound connection request could not be delivered: the transport
reported the recipient unreachable (e.g. the relay’s DeliveryError
for an offline peer), or the request exhausted its ACK retry budget
(in which case a generic MessageFailed also fires for the same
id). This is a status signal, not proof of permanent failure — the
original request may still be delivered by the retry machinery if
the peer comes back online. Apps typically surface “user is
offline”; a user-initiated resend can therefore arrive alongside the
retried original (the recipient sees the request event again, which
accept/reject flows already tolerate).
Fields
reason: StringFailure reason, drawn from a fixed local vocabulary:
recipient_unreachable on the transport verdict path, or
max_retries_exceeded / outbox_lifetime_exceeded /
outbox_capacity_exceeded on the give-up paths.
The relay’s wording is no longer appended to the first of these —
it is remote-chosen text, and recipient beside it is hashed by
the telemetry scrubber.
ConnectionAccepted
A previously sent connection request was accepted.
Fields
ConnectionRejected
A previously sent connection request was rejected.
ConnectionRequestCancelled
A previously sent connection request was cancelled by the sender.
GroupCreated
A group was created (from relay).
GroupMessageReceived
A message was received in a group (from relay).
Fields
forward_info: Option<ForwardInfoEvent>Forwarding attribution (present when this is a forwarded message).
media_metadata: Option<MediaMetadata>Media metadata restored from the sealed __RICH_V1__ body of a
rich group message (cloud attachments — including the
encryption_key/iv secrets, which only ever travel inside the
group MLS ciphertext). Absent on plain group messages.
GroupMemberAdded
A member was added to a group (from relay).
Fields
Whether added_by was authorized to make this change.
Some(false) means the change did happen — MLS accepted the
commit and the roster really has changed — but the committer was
not a known admin. The membership event is still emitted because
the local roster must not diverge from MLS state; see
Event::GroupUnauthorizedMembershipChange for the full signal.
None (absent in JSON) means authorization was not evaluated
on the path that produced this event: our own join accepted from
a Welcome (there is no prior group state to judge the inviter
against) and relay reconciliation frames (no authenticated
committer to judge). Events from an older core also omit the
field. Only Some(_) is a positive statement either way.
The judgment is made against this member’s local replica of
role state, which replicates best-effort and can lag — a
legitimate change may be flagged Some(false), and different
members can disagree about the same commit. Do not act on it
automatically.
GroupMemberRemoved
A member was removed from a group (from relay).
Fields
Whether this change was authorized (None = not evaluated on
this path). See Event::GroupMemberAdded::authorized. On the
relay reconciliation path the judgment applies to the frame’s
authenticated wire sender, which is not necessarily the
removed_by named here.
GroupInfo
Group info was received (from relay).
Fields
members: Vec<GroupInfoMember>Group member list.
UserGroups
User’s groups list was received (from relay).
Fields
groups: Vec<UserGroupSummary>List of group summaries.
GroupError
A group operation failed (from relay).
The relay’s own wording is not carried here. __GROUP_ERROR__ is
a relay answer, accepted unsigned on the relay ingest path (the
bridges inject it unattributed), so its text is chosen by whoever put
the frame on that socket — arbitrary content, arbitrary length, and
not something this SDK can vouch for. reason is a fixed code
classified locally instead; the
relay’s exact text is logged on-device and reaches apps, when they
want it, as the raw GroupError frame the bridges dual-emit on the
server-message channel.
Fields
GroupRelaySyncChanged
The relay-side registration state of a group changed.
synced: true fires only on the relay’s positive registration
acknowledgment (a GroupCreated answering a registration this
device actually sent, over the Internet transport) — including the
idempotent re-sync ack after a membership change. It is the signal
that relay-dependent server commands for the group (invite links,
server-side fan-out) can be issued. synced: false fires when that
trust is revoked; reason says why. Not emitted for groups the
relay was never asked about.
Fields
synced: boolWhether the relay currently holds a positively acknowledged registration for this group.
reason: StringWhy the state changed: registered (relay ack), error
(group-scoped relay error), removed (we were removed from the
group), left (local leave), internet_dropped (Internet
transport lost; re-registration re-arms on reconnect), or
ack_timeout (relay never answered the registration — likely a
relay without group support).
UsernameResolved
A username resolution finished, carrying every claim found.
§The set is the whole point, and there is deliberately no “best” claim
Anyone may publish any username claim, so a name resolves to a set of assertions, never to an answer. Even a single-device user is a set of one. This event is emitted exactly once per resolution and carries the complete set precisely so an app cannot accidentally treat the first arrival as the winner: there is no per-claim event to race, and no ordering field to mistake for a ranking.
An app MUST let the user choose. Silently picking one claim converts a non-authoritative directory into an authoritative-looking one, which is worse than not shipping the feature: the user believes they are talking to the name, and the protocol only ever promised them a key. Present the claims, let a human confirm out of band (a QR code, a shared secret, a voice), and remember the address rather than the name.
An empty claims list is an ordinary outcome: the name may be
unclaimed, the claimant offline-published to relays we do not use, or
every claim we saw failed verification.
Fields
claims: Vec<UsernameClaim>Every claim that verified, in no meaningful order.
rejected: u32How many records were seen but rejected.
Non-zero is normal, not an error: the tag is public, anyone may publish to it, and junk arrives. Surfaced because a resolution that returns nothing while rejecting many records means something different from one that returns nothing having seen nothing, and an app showing “not found” may want to distinguish them.
truncated: u32How many verified claims were dropped at the accumulator’s ceiling.
Separate from rejected because it is the opposite statement: these
records were good and are missing anyway. Without it a crowded name
renders exactly like an uncrowded one, a clean set with nothing
refused, which hides the single signal that a name is being
squatted at volume. Non-zero means claims is a sample and no
absence in it can be trusted.
GroupMessageSent
A group message was sent to all members via mesh (MLS-encrypted fan-out).
Fields
GroupMessagePartialFailure
A group message was only partially delivered (some members failed).
Fields
GroupMessageDeliveryReport
The relay’s settled per-recipient delivery report for a group message sent via relay broadcast, after the SDK acted on it.
Fires once per broadcast whose report arrived, seconds after
group_message_sent (the relay reports only when its whole fan-out
has settled — correlate by message_id, never by order). Members in
delivered took the message over a live relay socket; members in
pushed took a device push carrying the ciphertext. Every other
MLS roster member — the ones the relay reported missed and the
ones it did not know about at all — has already been re-sent a
per-member copy through the ordinary outbox/ACK/park delivery
ladder (missed_reissued), so no app action is required; the event
is delivery observability, not a failure signal. Not emitted when
the report itself is lost — the SDK then re-broadcasts (bounded)
and finally downgrades the whole message to per-member fan-out,
which reports per-member like any mesh send.
Fields
GroupRichExtrasDropped
Rich media metadata was dropped from an outbound group message because the group is not fully rich-capable (not every member advertised sealed rich payload support, or the local kill switch disabled it). The text was still sent; members receive it without the media attachment. Apps can use this to warn the sender that an attachment did not go through.
Fields
unknown_members: Vec<String>Members not known to parse the sealed rich payload — the ones
holding the seal gate closed. Absence of knowledge and known
non-support are indistinguishable here. Empty when the drop was
caused by the local rich_payload_enabled kill switch instead.
The SDK probes these members for their capability automatically;
apps can retry the send once a later attempt stops dropping.
An MLS membership change was applied that its committer was not authorized to make.
The change has been applied — MLS authenticated the committer as a group member and accepted the commit, and the local epoch advanced with it. The SDK’s admin model is an application-layer overlay on top of MLS (RFC 9420 leaves membership access control to the application), enforced on the sending side; refusing the change on receipt would mean refusing the merge, which permanently forks this member away from every peer that accepted it. So the change stands and is reported here instead.
This signal can false-positive. “Unauthorized” is judged against this member’s local replica of role state, which replicates best-effort (a joiner receives a point-in-time snapshot, role changes ride unreconciled mesh notifications) and can lag — so a legitimate change, e.g. a voluntary leave committed by a member whose admin role this device has not yet learned, may be reported here, and different members can disagree about the same commit.
Apps should treat this as a moderation signal for a human admin: an
admin can undo the change with remove_from_group /
invite_to_group. Never reverse a change automatically off a single
member’s event — corroborate first. A member added this way can read
all subsequent group traffic until removed.
Reports are rate-limited per (group, committer): a repeat within a
short window is not re-emitted (divergent role metadata would
otherwise re-fire it on every commit), but every affected
Event::GroupMemberAdded / Event::GroupMemberRemoved still
carries authorized: Some(false).
Known limitation: the member removed by an unauthorized Remove does not receive this event — it can no longer decrypt the commit that removed it, and it refuses to trust a non-admin’s unencrypted claim that it was removed. Only the remaining members report the removal.
Fields
MLS group identifier.
The MLS-authenticated committer that made the change.
Members the commit added, sorted. Empty for a pure removal.
Members the commit removed, sorted. Empty for a pure addition.
Why the change was judged unauthorized. Currently
"sender_not_admin" (the committer is not a known admin) or
"affected_member_mismatch" (an admin committed, but the commit’s
unencrypted framing named a different member than the MLS delta
actually changed). Treat as an opaque string — values may be added.
Whether the commit was refused rather than applied.
false (the default configuration) means the membership change
happened and is being reported after the fact — added/removed
describe real roster changes an admin can undo. true means
GroupConfig::enforce_admin_commits was on and the commit was
rejected before merging: no roster event accompanies this one, no
membership changed locally, and added/removed describe what the
commit would have done.
A true here also means this device declined an epoch every
accepting member advanced to, so it can no longer decrypt that
group’s traffic and needs re-inviting — treat it as a partition
alarm, not just a moderation signal. Note the re-invite arrives as
a Welcome, which is not policy-gated, so it readmits us to the
group including whatever the refused commit did; the change
itself still has to be resolved separately.
GroupEpochForkDetected
An epoch fork was detected in a group — concurrent commits caused members to diverge onto different MLS branches. The deterministic leader will attempt automatic resolution via a key-update commit.
Fields
GroupEpochForkResolved
An epoch fork was successfully resolved by the leader issuing a resync commit that re-established a canonical epoch.
Members in failed_members could not be reached with the resolution
commit and may still be on a forked branch — the application layer
should consider re-inviting them.
Fields
GroupRoleChanged
A member’s role was changed in a group.
Fields
GroupRenamed
A group was renamed.
Fields
ServiceDiscovered
A service was discovered on the mesh in response to a discovery query.
Fields
ServiceRequestReceived
A service request was received from another peer.
Fields
ServiceResponseReceived
A response to a service request was received.
Fields
PresenceUpdated
A peer’s presence status was updated.
Fields
status: PresenceStatusPresence status.
last_seen_ms: Option<i64>When the peer was last seen (Unix ms), if the source knows it —
e.g. the internet relay’s PresenceStatusWithLastSeen. Absent for
peer-sent __PRESENCE__ updates.
source: PresenceSourceWhich channel produced this update: the internet relay’s
authoritative answer, or a peer-sent self-report. Always
serialized; defaults to peer when deserializing legacy events.
TypingIndicatorReceived
A typing indicator was received from a peer.
Fields
ReadReceiptReceived
A read receipt was received from a peer.
Fields
DorsScoreUpdated
DORS scored all available transports for this decision cycle.
DorsTransportSelected
DORS selected a transport for the current message.
Fields
reason_code: DorsReasonCodeTyped reason for selection (initial vs primary selected).
DorsTransportSwitched
DORS switched from one transport to another. Emitted only when active transport actually changes after a successful send.
Fields
reason_code: DorsReasonCodeStable enum-backed reason for the transition.
DorsEscalationTriggered
DORS escalation from BLE to Wi‑Fi. Use phase to distinguish recommendation vs applied.
Fields
phase: DorsEscalationPhaseTRIGGERED = DORS decided to escalate (reason = trigger); APPLIED = fallback succeeded.
reason_code: DorsEscalationReasonCodeStable enum-backed reason code.
SecurityWarning
A security-relevant anomaly was detected (e.g. sender spoofing, a signing key that does not derive to its claimed address, an unsigned control message).
Fields
reason_code: SecurityWarningCodeStable machine-readable classification of the warning. Branch on
this rather than parsing reason.
MessageRelayed
A message was relayed (forwarded for a third party).
Fields
UserBlocked
A user was blocked. Emitted for local UI notification only.
UserUnblocked
A user was unblocked. Emitted for local UI notification only.
DataChanged
A replicated document changed and the change reached storage.
Emitted after the delta is durable, never before: an application that re-renders on this event is then rendering state that survives a crash.
Fields
DataDocRemoved
A replicated document was removed from every replica of its space.
Distinct from a document merely disappearing locally: this one is a decision that travels. It fires when this device removes a document and when it learns of a removal from a peer, so an application holding the document open can close it either way.
A removal loses to a concurrent edit, so a document may come back
after this fires. That arrives as an ordinary DataChanged on a
document the application thought was gone, which is the honest
report: the edit won, and its contents are the contents.
Fields
by: DocRemovedByWho removed it: local for this device, peer for a removal
learned from the space.
DataDocSizeWarning
A replicated document is approaching the per-document size cap.
Fires while there is still room to act. Without it the cap would be a cliff an application meets for the first time as a failed write.
Fields
DataAttachmentRequested
A peer asked for the bytes behind an attachment reference.
The SDK does not hold blob bytes, so it cannot answer this on its
own: the application either supplies them with
data_provide_attachment or says it cannot with
data_decline_attachment. An application that handles neither leaves
the asking peer with a reference it can see and never open, which is
why declining is a first-class answer rather than silence.
Fields
DataAttachmentReceived
Attachment bytes arrived and matched the hash that asked for them.
The bytes are handed over rather than stored: blobs never enter protocol state, so where this file lives is the application’s decision and its storage.
Fields
A fetch ended without bytes.
Either the peer answered that it no longer holds the blob, or the transfer carrying it failed. Both are ordinary: an attachment reference outlives the bytes it names, because the reference replicates and the bytes do not.
DataDocUnsyncable
A document cannot be replicated, in any form this protocol has.
The honest report of a real dead end rather than a warning in a log nobody reads. It fires when a document is too large for a sync frame and the peer cannot carry it over the media path either, which leaves two replicas that will not converge and no further rung to try.
Implementations§
Source§impl Event
impl Event
Sourcepub fn message_sent(message: &Message) -> Self
pub fn message_sent(message: &Message) -> Self
Creates a MessageSent event.
Sourcepub fn message_delivered(
message_id: MessageId,
latency_ms: u64,
hop_count: u8,
transport: TransportType,
) -> Self
pub fn message_delivered( message_id: MessageId, latency_ms: u64, hop_count: u8, transport: TransportType, ) -> Self
Creates a MessageDelivered event.
Sourcepub fn message_failed(
message_id: MessageId,
reason: &'static str,
retry_count: u32,
) -> Self
pub fn message_failed( message_id: MessageId, reason: &'static str, retry_count: u32, ) -> Self
Creates a MessageFailed event.
reason is &'static str for the same load-bearing reason
Event::message_deferred is, and
protocol::types::classify_transport_send_error returns one: the
telemetry pipe forwards this field to the ingest verbatim, without the
scrubber, because the classification taxonomy is the ingest’s. A
String parameter makes format!("{err}") at a call site
representable, and the transport layer renders the counterparty into
its own error text, so that one interpolation would ship a peer
address beside identifiers the same record hashes. A static string
cannot carry runtime data, which makes the mistake unrepresentable
rather than merely discouraged. Callers with a classified failure pass
the token; callers with a fixed condition pass its literal.
Sourcepub fn message_decryption_failed(
message_id: MessageId,
sender: String,
code: DecryptionFailureCode,
reason: String,
) -> Self
pub fn message_decryption_failed( message_id: MessageId, sender: String, code: DecryptionFailureCode, reason: String, ) -> Self
Creates a MessageDecryptionFailed event.
Sourcepub fn message_decryption_failed_for_frame(
message_id: MessageId,
sender: String,
code: DecryptionFailureCode,
reason: String,
sealed_at_ms: u64,
session_established_at_ms: Option<u64>,
) -> Self
pub fn message_decryption_failed_for_frame( message_id: MessageId, sender: String, code: DecryptionFailureCode, reason: String, sealed_at_ms: u64, session_established_at_ms: Option<u64>, ) -> Self
Creates a MessageDecryptionFailed event for a failed 1:1 decrypt, carrying the frame’s seal time and the current session’s establishment time (see the variant’s fields).
Sourcepub fn transport_switched(
from: Option<TransportType>,
to: TransportType,
reason: String,
) -> Self
pub fn transport_switched( from: Option<TransportType>, to: TransportType, reason: String, ) -> Self
Creates a TransportSwitched event.
Sourcepub fn relay_promoted(
connection_count: usize,
battery_level: Option<u8>,
) -> Self
pub fn relay_promoted( connection_count: usize, battery_level: Option<u8>, ) -> Self
Creates a RelayPromoted event.
Sourcepub fn relay_demoted(reason: &'static str) -> Self
pub fn relay_demoted(reason: &'static str) -> Self
Creates a RelayDemoted event.
&'static str for the reason given on Event::message_failed: the
telemetry pipe forwards this field raw.
Sourcepub fn neighbor_discovered(
peer_id: String,
transport: TransportType,
rssi: Option<i16>,
) -> Self
pub fn neighbor_discovered( peer_id: String, transport: TransportType, rssi: Option<i16>, ) -> Self
Creates a NeighborDiscovered event.
Sourcepub fn neighbor_lost(peer_id: String) -> Self
pub fn neighbor_lost(peer_id: String) -> Self
Creates a NeighborLost event.
Sourcepub fn identity_ready(address: impl Into<String>) -> Self
pub fn identity_ready(address: impl Into<String>) -> Self
Creates an IdentityReady event.
Sourcepub fn network_metrics(
neighbor_count: usize,
relay_count: usize,
delivery_ratio: f32,
avg_latency_ms: u64,
) -> Self
pub fn network_metrics( neighbor_count: usize, relay_count: usize, delivery_ratio: f32, avg_latency_ms: u64, ) -> Self
Creates a NetworkMetrics event.
Sourcepub fn file_progress(
file_id: String,
chunks_sent: u32,
total_chunks: u32,
) -> Self
pub fn file_progress( file_id: String, chunks_sent: u32, total_chunks: u32, ) -> Self
Creates a FileProgress event.
Sourcepub fn file_received(
file_id: String,
file_name: String,
file_size: u64,
sender: String,
content_type: ContentType,
media_metadata: Option<MediaMetadata>,
file_data: Vec<u8>,
timestamp: Option<i64>,
caption: Option<String>,
reply_to_msg: Option<String>,
reply_context: Option<&ReplyContext>,
forward_info: Option<&ForwardInfo>,
app_id: Option<String>,
) -> Self
pub fn file_received( file_id: String, file_name: String, file_size: u64, sender: String, content_type: ContentType, media_metadata: Option<MediaMetadata>, file_data: Vec<u8>, timestamp: Option<i64>, caption: Option<String>, reply_to_msg: Option<String>, reply_context: Option<&ReplyContext>, forward_info: Option<&ForwardInfo>, app_id: Option<String>, ) -> Self
Creates a FileReceived event.
Sourcepub fn file_receive_failed(
file_id: String,
file_name: String,
sender: String,
reason: String,
) -> Self
pub fn file_receive_failed( file_id: String, file_name: String, sender: String, reason: String, ) -> Self
Creates a FileReceiveFailed event.
Sourcepub fn media_sent(
file_id: String,
content_type: ContentType,
recipient: String,
) -> Self
pub fn media_sent( file_id: String, content_type: ContentType, recipient: String, ) -> Self
Creates a MediaSent event.
Sourcepub fn media_send_failed(
file_id: String,
recipient: String,
reason: String,
) -> Self
pub fn media_send_failed( file_id: String, recipient: String, reason: String, ) -> Self
Creates a MediaSendFailed event.
Sourcepub fn message_deferred(
message_id: MessageId,
recipient: String,
reason: &'static str,
retry_count: u32,
next_retry_at: Option<i64>,
) -> Self
pub fn message_deferred( message_id: MessageId, recipient: String, reason: &'static str, retry_count: u32, next_retry_at: Option<i64>, ) -> Self
Creates a MessageDeferred event.
Sourcepub fn message_retrying(
message_id: MessageId,
recipient: String,
retry_count: u32,
next_retry_at: i64,
) -> Self
pub fn message_retrying( message_id: MessageId, recipient: String, retry_count: u32, next_retry_at: i64, ) -> Self
Creates a MessageRetrying event.
Sourcepub fn message_undeliverable(
message_id: MessageId,
recipient: String,
reason: &'static str,
file_id: Option<String>,
) -> Self
pub fn message_undeliverable( message_id: MessageId, recipient: String, reason: &'static str, file_id: Option<String>, ) -> Self
Creates a MessageUndeliverable event.
Sourcepub fn media_resend_required(
file_id: String,
recipient: String,
file_name: String,
file_size: u64,
app_id: Option<String>,
) -> Self
pub fn media_resend_required( file_id: String, recipient: String, file_name: String, file_size: u64, app_id: Option<String>, ) -> Self
Creates a MediaResendRequired event.
Sourcepub fn ack_evicted(
message_id: MessageId,
priority: &str,
reason: String,
) -> Self
pub fn ack_evicted( message_id: MessageId, priority: &str, reason: String, ) -> Self
Creates an AckEvicted event.
Sourcepub fn fragment_assembly_evicted(
message_id: String,
completion_percent: u8,
reason: String,
) -> Self
pub fn fragment_assembly_evicted( message_id: String, completion_percent: u8, reason: String, ) -> Self
Creates a FragmentAssemblyEvicted event.
Sourcepub fn relay_demoted_battery(battery_level: u8, min_required: u8) -> Self
pub fn relay_demoted_battery(battery_level: u8, min_required: u8) -> Self
Creates a RelayDemotedBattery event.
Sourcepub fn secure_session_established(
peer_id: String,
group_id: String,
is_session: bool,
initiated_by_local: bool,
) -> Self
pub fn secure_session_established( peer_id: String, group_id: String, is_session: bool, initiated_by_local: bool, ) -> Self
Creates a SecureSessionEstablished event.
Sourcepub fn secure_session_failed(peer_id: String, reason: String) -> Self
pub fn secure_session_failed(peer_id: String, reason: String) -> Self
Creates a SecureSessionFailed event.
Sourcepub fn convergence_diag(stage: String, peer_id: String, detail: String) -> Self
pub fn convergence_diag(stage: String, peer_id: String, detail: String) -> Self
Creates a ConvergenceDiag event (1:1 MLS convergence instrumentation).
Sourcepub fn welcome_send_attempted(
peer_id: String,
message_id: String,
group_id: String,
attempt: u32,
) -> Self
pub fn welcome_send_attempted( peer_id: String, message_id: String, group_id: String, attempt: u32, ) -> Self
Creates a WelcomeSendAttempted event.
Sourcepub fn welcome_send_succeeded(
peer_id: String,
message_id: String,
group_id: String,
attempt: u32,
) -> Self
pub fn welcome_send_succeeded( peer_id: String, message_id: String, group_id: String, attempt: u32, ) -> Self
Creates a WelcomeSendSucceeded event.
Sourcepub fn welcome_send_failed(
peer_id: String,
message_id: String,
group_id: String,
attempt: u32,
reason_code: WelcomeReasonCode,
transport_error: Option<&'static str>,
retryable: bool,
next_retry_at: Option<i64>,
) -> Self
pub fn welcome_send_failed( peer_id: String, message_id: String, group_id: String, attempt: u32, reason_code: WelcomeReasonCode, transport_error: Option<&'static str>, retryable: bool, next_retry_at: Option<i64>, ) -> Self
Creates a WelcomeSendFailed event.
Sourcepub fn welcome_send_expired(
peer_id: String,
message_id: String,
attempt: u32,
reason_code: WelcomeReasonCode,
) -> Self
pub fn welcome_send_expired( peer_id: String, message_id: String, attempt: u32, reason_code: WelcomeReasonCode, ) -> Self
Creates a WelcomeSendExpired event.
Sourcepub fn connection_request_received(
sender: String,
sender_name: String,
timestamp: i64,
key_package: Option<Vec<u8>>,
initial_message: Option<String>,
) -> Self
pub fn connection_request_received( sender: String, sender_name: String, timestamp: i64, key_package: Option<Vec<u8>>, initial_message: Option<String>, ) -> Self
Creates a ConnectionRequestReceived event.
Sourcepub fn connection_request_undeliverable(
recipient: String,
message_id: String,
reason: &'static str,
) -> Self
pub fn connection_request_undeliverable( recipient: String, message_id: String, reason: &'static str, ) -> Self
Creates a ConnectionRequestUndeliverable event.
Sourcepub fn connection_accepted(
accepted_by: String,
accepted_by_name: String,
timestamp: i64,
key_package: Option<Vec<u8>>,
) -> Self
pub fn connection_accepted( accepted_by: String, accepted_by_name: String, timestamp: i64, key_package: Option<Vec<u8>>, ) -> Self
Creates a ConnectionAccepted event.
Sourcepub fn connection_rejected(rejected_by: String) -> Self
pub fn connection_rejected(rejected_by: String) -> Self
Creates a ConnectionRejected event.
Sourcepub fn connection_request_cancelled(cancelled_by: String) -> Self
pub fn connection_request_cancelled(cancelled_by: String) -> Self
Creates a ConnectionRequestCancelled event.
Sourcepub fn presence_updated(
peer_id: String,
status: PresenceStatus,
timestamp: i64,
) -> Self
pub fn presence_updated( peer_id: String, status: PresenceStatus, timestamp: i64, ) -> Self
Creates a PresenceUpdated event for a peer-sent __PRESENCE__
self-report (source: peer).
Sourcepub fn presence_updated_with_last_seen(
peer_id: String,
status: PresenceStatus,
timestamp: i64,
last_seen_ms: Option<i64>,
) -> Self
pub fn presence_updated_with_last_seen( peer_id: String, status: PresenceStatus, timestamp: i64, last_seen_ms: Option<i64>, ) -> Self
Creates a PresenceUpdated event carrying a last-seen timestamp
(relay-sourced presence, source: internet).
Sourcepub fn presence_updated_from(
peer_id: String,
status: PresenceStatus,
timestamp: i64,
last_seen_ms: Option<i64>,
source: PresenceSource,
) -> Self
pub fn presence_updated_from( peer_id: String, status: PresenceStatus, timestamp: i64, last_seen_ms: Option<i64>, source: PresenceSource, ) -> Self
Creates a PresenceUpdated event for a gateway answer, naming which carrier answered.
The relay is one gateway among others now, so the source is a
parameter rather than a constant. It is still not free-form: a
peer-sent self-report goes through Self::presence_updated, which
is the only way to produce PresenceSource::Peer, so a carrier answer
can never be mislabelled as one.
Sourcepub fn typing_indicator_received(
sender: String,
conversation_id: String,
is_typing: bool,
timestamp: i64,
) -> Self
pub fn typing_indicator_received( sender: String, conversation_id: String, is_typing: bool, timestamp: i64, ) -> Self
Creates a TypingIndicatorReceived event.
Sourcepub fn read_receipt_received(
sender: String,
message_ids: Vec<String>,
timestamp: i64,
) -> Self
pub fn read_receipt_received( sender: String, message_ids: Vec<String>, timestamp: i64, ) -> Self
Creates a ReadReceiptReceived event.
Sourcepub fn group_created(group_id: String, name: String) -> Self
pub fn group_created(group_id: String, name: String) -> Self
Creates a GroupCreated event.
Sourcepub fn group_message_received(
group_id: String,
sender: String,
content: String,
timestamp: String,
message_id: String,
reply_to_msg: Option<String>,
forward_info: Option<ForwardInfoEvent>,
media_metadata: Option<MediaMetadata>,
content_type: Option<String>,
) -> Self
pub fn group_message_received( group_id: String, sender: String, content: String, timestamp: String, message_id: String, reply_to_msg: Option<String>, forward_info: Option<ForwardInfoEvent>, media_metadata: Option<MediaMetadata>, content_type: Option<String>, ) -> Self
Creates a GroupMessageReceived event.
Sourcepub fn group_member_added(
group_id: String,
user_id: String,
added_by: String,
group_name: Option<String>,
authorized: Option<bool>,
) -> Self
pub fn group_member_added( group_id: String, user_id: String, added_by: String, group_name: Option<String>, authorized: Option<bool>, ) -> Self
Creates a GroupMemberAdded event.
Sourcepub fn group_member_removed(
group_id: String,
user_id: String,
removed_by: String,
authorized: Option<bool>,
) -> Self
pub fn group_member_removed( group_id: String, user_id: String, removed_by: String, authorized: Option<bool>, ) -> Self
Creates a GroupMemberRemoved event.
Sourcepub fn group_role_changed(
group_id: String,
user_id: String,
new_role: String,
changed_by: String,
) -> Self
pub fn group_role_changed( group_id: String, user_id: String, new_role: String, changed_by: String, ) -> Self
Creates a GroupRoleChanged event.
Sourcepub fn group_renamed(
group_id: String,
new_name: String,
old_name: Option<String>,
renamed_by: String,
) -> Self
pub fn group_renamed( group_id: String, new_name: String, old_name: Option<String>, renamed_by: String, ) -> Self
Creates a GroupRenamed event.
Sourcepub fn group_info(
group_id: String,
name: String,
created_by: String,
created_at: String,
members: Vec<GroupInfoMember>,
) -> Self
pub fn group_info( group_id: String, name: String, created_by: String, created_at: String, members: Vec<GroupInfoMember>, ) -> Self
Creates a GroupInfo event.
Sourcepub fn user_groups(groups: Vec<UserGroupSummary>) -> Self
pub fn user_groups(groups: Vec<UserGroupSummary>) -> Self
Creates a UserGroups event.
Sourcepub fn group_error(reason: String, group_id: Option<String>) -> Self
pub fn group_error(reason: String, group_id: Option<String>) -> Self
Creates a GroupError event.
reason must be a locally-minted code, never relay text — callers on
the wire path get theirs from GroupErrorPayload::classify_reason.
Sourcepub fn group_relay_sync_changed(
group_id: String,
synced: bool,
reason: &str,
) -> Self
pub fn group_relay_sync_changed( group_id: String, synced: bool, reason: &str, ) -> Self
Creates a GroupRelaySyncChanged event.
Sourcepub fn group_message_sent(
group_id: String,
message_ids: Vec<String>,
member_count: u32,
) -> Self
pub fn group_message_sent( group_id: String, message_ids: Vec<String>, member_count: u32, ) -> Self
Creates a GroupMessageSent event.
Sourcepub fn group_message_partial_failure(
group_id: String,
failed_members: Vec<String>,
succeeded_members: Vec<String>,
) -> Self
pub fn group_message_partial_failure( group_id: String, failed_members: Vec<String>, succeeded_members: Vec<String>, ) -> Self
Creates a GroupMessagePartialFailure event.
Sourcepub fn group_message_delivery_report(
group_id: String,
message_id: String,
delivered: Vec<String>,
pushed: Vec<String>,
missed_reissued: Vec<String>,
) -> Self
pub fn group_message_delivery_report( group_id: String, message_id: String, delivered: Vec<String>, pushed: Vec<String>, missed_reissued: Vec<String>, ) -> Self
Creates a GroupMessageDeliveryReport event.
Sourcepub fn group_rich_extras_dropped(
group_id: String,
unknown_members: Vec<String>,
) -> Self
pub fn group_rich_extras_dropped( group_id: String, unknown_members: Vec<String>, ) -> Self
Creates a GroupRichExtrasDropped event.
Creates a GroupUnauthorizedMembershipChange event.
Sourcepub fn group_epoch_fork_detected(
group_id: String,
local_epoch: Option<u64>,
) -> Self
pub fn group_epoch_fork_detected( group_id: String, local_epoch: Option<u64>, ) -> Self
Creates a GroupEpochForkDetected event.
Sourcepub fn group_epoch_fork_resolved(
group_id: String,
resolved_epoch: u64,
failed_members: Vec<String>,
) -> Self
pub fn group_epoch_fork_resolved( group_id: String, resolved_epoch: u64, failed_members: Vec<String>, ) -> Self
Creates a GroupEpochForkResolved event.
Sourcepub fn service_discovered(
query_id: String,
service_id: String,
version: String,
provider_peer_id: String,
capabilities: HashMap<String, String>,
hop_count: u8,
) -> Self
pub fn service_discovered( query_id: String, service_id: String, version: String, provider_peer_id: String, capabilities: HashMap<String, String>, hop_count: u8, ) -> Self
Creates a ServiceDiscovered event.
Sourcepub fn service_request_received(
request_id: String,
service_id: String,
method: String,
body: String,
sender: String,
) -> Self
pub fn service_request_received( request_id: String, service_id: String, method: String, body: String, sender: String, ) -> Self
Creates a ServiceRequestReceived event for a request that arrived as
signed plaintext (encrypted: false).
Sourcepub fn service_response_received(
request_id: String,
service_id: String,
status: String,
body: String,
provider_peer_id: String,
) -> Self
pub fn service_response_received( request_id: String, service_id: String, status: String, body: String, provider_peer_id: String, ) -> Self
Creates a ServiceResponseReceived event for a response that arrived as
signed plaintext (encrypted: false).
Sourcepub fn dors_score_updated(scores: Vec<(String, f32)>) -> Self
pub fn dors_score_updated(scores: Vec<(String, f32)>) -> Self
Creates a DorsScoreUpdated event (DORS observability).
Sourcepub fn dors_transport_selected(
from: Option<String>,
transport: String,
reason_code: DorsReasonCode,
score: f32,
) -> Self
pub fn dors_transport_selected( from: Option<String>, transport: String, reason_code: DorsReasonCode, score: f32, ) -> Self
Creates a DorsTransportSelected event (DORS observability).
Sourcepub fn dors_transport_switched(
from: Option<String>,
to: String,
reason_code: DorsReasonCode,
reason_detail: Option<String>,
) -> Self
pub fn dors_transport_switched( from: Option<String>, to: String, reason_code: DorsReasonCode, reason_detail: Option<String>, ) -> Self
Creates a DorsTransportSwitched event (DORS observability). Emitted only when active transport actually changes after a successful send.
Sourcepub fn dors_escalation_triggered(
phase: DorsEscalationPhase,
from: String,
to: String,
reason_code: DorsEscalationReasonCode,
reason_detail: Option<String>,
) -> Self
pub fn dors_escalation_triggered( phase: DorsEscalationPhase, from: String, to: String, reason_code: DorsEscalationReasonCode, reason_detail: Option<String>, ) -> Self
Creates a DorsEscalationTriggered event (DORS observability). Use phase Triggered at the DORS trigger boundary, Applied when fallback succeeds.
Sourcepub fn security_warning(
peer_id: String,
reason_code: SecurityWarningCode,
reason: String,
) -> Self
pub fn security_warning( peer_id: String, reason_code: SecurityWarningCode, reason: String, ) -> Self
Creates a SecurityWarning event.
Sourcepub fn message_relayed(
message_id: String,
sender: String,
recipient: String,
hop_count: u8,
remaining_ttl: u8,
) -> Self
pub fn message_relayed( message_id: String, sender: String, recipient: String, hop_count: u8, remaining_ttl: u8, ) -> Self
Creates a MessageRelayed event.
Sourcepub fn user_blocked(user_id: String) -> Self
pub fn user_blocked(user_id: String) -> Self
Creates a UserBlocked event.
Sourcepub fn user_unblocked(user_id: String) -> Self
pub fn user_unblocked(user_id: String) -> Self
Creates a UserUnblocked event.
Sourcepub fn telemetry_name(&self) -> &'static str
pub fn telemetry_name(&self) -> &'static str
Returns the stable snake.dot.case telemetry name for this event.
Names are compatible with OpenTelemetry naming conventions and are considered stable across minor versions of the SDK.
Trait Implementations§
Source§impl Debug for Event
Custom Debug implementation that redacts sensitive fields to prevent
accidental logging of message content and other potentially sensitive data.
impl Debug for Event
Custom Debug implementation that redacts sensitive fields to prevent accidental logging of message content and other potentially sensitive data.
Source§impl<'de> Deserialize<'de> for Event
impl<'de> Deserialize<'de> for Event
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl From<ServiceEvent> for Event
impl From<ServiceEvent> for Event
Source§fn from(event: ServiceEvent) -> Self
fn from(event: ServiceEvent) -> Self
Auto Trait Implementations§
impl Freeze for Event
impl RefUnwindSafe for Event
impl Send for Event
impl Sync for Event
impl Unpin for Event
impl UnsafeUnpin for Event
impl UnwindSafe for Event
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Declassify for T
impl<T> Declassify for T
type Declassified = T
fn declassify(self) -> T
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);