cdx_core/extensions/collaboration/
thread.rs1use serde::{Deserialize, Serialize};
4
5use super::Comment;
6
7#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct CommentThread {
11 pub comments: Vec<Comment>,
13}
14
15impl CommentThread {
16 #[must_use]
18 pub fn new() -> Self {
19 Self {
20 comments: Vec::new(),
21 }
22 }
23
24 pub fn add(&mut self, comment: Comment) {
26 self.comments.push(comment);
27 }
28
29 #[must_use]
31 pub fn get(&self, id: &str) -> Option<&Comment> {
32 Self::find_comment(id, &self.comments)
33 }
34
35 #[must_use]
37 pub fn get_mut(&mut self, id: &str) -> Option<&mut Comment> {
38 self.find_comment_mut(id)
39 }
40
41 #[must_use]
43 pub fn for_block(&self, block_ref: &str) -> Vec<&Comment> {
44 self.comments
45 .iter()
46 .filter(|c| c.block_ref == block_ref)
47 .collect()
48 }
49
50 #[must_use]
52 pub fn unresolved(&self) -> Vec<&Comment> {
53 self.comments.iter().filter(|c| !c.resolved).collect()
54 }
55
56 #[must_use]
58 pub fn resolved(&self) -> Vec<&Comment> {
59 self.comments.iter().filter(|c| c.resolved).collect()
60 }
61
62 #[must_use]
64 pub fn len(&self) -> usize {
65 self.comments.len()
66 }
67
68 #[must_use]
70 pub fn is_empty(&self) -> bool {
71 self.comments.is_empty()
72 }
73
74 fn find_comment<'a>(id: &str, comments: &'a [Comment]) -> Option<&'a Comment> {
76 for comment in comments {
77 if comment.id == id {
78 return Some(comment);
79 }
80 if let Some(found) = Self::find_comment(id, &comment.replies) {
81 return Some(found);
82 }
83 }
84 None
85 }
86
87 fn find_comment_mut(&mut self, id: &str) -> Option<&mut Comment> {
89 self.comments.iter_mut().find(|comment| comment.id == id)
92 }
93}