///|
/// Shard lifecycle state.
pub(all) enum ShardState {
Disconnected(reconnect_attempts~ : Int)
Connecting
Identifying
Resuming
Active
FatallyClosed(code~ : Int)
} derive(Eq, Debug)
///|
/// Action after a gateway close: resume the session, identify from scratch,
/// or give up because reconnecting cannot succeed.
pub(all) enum ReconnectPolicy {
Resume
Reidentify
Fatal
} derive(Eq, Debug)
///|
/// Gateway session state retained across reconnects for RESUME.
pub(all) struct Session {
id : String
resume_url : String
mut sequence : Int64
} derive(Debug)
///|
/// Classify a close code into the action to take, per the Discord docs.
///
/// - fatal: authentication failure or invalid shard/intent configuration —
/// reconnecting cannot succeed;
/// - re-identify: the session is gone (invalid seq, session timeout);
/// - resume: everything else (transient errors, unclean closes), provided a
/// session exists.
pub fn on_close(code : Int?, has_session : Bool) -> ReconnectPolicy {
let policy = match code {
Some(4004)
| Some(4010)
| Some(4011)
| Some(4012)
| Some(4013)
| Some(4014) => ReconnectPolicy::Fatal
Some(4007) | Some(4009) => Reidentify
// normal closure invalidates the session per Discord's resume rules
Some(1000) | Some(1001) => Reidentify
_ => Resume
}
if policy is Resume && !has_session {
Reidentify
} else {
policy
}
}