From 4832e116fd197e7517f427e394bc271204857d83 Mon Sep 17 00:00:00 2001 From: = <=> Date: Wed, 8 Nov 2023 01:23:02 +0100 Subject: [PATCH] feat: improved casting with cache --- src/events/field.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++ src/events/ifield.rs | 21 +++++++++++- src/events/log.rs | 43 ++++++++++++++++++++++-- 3 files changed, 139 insertions(+), 3 deletions(-) diff --git a/src/events/field.rs b/src/events/field.rs index e9408d3..fae9393 100644 --- a/src/events/field.rs +++ b/src/events/field.rs @@ -312,6 +312,84 @@ impl<'a> TryInto for &'a SiemField { } } +impl From<&'static str> for SiemField { + fn from(v : &'static str) -> SiemField { + SiemField::Text(LogString::Borrowed(v)) + } +} +impl From<&String> for SiemField { + fn from(v : &String) -> SiemField { + SiemField::Text(LogString::Owned(v.to_string())) + } +} +impl From for SiemField { + fn from(v : String) -> SiemField { + SiemField::Text(LogString::Owned(v)) + } +} +impl From for SiemField { + fn from(v : LogString) -> SiemField { + SiemField::Text(v) + } +} +impl From<&LogString> for SiemField { + fn from(v : &LogString) -> SiemField { + SiemField::Text(v.clone()) + } +} + +impl From<&u64> for SiemField { + fn from(v : &u64) -> SiemField { + SiemField::U64(*v) + } +} +impl From for SiemField { + fn from(v : u64) -> SiemField { + SiemField::U64(v) + } +} +impl From<&i64> for SiemField { + fn from(v : &i64) -> SiemField { + SiemField::I64(*v) + } +} +impl From for SiemField { + fn from(v : i64) -> SiemField { + SiemField::I64(v) + } +} + +impl From<&f64> for SiemField { + fn from(v : &f64) -> SiemField { + SiemField::F64(*v) + } +} +impl From for SiemField { + fn from(v : f64) -> SiemField { + SiemField::F64(v) + } +} +impl From for SiemField { + fn from(v : SiemIp) -> SiemField { + SiemField::IP(v) + } +} +impl From<&SiemIp> for SiemField { + fn from(v : &SiemIp) -> SiemField { + SiemField::IP(*v) + } +} +impl From> for SiemField { + fn from(v : Vec) -> SiemField { + SiemField::Array(v) + } +} +impl From<&Vec> for SiemField { + fn from(v : &Vec) -> SiemField { + SiemField::Array(v.clone()) + } +} + #[cfg(test)] mod tests { use crate::prelude::SiemIp; diff --git a/src/events/ifield.rs b/src/events/ifield.rs index 4b7a0c4..64340ee 100644 --- a/src/events/ifield.rs +++ b/src/events/ifield.rs @@ -24,9 +24,28 @@ pub struct InternalField { impl Into for SiemField{ fn into(self) -> InternalField { - InternalField { + let mut ifield = InternalField { original : self, ..Default::default() + }; + match &ifield.original { + SiemField::F64(v) => { + ifield.nf64 = Box::new(PreStoredField::Some(*v)); + }, + SiemField::I64(v) => { + ifield.ni64 = Box::new(PreStoredField::Some(*v)); + }, + SiemField::Date(v) => { + ifield.ni64 = Box::new(PreStoredField::Some(*v)); + }, + SiemField::U64(v) => { + ifield.nu64 = Box::new(PreStoredField::Some(*v)); + }, + SiemField::IP(v) => { + ifield.ip = Box::new(PreStoredField::Some(*v)); + }, + _ => {} } + ifield } } \ No newline at end of file diff --git a/src/events/log.rs b/src/events/log.rs index d082234..2f01fbd 100644 --- a/src/events/log.rs +++ b/src/events/log.rs @@ -272,6 +272,7 @@ impl<'a> SiemLog { fields: &self.fields, } } + /// Obtains the casted value of the field into i64 and caches it pub fn i64_field(&'a mut self, field_name: &str) -> Option { let field = self.fields.get_mut(field_name)?; match field.ni64.as_ref() { @@ -290,7 +291,7 @@ impl<'a> SiemLog { _ => None } } - + /// Obtains the casted value of the field into f64 and caches it pub fn f64_field(&'a mut self, field_name: &str) -> Option { let field = self.fields.get_mut(field_name)?; match field.nf64.as_ref() { @@ -309,6 +310,7 @@ impl<'a> SiemLog { _ => None } } + /// Obtains the casted value of the field into u64 and caches it pub fn u64_field(&'a mut self, field_name: &str) -> Option { let field = self.fields.get_mut(field_name)?; match field.nu64.as_ref() { @@ -327,6 +329,7 @@ impl<'a> SiemLog { _ => None } } + /// Obtains the casted value of the field into IP and caches it pub fn ip_field(&'a mut self, field_name: &str) -> Option { let field = self.fields.get_mut(field_name)?; match field.ip.as_ref() { @@ -345,7 +348,7 @@ impl<'a> SiemLog { _ => None } } - + /// Obtains the casted value of the field into LogString and caches it pub fn txt_field(&'a mut self, field_name: &str) -> Option<&LogString> { let mut has_value = false; @@ -375,6 +378,7 @@ impl<'a> SiemLog { _ => None } } + /// Obtains the casted value of the field into Vec and caches it pub fn array_field(&'a mut self, field_name: &str) -> Option<&Vec> { let mut has_value = false; @@ -475,4 +479,39 @@ mod tests { let val : &str = log.field("event.dataset").unwrap().try_into().unwrap(); assert_eq!("filterlog", val); } + + #[test] + fn casting_between_fields() { + let mut log = SiemLog::new("", 0, ""); + let (name, value) = ("field_1", "value_1"); + log.add_field(name, value.clone().into()); + assert_eq!(value, log.txt_field(name).unwrap()); + + let (name, value) = ("field_1", 100u64); + log.add_field(name, value.clone().into()); + assert_eq!(value as u64, log.u64_field(name).unwrap()); + assert_eq!(value as i64, log.i64_field(name).unwrap()); + assert_eq!(value as f64, log.f64_field(name).unwrap()); + + let (name, value) = ("field_1", -200i64); + log.add_field(name, value.clone().into()); + assert_eq!(value as u64, log.u64_field(name).unwrap()); + assert_eq!(value as i64, log.i64_field(name).unwrap()); + assert_eq!(value as f64, log.f64_field(name).unwrap()); + + let (name, value) = ("field_1", 300.512f64); + log.add_field(name, value.clone().into()); + assert_eq!(value as u64, log.u64_field(name).unwrap()); + assert_eq!(value as i64, log.i64_field(name).unwrap()); + assert_eq!(value as f64, log.f64_field(name).unwrap()); + + let (name, value) = ("field_1", SiemIp::V4(1234)); + log.add_field(name, value.clone().into()); + assert_eq!(value, log.ip_field(name).unwrap()); + + let (name, value) : (&'static str, Vec) = ("field_1", vec!["value_001".into(), "value_002".into()]); + log.add_field(name, value.clone().into()); + assert_eq!(&value, log.array_field(name).unwrap()); + + } }