#![allow(unused)]
use crate::prelude::*;
pub struct MailGroup<'a> {
pub(crate) esi: &'a Esi,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct MailLabels {
#[serde(default)]
pub labels: Vec<MailLabel>,
pub total_unread_count: Option<i64>,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct MailLabel {
pub color: String,
pub label_id: i64,
pub name: String,
#[serde(default)]
pub unread_count: Option<i64>,
}
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
pub enum RecipientType {
#[serde(rename = "alliance")]
Alliance,
#[serde(rename = "character")]
Character,
#[serde(rename = "corporation")]
Corporation,
#[serde(rename = "mailing_list")]
MailingList,
#[serde(other)]
Unrecognized,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
pub struct MailRecipient {
pub recipient_id: i64,
pub recipient_type: RecipientType,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct MailHeader {
pub from: Option<i64>,
pub is_read: Option<bool>,
#[serde(default)]
pub labels: Vec<i64>,
pub mail_id: Option<i64>,
#[serde(default)]
pub recipients: Vec<MailRecipient>,
pub subject: Option<String>,
pub timestamp: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Mail {
pub body: Option<String>,
pub from: Option<i64>,
#[serde(default)]
pub labels: Vec<i64>,
pub read: Option<bool>,
#[serde(default)]
pub recipients: Vec<MailRecipient>,
pub subject: Option<String>,
pub timestamp: Option<String>,
}
#[derive(Debug, Serialize, Clone)]
pub struct NewMail {
pub body: String,
pub recipients: Vec<MailRecipient>,
pub subject: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub approved_cost: Option<i64>,
}
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
pub enum MailLabelColor {
#[serde(rename = "#0000fe")]
Blue,
#[serde(rename = "#006634")]
DarkGreen,
#[serde(rename = "#0099ff")]
LightBlue,
#[serde(rename = "#00ff33")]
BrightGreen,
#[serde(rename = "#01ffff")]
Cyan,
#[serde(rename = "#349800")]
Green,
#[serde(rename = "#660066")]
Purple,
#[serde(rename = "#666666")]
DarkGrey,
#[serde(rename = "#999999")]
Grey,
#[serde(rename = "#99ffff")]
PaleCyan,
#[serde(rename = "#9a0000")]
DarkRed,
#[serde(rename = "#ccff9a")]
PaleGreen,
#[serde(rename = "#e6e6e6")]
LightGrey,
#[serde(rename = "#fe0000")]
Red,
#[serde(rename = "#ff6600")]
Orange,
#[serde(rename = "#ffff01")]
Yellow,
#[serde(rename = "#ffffcd")]
PaleYellow,
#[serde(rename = "#ffffff")]
White,
#[serde(other)]
Unrecognized,
}
#[derive(Debug, Serialize, Clone)]
pub struct NewMailLabel {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub color: Option<MailLabelColor>,
}
#[derive(Debug, Serialize, Clone, Default)]
pub struct MailUpdate {
#[serde(skip_serializing_if = "Option::is_none")]
pub labels: Option<Vec<i64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub read: Option<bool>,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct MailingList {
pub mailing_list_id: i64,
pub name: String,
}
impl MailGroup<'_> {
api_get!(
get_character_mail,
"GetCharactersCharacterIdMail",
RequestType::Authenticated,
Vec<MailHeader>,
(character_id: i64) => "{character_id}";
OptionalMany(labels: &[i64]) => "labels",
Optional(last_mail_id: i64) => "last_mail_id"
);
api_post!(
send_character_mail,
"PostCharactersCharacterIdMail",
RequestType::Authenticated,
i64,
(character_id: i64) => "{character_id}",
mail: &NewMail,
);
api_get!(
get_character_mail_labels,
"GetCharactersCharacterIdMailLabels",
RequestType::Authenticated,
MailLabels,
(character_id: i64) => "{character_id}"
);
api_post!(
create_character_mail_label,
"PostCharactersCharacterIdMailLabels",
RequestType::Authenticated,
i64,
(character_id: i64) => "{character_id}",
label: &NewMailLabel,
);
api_delete!(
delete_character_mail_label,
"DeleteCharactersCharacterIdMailLabelsLabelId",
RequestType::Authenticated,
(),
(character_id: i64) => "{character_id}",
(label_id: i64) => "{label_id}"
);
api_get!(
get_character_mailing_lists,
"GetCharactersCharacterIdMailLists",
RequestType::Authenticated,
Vec<MailingList>,
(character_id: i64) => "{character_id}"
);
api_delete!(
delete_character_mail,
"DeleteCharactersCharacterIdMailMailId",
RequestType::Authenticated,
(),
(character_id: i64) => "{character_id}",
(mail_id: i64) => "{mail_id}"
);
api_get!(
get_character_mail_by_id,
"GetCharactersCharacterIdMailMailId",
RequestType::Authenticated,
Mail,
(character_id: i64) => "{character_id}",
(mail_id: i64) => "{mail_id}"
);
api_put!(
update_character_mail,
"PutCharactersCharacterIdMailMailId",
RequestType::Authenticated,
(),
(character_id: i64) => "{character_id}",
(mail_id: i64) => "{mail_id}",
update: &MailUpdate,
);
}
#[cfg(test)]
mod mail_tests {
use super::*;
#[test]
fn test_parse_mail_header_and_unknown_recipient() {
let json = r#"[{"from": 2112625428, "is_read": true, "labels": [3, 9000000000],
"mail_id": 7000000000, "subject": "Hi", "timestamp": "2026-10-01T00:00:00Z",
"recipients": [{"recipient_id": 1, "recipient_type": "mailing_list"},
{"recipient_id": 2, "recipient_type": "something_new"}]}]"#;
let headers: Vec<MailHeader> = serde_json::from_str(json).unwrap();
assert_eq!(headers[0].mail_id, Some(7_000_000_000));
assert_eq!(
headers[0].recipients[0].recipient_type,
RecipientType::MailingList
);
assert_eq!(
headers[0].recipients[1].recipient_type,
RecipientType::Unrecognized
);
}
#[test]
fn test_serialize_new_mail_and_label() {
let mail = NewMail {
body: "b".into(),
recipients: vec![MailRecipient {
recipient_id: 1,
recipient_type: RecipientType::Character,
}],
subject: "s".into(),
approved_cost: None,
};
let v = serde_json::to_value(&mail).unwrap();
assert_eq!(v["recipients"][0]["recipient_type"], "character");
assert!(v.get("approved_cost").is_none());
let label = NewMailLabel {
name: "x".into(),
color: Some(MailLabelColor::Red),
};
assert_eq!(serde_json::to_value(&label).unwrap()["color"], "#fe0000");
let upd = MailUpdate {
labels: None,
read: Some(true),
};
assert_eq!(serde_json::to_string(&upd).unwrap(), r#"{"read":true}"#);
}
#[test]
fn test_parse_mail_and_lists() {
let m: Mail = serde_json::from_str(r#"{"body": "x", "from": 1, "read": false}"#).unwrap();
assert_eq!(m.read, Some(false));
let l: Vec<MailingList> =
serde_json::from_str(r#"[{"mailing_list_id": 5000000000, "name": "n"}]"#).unwrap();
assert_eq!(l[0].mailing_list_id, 5_000_000_000);
}
}