diff --git a/Cargo.lock b/Cargo.lock index f18b6ef..3b94289 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -681,6 +681,15 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -765,6 +774,7 @@ dependencies = [ name = "mostr" version = "0.1.0" dependencies = [ + "itertools", "nostr-sdk", "once_cell", "tokio", diff --git a/Cargo.toml b/Cargo.toml index c72055f..91808d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,4 @@ nostr-sdk = "0.30" tokio = { version = "1.0.0", features = ["rt", "rt-multi-thread", "macros"] } once_cell = "1.19.0" xdg = "2.5.2" +itertools = "0.12.1" \ No newline at end of file diff --git a/src/task.rs b/src/task.rs index d3926cc..efdd143 100644 --- a/src/task.rs +++ b/src/task.rs @@ -2,6 +2,8 @@ use std::collections::{BTreeSet, HashSet}; use std::fmt; use std::ops::Div; +use itertools::Either::{Left, Right}; +use itertools::Itertools; use nostr_sdk::{Alphabet, Event, EventBuilder, EventId, Kind, Tag, Timestamp}; use crate::EventSender; @@ -13,18 +15,22 @@ pub(crate) struct Task { pub(crate) props: BTreeSet, /// Cached sorted tags of the event pub(crate) tags: Option>, + parents: Vec, } impl Task { pub(crate) fn new(event: Event) -> Task { + let (parents, tags) = event.tags.iter().partition_map(|tag| { + match tag { + Tag::Event { event_id, .. } => return Left(event_id), + _ => Right(tag.clone()) + } + }); Task { children: Default::default(), props: Default::default(), - tags: if event.tags.is_empty() { - None - } else { - Some(event.tags.iter().cloned().collect()) - }, + tags: Some(tags).filter(|t: &BTreeSet| !t.is_empty()), + parents, event, } } @@ -34,13 +40,7 @@ impl Task { } pub(crate) fn parent_id(&self) -> Option { - for tag in self.event.tags.iter() { - match tag { - Tag::Event { event_id, .. } => return Some(*event_id), - _ => {} - } - } - None + self.parents.first().cloned() } pub(crate) fn get_title(&self) -> String { @@ -127,8 +127,8 @@ impl Task { } total } - - fn filter_tags

(&self, predicate: P) -> Option + + fn filter_tags

(&self, predicate: P) -> Option where P: FnMut(&&Tag) -> bool{ self.tags.as_ref().map(|tags| { tags.into_iter() @@ -147,7 +147,8 @@ impl Task { "name" => Some(self.event.content.clone()), "time" => Some(format!("{}m", self.time_tracked().div(60))), "hashtags" => self.filter_tags(|tag| tag.single_letter_tag().is_some_and(|sltag| sltag.character == Alphabet::T)), - "tags" => self.filter_tags(|tag| !tag.single_letter_tag().is_some_and(|sltag| sltag.character == Alphabet::E)), + "tags" => self.filter_tags(|_| true), + "alltags" => Some(format!("{:?}", self.tags)), "props" => Some(format!( "{:?}", self.props