///|
pub struct ArchiveKey {
year : Int
month : Int
category : String
sender_domain : String
} derive(Eq, Debug)
///|
pub struct ArchiveBucket {
key : ArchiveKey
messages : Array[MailMessage]
} derive(Eq, Debug)
///|
pub fn archive_key(message : MailMessage) -> ArchiveKey {
let date = message_date(message)
{
year: date.year,
month: date_month_number(date),
category: category_name(classify_message(message)),
sender_domain: sender_domain(message),
}
}
///|
pub fn archive_key_string(key : ArchiveKey) -> String {
key.year.to_string() +
"/" +
pad2(key.month) +
"/" +
key.category +
"/" +
key.sender_domain
}
///|
fn pad2(value : Int) -> String {
if value < 10 {
"0" + value.to_string()
} else {
value.to_string()
}
}
///|
pub fn group_archive(messages : Array[MailMessage]) -> Array[ArchiveBucket] {
let buckets : Array[ArchiveBucket] = []
for message in messages {
add_to_bucket(buckets, message)
}
buckets
}
///|
fn add_to_bucket(buckets : Array[ArchiveBucket], message : MailMessage) -> Unit {
let key = archive_key(message)
let key_text = archive_key_string(key)
let mut i = 0
while i < buckets.length() {
if archive_key_string(buckets[i].key) == key_text {
let next_messages : Array[MailMessage] = []
for item in buckets[i].messages {
next_messages.push(item)
}
next_messages.push(message)
buckets[i] = { key: buckets[i].key, messages: next_messages }
return
}
i = i + 1
}
buckets.push({ key, messages: [message] })
}
///|
pub fn archive_bucket_count(messages : Array[MailMessage]) -> Int {
group_archive(messages).length()
}
///|
pub fn archive_subjects(bucket : ArchiveBucket) -> Array[String] {
let out : Array[String] = []
for message in bucket.messages {
out.push(message.subject)
}
out
}
///|
pub fn find_archive_bucket(
buckets : Array[ArchiveBucket],
key_text : String,
) -> ArchiveBucket? {
for bucket in buckets {
if archive_key_string(bucket.key) == key_text {
return Some(bucket)
}
}
None
}
///|
pub fn archive_manifest(messages : Array[MailMessage]) -> String {
let mut out = ""
for bucket in group_archive(messages) {
out = out +
archive_key_string(bucket.key) +
" " +
bucket.messages.length().to_string() +
"\n"
}
out
}
///|
pub fn archive_by_category(
messages : Array[MailMessage],
category : MailCategory,
) -> Array[MailMessage] {
let out : Array[MailMessage] = []
for message in messages {
if classify_message(message) == category {
out.push(message)
}
}
out
}
///|
pub fn archive_by_year_month(
messages : Array[MailMessage],
year : Int,
month : Int,
) -> Array[MailMessage] {
let out : Array[MailMessage] = []
for message in messages {
let key = archive_key(message)
if key.year == year && key.month == month {
out.push(message)
}
}
out
}
///|
pub fn archive_by_sender_domain(
messages : Array[MailMessage],
domain : String,
) -> Array[MailMessage] {
let out : Array[MailMessage] = []
let target = lower_ascii(domain)
for message in messages {
if sender_domain(message) == target {
out.push(message)
}
}
out
}
///|
pub fn archive_health_report(messages : Array[MailMessage]) -> String {
let mut out = "archive messages=" + messages.length().to_string()
out = out + " buckets=" + archive_bucket_count(messages).to_string()
out = out + " risky=" + risky_archive_count(messages).to_string()
out = out + " errors=" + archive_lint_error_count(messages).to_string()
out
}
///|
fn risky_archive_count(messages : Array[MailMessage]) -> Int {
let mut count = 0
for message in messages {
if is_high_risk(message) {
count = count + 1
}
}
count
}
///|
fn archive_lint_error_count(messages : Array[MailMessage]) -> Int {
let mut count = 0
for message in messages {
if error_count(lint_message(message)) > 0 {
count = count + 1
}
}
count
}