From d0f57aea2192c49efc89b27a43475cdc39ac3a08 Mon Sep 17 00:00:00 2001 From: Greg Heartsfield Date: Wed, 15 Feb 2023 18:47:27 -0600 Subject: [PATCH] improvement(NIP-40): functions for checking event expiration --- src/event.rs | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/src/event.rs b/src/event.rs index 06be1e2..83640f8 100644 --- a/src/event.rs +++ b/src/event.rs @@ -125,6 +125,19 @@ impl Event { self.kind >= 20000 && self.kind < 30000 } + /// Determine the time at which this event should expire + pub fn expiration(&self) -> Option { + let default = "".to_string(); + let dvals:Vec<&String> = self.tags + .iter() + .filter(|x| !x.is_empty()) + .filter(|x| x.get(0).unwrap() == "expiration") + .map(|x| x.get(1).unwrap_or(&default)).take(1) + .collect(); + let val_first = dvals.get(0); + val_first.and_then(|t| t.parse::().ok()) + } + /// Should this event be replaced with newer timestamps from same author? #[must_use] pub fn is_replaceable(&self) -> bool { self.kind == 0 || self.kind == 3 || self.kind == 41 || (self.kind >= 10000 && self.kind < 20000) @@ -135,8 +148,6 @@ impl Event { self.kind >= 30000 && self.kind < 40000 } - /// What is the replaceable `d` tag value? - /// Should this event be replaced with newer timestamps from same author, for distinct `d` tag values? #[must_use] pub fn distinct_param(&self) -> Option { if self.is_param_replaceable() { @@ -654,4 +665,85 @@ mod tests { assert_eq!(event.distinct_param(), Some("".to_string())); } + #[test] + fn expiring_event_none() { + // regular events do not expire + let mut event = Event::simple_event(); + event.kind = 7; + event.tags = vec![ + vec!["test".to_string(), "foo".to_string()], + ]; + assert_eq!(event.expiration(), None); + } + + #[test] + fn expiring_event_empty() { + // regular events do not expire + let mut event = Event::simple_event(); + event.kind = 7; + event.tags = vec![ + vec!["expiration".to_string()], + ]; + assert_eq!(event.expiration(), None); + } + + #[test] + fn expiring_event_future() { + // a normal expiring event + let exp:u64 = 1676264138; + let mut event = Event::simple_event(); + event.kind = 1; + event.tags = vec![ + vec!["expiration".to_string(), exp.to_string()], + ]; + assert_eq!(event.expiration(), Some(exp)); + } + + #[test] + fn expiring_event_negative() { + // expiration set to a negative value (invalid) + let exp:i64 = -90; + let mut event = Event::simple_event(); + event.kind = 1; + event.tags = vec![ + vec!["expiration".to_string(), exp.to_string()], + ]; + assert_eq!(event.expiration(), None); + } + + #[test] + fn expiring_event_zero() { + // a normal expiring event set to zero + let exp:i64 = 0; + let mut event = Event::simple_event(); + event.kind = 1; + event.tags = vec![ + vec!["expiration".to_string(), exp.to_string()], + ]; + assert_eq!(event.expiration(), Some(0)); + } + + #[test] + fn expiring_event_fraction() { + // expiration is fractional (invalid) + let exp:f64 = 23.334; + let mut event = Event::simple_event(); + event.kind = 1; + event.tags = vec![ + vec!["expiration".to_string(), exp.to_string()], + ]; + assert_eq!(event.expiration(), None); + } + + #[test] + fn expiring_event_multiple() { + // multiple values, we just take the first + let mut event = Event::simple_event(); + event.kind = 1; + event.tags = vec![ + vec!["expiration".to_string(), (10).to_string()], + vec!["expiration".to_string(), (20).to_string()], + ]; + assert_eq!(event.expiration(), Some(10)); + } }