use std::time::SystemTime;
#[derive(Debug, Clone)]
pub struct Email {
pub from: String,
pub to: Vec<String>,
pub data: String,
pub timestamp: SystemTime,
}
impl Email {
pub fn new(from: String, to: Vec<String>, data: String) -> Self {
Self {
from,
to,
data,
timestamp: SystemTime::now(),
}
}
pub fn has_recipient(&self, recipient: &str) -> bool {
self.to.iter().any(|addr| addr == recipient)
}
pub fn is_from_sender(&self, sender: &str) -> bool {
self.from == sender
}
pub fn data_size(&self) -> usize {
self.data.len()
}
pub fn get_subject(&self) -> Option<&str> {
for line in self.data.lines() {
if line.is_empty() {
break;
}
if let Some(subject) = line.strip_prefix("Subject: ") {
return Some(subject);
}
if let Some(subject) = line.strip_prefix("subject: ") {
return Some(subject);
}
}
None
}
pub fn get_body(&self) -> Option<&str> {
let mut in_body = false;
let mut body_start = 0;
for (i, line) in self.data.lines().enumerate() {
if !in_body && line.is_empty() {
in_body = true;
body_start = self.data.lines().take(i + 1).map(|l| l.len() + 1).sum();
break;
}
}
if in_body && body_start < self.data.len() {
Some(&self.data[body_start..])
} else {
None
}
}
pub fn contains_text(&self, text: &str) -> bool {
self.data.contains(text)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_email_creation() {
let email = Email::new(
"sender@example.com".to_string(),
vec!["recipient@example.com".to_string()],
"Subject: Test\n\nHello World".to_string(),
);
assert_eq!(email.from, "sender@example.com");
assert_eq!(email.to, vec!["recipient@example.com"]);
assert_eq!(email.data, "Subject: Test\n\nHello World");
assert!(email.timestamp <= SystemTime::now());
}
#[test]
fn test_has_recipient() {
let email = Email::new(
"sender@example.com".to_string(),
vec![
"user1@example.com".to_string(),
"user2@example.com".to_string(),
],
"Test email".to_string(),
);
assert!(email.has_recipient("user1@example.com"));
assert!(email.has_recipient("user2@example.com"));
assert!(!email.has_recipient("user3@example.com"));
}
#[test]
fn test_is_from_sender() {
let email = Email::new(
"sender@example.com".to_string(),
vec!["recipient@example.com".to_string()],
"Test email".to_string(),
);
assert!(email.is_from_sender("sender@example.com"));
assert!(!email.is_from_sender("other@example.com"));
}
#[test]
fn test_get_subject() {
let email = Email::new(
"sender@example.com".to_string(),
vec!["recipient@example.com".to_string()],
"Subject: Test Email\nFrom: sender@example.com\n\nHello World".to_string(),
);
assert_eq!(email.get_subject(), Some("Test Email"));
let email_no_subject = Email::new(
"sender@example.com".to_string(),
vec!["recipient@example.com".to_string()],
"From: sender@example.com\n\nHello World".to_string(),
);
assert_eq!(email_no_subject.get_subject(), None);
}
#[test]
fn test_get_body() {
let email = Email::new(
"sender@example.com".to_string(),
vec!["recipient@example.com".to_string()],
"Subject: Test\nFrom: sender@example.com\n\nHello World\nSecond line".to_string(),
);
assert_eq!(email.get_body(), Some("Hello World\nSecond line"));
let email_no_body = Email::new(
"sender@example.com".to_string(),
vec!["recipient@example.com".to_string()],
"Subject: Test\nFrom: sender@example.com".to_string(),
);
assert_eq!(email_no_body.get_body(), None);
}
#[test]
fn test_contains_text() {
let email = Email::new(
"sender@example.com".to_string(),
vec!["recipient@example.com".to_string()],
"Subject: Important Message\n\nThis is a test email".to_string(),
);
assert!(email.contains_text("Important"));
assert!(email.contains_text("test email"));
assert!(!email.contains_text("not found"));
}
#[test]
fn test_data_size() {
let email = Email::new(
"sender@example.com".to_string(),
vec!["recipient@example.com".to_string()],
"Hello".to_string(),
);
assert_eq!(email.data_size(), 5);
}
}