1use chrono::{DateTime, FixedOffset, NaiveDateTime};
2use uuid::Uuid;
3
4use crate::CellReference;
5
6#[derive(Clone, Debug, Eq, PartialEq)]
7pub enum CommentTimestamp {
8 Local(NaiveDateTime),
9 Offset(DateTime<FixedOffset>),
10}
11
12#[derive(Clone, Debug, Eq, PartialEq)]
13pub struct CommentPerson {
14 id: Uuid,
15 display_name: String,
16 user_id: Option<String>,
17 provider_id: Option<String>,
18}
19
20impl CommentPerson {
21 pub(crate) fn new(
22 id: Uuid,
23 display_name: String,
24 user_id: Option<String>,
25 provider_id: Option<String>,
26 ) -> Self {
27 Self { id, display_name, user_id, provider_id }
28 }
29
30 #[must_use]
31 pub const fn id(&self) -> Uuid {
32 self.id
33 }
34
35 #[must_use]
36 pub fn display_name(&self) -> &str {
37 &self.display_name
38 }
39
40 #[must_use]
41 pub fn user_id(&self) -> Option<&str> {
42 self.user_id.as_deref()
43 }
44
45 #[must_use]
46 pub fn provider_id(&self) -> Option<&str> {
47 self.provider_id.as_deref()
48 }
49}
50
51#[derive(Clone, Debug, Eq, PartialEq)]
52pub struct ThreadedCommentReply {
53 id: Uuid,
54 parent_id: Uuid,
55 person_id: Uuid,
56 person: Option<CommentPerson>,
57 created_at: Option<CommentTimestamp>,
58 text: String,
59}
60
61impl ThreadedCommentReply {
62 #[must_use]
63 pub const fn id(&self) -> Uuid {
64 self.id
65 }
66 #[must_use]
67 pub const fn parent_id(&self) -> Uuid {
68 self.parent_id
69 }
70 #[must_use]
71 pub const fn person_id(&self) -> Uuid {
72 self.person_id
73 }
74 #[must_use]
75 pub fn person(&self) -> Option<&CommentPerson> {
76 self.person.as_ref()
77 }
78 #[must_use]
79 pub const fn created_at(&self) -> Option<&CommentTimestamp> {
80 self.created_at.as_ref()
81 }
82 #[must_use]
83 pub fn text(&self) -> &str {
84 &self.text
85 }
86}
87
88#[derive(Clone, Debug, Eq, PartialEq)]
89pub struct ThreadedComment {
90 id: Uuid,
91 cell: CellReference,
92 person_id: Uuid,
93 person: Option<CommentPerson>,
94 created_at: Option<CommentTimestamp>,
95 resolved: bool,
96 text: String,
97 replies: Vec<ThreadedCommentReply>,
98}
99
100impl ThreadedComment {
101 #[must_use]
102 pub const fn id(&self) -> Uuid {
103 self.id
104 }
105 #[must_use]
106 pub const fn cell(&self) -> CellReference {
107 self.cell
108 }
109 #[must_use]
110 pub const fn person_id(&self) -> Uuid {
111 self.person_id
112 }
113 #[must_use]
114 pub fn person(&self) -> Option<&CommentPerson> {
115 self.person.as_ref()
116 }
117 #[must_use]
118 pub const fn created_at(&self) -> Option<&CommentTimestamp> {
119 self.created_at.as_ref()
120 }
121 #[must_use]
122 pub const fn resolved(&self) -> bool {
123 self.resolved
124 }
125 #[must_use]
126 pub fn text(&self) -> &str {
127 &self.text
128 }
129 #[must_use]
130 pub fn replies(&self) -> &[ThreadedCommentReply] {
131 &self.replies
132 }
133}
134
135#[derive(Clone, Debug, Eq, PartialEq)]
136pub struct NoteComment {
137 id: Option<Uuid>,
138 cell: CellReference,
139 author: Option<String>,
140 text: String,
141}
142
143impl NoteComment {
144 #[must_use]
145 pub const fn id(&self) -> Option<Uuid> {
146 self.id
147 }
148 #[must_use]
149 pub const fn cell(&self) -> CellReference {
150 self.cell
151 }
152 #[must_use]
153 pub fn author(&self) -> Option<&str> {
154 self.author.as_deref()
155 }
156 #[must_use]
157 pub fn text(&self) -> &str {
158 &self.text
159 }
160}
161
162#[derive(Clone, Debug, Eq, PartialEq)]
163pub struct SheetComments {
164 sheet_name: String,
165 threaded_comments: Vec<ThreadedComment>,
166 notes: Vec<NoteComment>,
167}
168
169impl SheetComments {
170 pub(crate) fn new(
171 sheet_name: String,
172 threaded_comments: Vec<ThreadedComment>,
173 notes: Vec<NoteComment>,
174 ) -> Self {
175 Self { sheet_name, threaded_comments, notes }
176 }
177
178 #[must_use]
179 pub fn sheet_name(&self) -> &str {
180 &self.sheet_name
181 }
182 #[must_use]
183 pub fn threaded_comments(&self) -> &[ThreadedComment] {
184 &self.threaded_comments
185 }
186 #[must_use]
187 pub fn notes(&self) -> &[NoteComment] {
188 &self.notes
189 }
190}
191
192pub(crate) struct ThreadedCommentParts {
193 pub id: Uuid,
194 pub cell: CellReference,
195 pub person_id: Uuid,
196 pub person: Option<CommentPerson>,
197 pub created_at: Option<CommentTimestamp>,
198 pub resolved: bool,
199 pub text: String,
200 pub replies: Vec<ThreadedCommentReply>,
201}
202
203impl From<ThreadedCommentParts> for ThreadedComment {
204 fn from(parts: ThreadedCommentParts) -> Self {
205 Self {
206 id: parts.id,
207 cell: parts.cell,
208 person_id: parts.person_id,
209 person: parts.person,
210 created_at: parts.created_at,
211 resolved: parts.resolved,
212 text: parts.text,
213 replies: parts.replies,
214 }
215 }
216}
217
218pub(crate) struct ThreadedReplyParts {
219 pub id: Uuid,
220 pub parent_id: Uuid,
221 pub person_id: Uuid,
222 pub person: Option<CommentPerson>,
223 pub created_at: Option<CommentTimestamp>,
224 pub text: String,
225}
226
227impl From<ThreadedReplyParts> for ThreadedCommentReply {
228 fn from(parts: ThreadedReplyParts) -> Self {
229 Self {
230 id: parts.id,
231 parent_id: parts.parent_id,
232 person_id: parts.person_id,
233 person: parts.person,
234 created_at: parts.created_at,
235 text: parts.text,
236 }
237 }
238}
239
240pub(crate) struct NoteParts {
241 pub id: Option<Uuid>,
242 pub cell: CellReference,
243 pub author: Option<String>,
244 pub text: String,
245}
246
247impl From<NoteParts> for NoteComment {
248 fn from(parts: NoteParts) -> Self {
249 Self { id: parts.id, cell: parts.cell, author: parts.author, text: parts.text }
250 }
251}