use crate::error::ErrorStatus;
use crate::value::Value;
use crate::varbind::VarBind;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SetResult {
Ok,
NoAccess,
NotWritable,
WrongType,
WrongLength,
WrongEncoding,
WrongValue,
NoCreation,
InconsistentValue,
ResourceUnavailable,
CommitFailed,
UndoFailed,
InconsistentName,
}
impl SetResult {
pub fn is_ok(&self) -> bool {
matches!(self, SetResult::Ok)
}
pub fn to_error_status(&self) -> ErrorStatus {
match self {
SetResult::Ok => ErrorStatus::NoError,
SetResult::NoAccess => ErrorStatus::NoAccess,
SetResult::NotWritable => ErrorStatus::NotWritable,
SetResult::WrongType => ErrorStatus::WrongType,
SetResult::WrongLength => ErrorStatus::WrongLength,
SetResult::WrongEncoding => ErrorStatus::WrongEncoding,
SetResult::WrongValue => ErrorStatus::WrongValue,
SetResult::NoCreation => ErrorStatus::NoCreation,
SetResult::InconsistentValue => ErrorStatus::InconsistentValue,
SetResult::ResourceUnavailable => ErrorStatus::ResourceUnavailable,
SetResult::CommitFailed => ErrorStatus::CommitFailed,
SetResult::UndoFailed => ErrorStatus::UndoFailed,
SetResult::InconsistentName => ErrorStatus::InconsistentName,
}
}
}
#[derive(Debug, Clone)]
pub struct Response {
pub varbinds: Vec<VarBind>,
pub error_status: ErrorStatus,
pub error_index: i32,
}
impl Response {
pub fn success(varbinds: Vec<VarBind>) -> Self {
Self {
varbinds,
error_status: ErrorStatus::NoError,
error_index: 0,
}
}
pub fn error(error_status: ErrorStatus, error_index: i32, varbinds: Vec<VarBind>) -> Self {
Self {
varbinds,
error_status,
error_index,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum GetResult {
Value(Value),
NoSuchObject,
NoSuchInstance,
}
impl GetResult {
pub fn from_option(value: Option<Value>) -> Self {
match value {
Some(v) => GetResult::Value(v),
None => GetResult::NoSuchObject,
}
}
}
impl From<Value> for GetResult {
fn from(value: Value) -> Self {
GetResult::Value(value)
}
}
impl From<Option<Value>> for GetResult {
fn from(value: Option<Value>) -> Self {
GetResult::from_option(value)
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum GetNextResult {
Value(VarBind),
EndOfMibView,
}
impl GetNextResult {
pub fn from_option(value: Option<VarBind>) -> Self {
match value {
Some(vb) => GetNextResult::Value(vb),
None => GetNextResult::EndOfMibView,
}
}
pub fn is_value(&self) -> bool {
matches!(self, GetNextResult::Value(_))
}
pub fn is_end_of_mib_view(&self) -> bool {
matches!(self, GetNextResult::EndOfMibView)
}
pub fn into_option(self) -> Option<VarBind> {
match self {
GetNextResult::Value(vb) => Some(vb),
GetNextResult::EndOfMibView => None,
}
}
}
impl From<VarBind> for GetNextResult {
fn from(vb: VarBind) -> Self {
GetNextResult::Value(vb)
}
}
impl From<Option<VarBind>> for GetNextResult {
fn from(value: Option<VarBind>) -> Self {
GetNextResult::from_option(value)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::oid;
#[test]
fn test_response_success() {
let response = Response::success(vec![VarBind::new(oid!(1, 3, 6, 1), Value::Integer(1))]);
assert_eq!(response.error_status, ErrorStatus::NoError);
assert_eq!(response.error_index, 0);
assert_eq!(response.varbinds.len(), 1);
}
#[test]
fn test_response_error() {
let response = Response::error(
ErrorStatus::NoSuchName,
1,
vec![VarBind::new(oid!(1, 3, 6, 1), Value::Null)],
);
assert_eq!(response.error_status, ErrorStatus::NoSuchName);
assert_eq!(response.error_index, 1);
}
#[test]
fn test_get_result_from_option() {
let result = GetResult::from_option(Some(Value::Integer(42)));
assert!(matches!(result, GetResult::Value(Value::Integer(42))));
let result = GetResult::from_option(None);
assert!(matches!(result, GetResult::NoSuchObject));
}
#[test]
fn test_get_result_from_value() {
let result: GetResult = Value::Integer(42).into();
assert!(matches!(result, GetResult::Value(Value::Integer(42))));
}
#[test]
fn test_get_next_result_from_option() {
let vb = VarBind::new(oid!(1, 3, 6, 1), Value::Integer(42));
let result = GetNextResult::from_option(Some(vb.clone()));
assert!(result.is_value());
assert_eq!(result.into_option(), Some(vb));
let result = GetNextResult::from_option(None);
assert!(result.is_end_of_mib_view());
assert_eq!(result.into_option(), None);
}
#[test]
fn test_get_next_result_from_varbind() {
let vb = VarBind::new(oid!(1, 3, 6, 1), Value::Integer(42));
let result: GetNextResult = vb.clone().into();
assert!(result.is_value());
if let GetNextResult::Value(inner) = result {
assert_eq!(inner.oid, oid!(1, 3, 6, 1));
}
}
#[test]
fn test_set_result_to_error_status() {
assert_eq!(SetResult::Ok.to_error_status(), ErrorStatus::NoError);
assert_eq!(SetResult::NoAccess.to_error_status(), ErrorStatus::NoAccess);
assert_eq!(
SetResult::NotWritable.to_error_status(),
ErrorStatus::NotWritable
);
assert_eq!(
SetResult::WrongType.to_error_status(),
ErrorStatus::WrongType
);
assert_eq!(
SetResult::CommitFailed.to_error_status(),
ErrorStatus::CommitFailed
);
}
#[test]
fn test_set_result_is_ok() {
assert!(SetResult::Ok.is_ok());
assert!(!SetResult::NoAccess.is_ok());
assert!(!SetResult::NotWritable.is_ok());
}
}