/// Accounting helpers for RFC 2866 start, interim, and stop records.
///|
/// The lifecycle class of an Accounting-Request.
pub enum AccountingEvent {
Start
Interim
Stop
AdministrativeOn
AdministrativeOff
UnknownStatus(Int)
MissingStatus
} derive(Eq, Debug)
///|
pub extend AccountingEvent with Eq::{not_equal, equal}
///|
pub extend AccountingEvent with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub fn accounting_status(packet : Packet) -> Int? {
match packet.attribute(Acct_Status_Type) {
Some(attribute) => attribute.as_integer()
None => None
}
}
///|
/// Classify the status attribute without making callers depend on numeric
/// RFC constants.
pub fn accounting_event(packet : Packet) -> AccountingEvent {
match accounting_status(packet) {
None => MissingStatus
Some(Acct_Start) => Start
Some(Acct_Interim_Update) => Interim
Some(Acct_Stop) => Stop
Some(Acct_On) => AdministrativeOn
Some(Acct_Off) => AdministrativeOff
Some(value) => UnknownStatus(value)
}
}
///|
/// Return a stable session label for logs and accounting adapters.
pub fn accounting_session_label(packet : Packet) -> String {
match accounting_session_id(packet) {
Some(value) if value.length() > 0 => value
_ => ""
}
}
///|
pub fn is_accounting_start(packet : Packet) -> Bool {
accounting_status(packet) == Some(Acct_Start)
}
///|
pub fn is_accounting_stop(packet : Packet) -> Bool {
accounting_status(packet) == Some(Acct_Stop)
}
///|
pub fn is_accounting_interim(packet : Packet) -> Bool {
accounting_status(packet) == Some(Acct_Interim_Update)
}
///|
pub fn accounting_session_id(packet : Packet) -> String? {
match packet.attribute(Acct_Session_Id) {
Some(attribute) => Some(@utf8.decode_lossy(attribute.value))
None => None
}
}
///|
pub fn accounting_counter(packet : Packet, kind : Byte) -> Int {
match packet.attribute(kind) {
Some(attribute) =>
match attribute.as_integer() {
Some(value) => value
None => 0
}
None => 0
}
}
///|
pub fn accounting_octets(packet : Packet) -> Int {
accounting_counter(packet, Acct_Input_Octets) +
accounting_counter(packet, Acct_Output_Octets)
}
///|
pub fn accounting_packets(packet : Packet) -> Int {
accounting_counter(packet, Acct_Input_Packets) +
accounting_counter(packet, Acct_Output_Packets)
}
///|
pub fn make_accounting_start(
identifier : Byte,
authenticator : Bytes,
session_id : String,
) -> Packet {
Packet::new(AccountingRequest, identifier, authenticator)
.with_attribute(Attribute::session_status(Acct_Start))
.with_attribute(Attribute::session_id(session_id))
}
///|
pub fn make_accounting_stop(
identifier : Byte,
authenticator : Bytes,
session_id : String,
input_octets : Int,
output_octets : Int,
) -> Packet {
make_accounting_start(identifier, authenticator, session_id)
.replace_attribute(Acct_Status_Type, Attribute::session_status(Acct_Stop))
.with_attribute(Attribute::integer(Acct_Input_Octets, input_octets))
.with_attribute(Attribute::integer(Acct_Output_Octets, output_octets))
}