use std::fmt;
macro_rules! impl_display {
($ty:ident { $($variant:ident => $s:literal),* $(,)? }) => {
impl fmt::Display for $ty {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
$($ty::$variant => $s),*
})
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
pub enum Severity {
Fatal = 0,
Severe = 1,
Error = 2,
Minor = 3,
Style = 4,
Warning = 5,
Info = 6,
}
impl Severity {
pub fn at_least(self, threshold: Severity) -> bool {
self <= threshold
}
}
impl_display!(Severity {
Fatal => "fatal",
Severe => "severe",
Error => "error",
Minor => "minor",
Style => "style",
Warning => "warning",
Info => "info",
});
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum ResolverStrictness {
Strict = 0,
Normal = 1,
Permissive = 2,
}
impl ResolverStrictness {
pub fn allow_constrained_fallbacks(self) -> bool {
self != ResolverStrictness::Strict
}
pub fn allow_global_fallbacks(self) -> bool {
self == ResolverStrictness::Permissive
}
}
impl_display!(ResolverStrictness {
Strict => "strict",
Normal => "normal",
Permissive => "permissive",
});
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum ReportingLevel {
Silent = 0,
Quiet = 1,
Default = 2,
Verbose = 3,
}
impl_display!(ReportingLevel {
Silent => "silent",
Quiet => "quiet",
Default => "default",
Verbose => "verbose",
});
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[repr(u8)]
pub enum Kind {
#[default]
Unknown = 0,
Internal = 1,
Node = 2,
Scalar = 3,
Table = 4,
Row = 5,
Column = 6,
Notification = 7,
Group = 8,
Compliance = 9,
Capability = 10,
ModuleIdentity = 11,
ObjectIdentity = 12,
}
impl Kind {
pub fn is_object_type(self) -> bool {
matches!(self, Kind::Scalar | Kind::Table | Kind::Row | Kind::Column)
}
pub fn is_conformance(self) -> bool {
matches!(self, Kind::Group | Kind::Compliance | Kind::Capability)
}
pub fn is_node_like(self) -> bool {
matches!(
self,
Kind::Node | Kind::ModuleIdentity | Kind::ObjectIdentity
)
}
}
impl_display!(Kind {
Unknown => "unknown",
Internal => "internal",
Node => "node",
Scalar => "scalar",
Table => "table",
Row => "row",
Column => "column",
Notification => "notification",
Group => "group",
Compliance => "compliance",
Capability => "capabilities",
ModuleIdentity => "module-identity",
ObjectIdentity => "object-identity",
});
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[repr(u8)]
pub enum Access {
#[default]
NotAccessible = 0,
AccessibleForNotify = 1,
ReadOnly = 2,
ReadWrite = 3,
ReadCreate = 4,
WriteOnly = 5,
NotImplemented = 6,
}
impl_display!(Access {
NotAccessible => "not-accessible",
AccessibleForNotify => "accessible-for-notify",
ReadOnly => "read-only",
ReadWrite => "read-write",
ReadCreate => "read-create",
WriteOnly => "write-only",
NotImplemented => "not-implemented",
});
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[repr(u8)]
pub enum Status {
#[default]
Current = 0,
Deprecated = 1,
Obsolete = 2,
Mandatory = 3,
Optional = 4,
}
impl Status {
pub fn is_smiv1(self) -> bool {
matches!(self, Status::Mandatory | Status::Optional)
}
}
impl_display!(Status {
Current => "current",
Deprecated => "deprecated",
Obsolete => "obsolete",
Mandatory => "mandatory",
Optional => "optional",
});
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[repr(u8)]
pub enum Language {
#[default]
Unknown = 0,
SMIv1 = 1,
SMIv2 = 2,
SPPI = 3,
}
impl_display!(Language {
Unknown => "unknown",
SMIv1 => "SMIv1",
SMIv2 => "SMIv2",
SPPI => "SPPI",
});
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[repr(u8)]
pub enum BaseType {
#[default]
Unknown = 0,
Integer32 = 1,
Unsigned32 = 2,
Counter32 = 3,
Counter64 = 4,
Gauge32 = 5,
TimeTicks = 6,
IpAddress = 7,
OctetString = 8,
ObjectIdentifier = 9,
Bits = 10,
Opaque = 11,
Sequence = 12,
Integer64 = 13,
Unsigned64 = 14,
}
impl_display!(BaseType {
Unknown => "unknown",
Integer32 => "Integer32",
Unsigned32 => "Unsigned32",
Counter32 => "Counter32",
Counter64 => "Counter64",
Gauge32 => "Gauge32",
TimeTicks => "TimeTicks",
IpAddress => "IpAddress",
OctetString => "OCTET STRING",
ObjectIdentifier => "OBJECT IDENTIFIER",
Bits => "BITS",
Opaque => "Opaque",
Sequence => "SEQUENCE",
Integer64 => "Integer64",
Unsigned64 => "Unsigned64",
});
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[repr(u8)]
pub enum IndexEncoding {
#[default]
Unknown = 0,
Integer = 1,
FixedString = 2,
LengthPrefixed = 3,
Implied = 4,
IpAddress = 5,
}
impl_display!(IndexEncoding {
Unknown => "unknown",
Integer => "integer",
FixedString => "fixed-string",
LengthPrefixed => "length-prefixed",
Implied => "implied",
IpAddress => "ip-address",
});
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[repr(u8)]
pub enum AccessKeyword {
#[default]
Access = 0,
MaxAccess = 1,
MinAccess = 2,
}
impl_display!(AccessKeyword {
Access => "ACCESS",
MaxAccess => "MAX-ACCESS",
MinAccess => "MIN-ACCESS",
});
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn severity_ordering() {
assert!(Severity::Fatal <= Severity::Info);
assert!(Severity::Fatal <= Severity::Fatal);
assert!(Severity::Info > Severity::Fatal);
}
#[test]
fn severity_display() {
assert_eq!(Severity::Fatal.to_string(), "fatal");
assert_eq!(Severity::Info.to_string(), "info");
}
#[test]
fn kind_classification() {
assert!(Kind::Scalar.is_object_type());
assert!(Kind::Table.is_object_type());
assert!(Kind::Row.is_object_type());
assert!(Kind::Column.is_object_type());
assert!(!Kind::Node.is_object_type());
assert!(!Kind::Notification.is_object_type());
assert!(Kind::Group.is_conformance());
assert!(Kind::Compliance.is_conformance());
assert!(Kind::Capability.is_conformance());
assert!(!Kind::Scalar.is_conformance());
}
#[test]
fn status_smiv1() {
assert!(Status::Mandatory.is_smiv1());
assert!(Status::Optional.is_smiv1());
assert!(!Status::Current.is_smiv1());
assert!(!Status::Deprecated.is_smiv1());
}
}