use serde::{Deserialize, Serialize};
use crate::common::{EmailAddress, GrantId, ThreadId};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Thread {
pub id: ThreadId,
pub grant_id: GrantId,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject: Option<String>,
#[serde(default)]
pub participants: Vec<EmailAddress>,
#[serde(default)]
pub message_ids: Vec<String>,
#[serde(default)]
pub draft_ids: Vec<String>,
#[serde(default)]
pub folders: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub snippet: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub starred: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub unread: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub latest_draft_or_message: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub has_attachments: Option<bool>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct UpdateThreadRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub starred: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub unread: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub folders: Option<Vec<String>>,
}
impl UpdateThreadRequest {
pub fn builder() -> UpdateThreadRequestBuilder {
UpdateThreadRequestBuilder::default()
}
}
#[derive(Debug, Clone, Default)]
pub struct UpdateThreadRequestBuilder {
starred: Option<bool>,
unread: Option<bool>,
folders: Option<Vec<String>>,
}
impl UpdateThreadRequestBuilder {
pub fn starred(mut self, starred: bool) -> Self {
self.starred = Some(starred);
self
}
pub fn unread(mut self, unread: bool) -> Self {
self.unread = Some(unread);
self
}
pub fn folders(mut self, folders: Vec<String>) -> Self {
self.folders = Some(folders);
self
}
pub fn build(self) -> UpdateThreadRequest {
UpdateThreadRequest {
starred: self.starred,
unread: self.unread,
folders: self.folders,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_thread_creation() {
let thread = Thread {
id: ThreadId::new("thread_123"),
grant_id: GrantId::new("grant_456"),
subject: Some("Test Subject".to_string()),
participants: vec![],
message_ids: vec!["msg_1".to_string(), "msg_2".to_string()],
draft_ids: vec![],
folders: vec!["folder_1".to_string()],
snippet: Some("Test snippet".to_string()),
starred: Some(false),
unread: Some(true),
latest_draft_or_message: Some(1234567890),
has_attachments: Some(false),
};
assert_eq!(thread.id.as_str(), "thread_123");
assert_eq!(thread.subject, Some("Test Subject".to_string()));
assert_eq!(thread.message_ids.len(), 2);
assert_eq!(thread.unread, Some(true));
}
#[test]
fn test_thread_serialization() {
let thread = Thread {
id: ThreadId::new("thread_123"),
grant_id: GrantId::new("grant_456"),
subject: Some("Test".to_string()),
participants: vec![],
message_ids: vec!["msg_1".to_string()],
draft_ids: vec![],
folders: vec![],
snippet: None,
starred: Some(true),
unread: Some(false),
latest_draft_or_message: None,
has_attachments: Some(false),
};
let json = serde_json::to_string(&thread).unwrap();
assert!(json.contains("thread_123"));
assert!(json.contains("Test"));
}
#[test]
fn test_thread_deserialization() {
let json = r#"{
"id": "thread_123",
"grant_id": "grant_456",
"subject": "Test Subject",
"participants": [],
"message_ids": ["msg_1", "msg_2"],
"draft_ids": [],
"folders": ["folder_1"],
"starred": false,
"unread": true,
"latest_draft_or_message": 1234567890
}"#;
let thread: Thread = serde_json::from_str(json).unwrap();
assert_eq!(thread.id.as_str(), "thread_123");
assert_eq!(thread.subject, Some("Test Subject".to_string()));
assert_eq!(thread.message_ids.len(), 2);
assert_eq!(thread.unread, Some(true));
}
#[test]
fn test_update_thread_request_builder() {
let update = UpdateThreadRequest::builder()
.starred(true)
.unread(false)
.folders(vec!["folder_1".to_string()])
.build();
assert_eq!(update.starred, Some(true));
assert_eq!(update.unread, Some(false));
assert_eq!(update.folders, Some(vec!["folder_1".to_string()]));
}
#[test]
fn test_update_thread_request_partial() {
let update = UpdateThreadRequest::builder().starred(true).build();
assert_eq!(update.starred, Some(true));
assert_eq!(update.unread, None);
assert_eq!(update.folders, None);
}
#[test]
fn test_update_thread_request_serialization() {
let update = UpdateThreadRequest::builder()
.starred(true)
.unread(false)
.build();
let json = serde_json::to_string(&update).unwrap();
assert!(json.contains("starred"));
assert!(json.contains("unread"));
let deserialized: UpdateThreadRequest = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized, update);
}
}