Skip to main content

agent_protocols/mail/
types.rs

1use crate::identity::{AgentId, Envelope};
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5pub type MailboxCard = Envelope<MailboxCardPayload>;
6/// The signed `mail.submit` envelope: the wire object relays store and recipients open.
7pub type Packet = Envelope<PacketPayload>;
8#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
9#[serde(deny_unknown_fields)]
10pub struct MailboxCardPayload {
11    pub mailbox_id: String,
12    pub expires_at: i64,
13    pub receive_until: i64,
14    pub public_key: String,
15    /// Zero to eight relay origins; an empty list closes the mailbox.
16    pub routes: Vec<String>,
17    pub max_packet_bytes: usize,
18}
19#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
20#[serde(deny_unknown_fields)]
21pub struct MessagePayload {
22    pub message_id: String,
23    #[serde(rename = "from")]
24    pub sender: AgentId,
25    pub created_at: i64,
26    pub to: AgentId,
27    pub expires_at: i64,
28    pub thread_id: String,
29    pub parts: Vec<MailPart>,
30    #[serde(default, skip_serializing_if = "Option::is_none")]
31    pub subject: Option<String>,
32    #[serde(default, skip_serializing_if = "Option::is_none")]
33    pub in_reply_to: Option<String>,
34    #[serde(default, skip_serializing_if = "Option::is_none")]
35    pub reply_card: Option<Value>,
36}
37#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
38#[serde(deny_unknown_fields)]
39pub struct MailPart {
40    pub media_type: String,
41    pub data: String,
42    #[serde(default, skip_serializing_if = "Option::is_none")]
43    pub name: Option<String>,
44}
45impl MailPart {
46    pub fn text(text: &str) -> Self {
47        Self {
48            media_type: "text/plain".into(),
49            data: super::encode_bytes(text.as_bytes()),
50            name: None,
51        }
52    }
53    pub fn bytes(media_type: impl Into<String>, bytes: &[u8], name: Option<String>) -> Self {
54        Self {
55            media_type: media_type.into(),
56            data: super::encode_bytes(bytes),
57            name,
58        }
59    }
60}
61#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
62#[serde(deny_unknown_fields)]
63pub struct PacketHeader {
64    pub mailbox_id: String,
65    pub card_hash: String,
66    pub expires_at: i64,
67}
68#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
69#[serde(deny_unknown_fields)]
70pub struct PacketPayload {
71    pub header: PacketHeader,
72    pub enc: String,
73    pub ciphertext: String,
74}
75/// Sender-authenticated delivery result. It never carries the mailbox `seq`.
76#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
77#[serde(deny_unknown_fields)]
78pub struct DeliveryResult {
79    pub packet_id: String,
80    pub accepted_at: i64,
81}
82#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
83#[serde(deny_unknown_fields)]
84pub struct PacketRecord {
85    pub packet_id: String,
86    pub packet: Packet,
87    pub accepted_at: i64,
88    pub seq: u64,
89}
90/// A parsed mailbox address (Mail Section 3.3). `routes` is empty for the stable form.
91#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
92#[serde(deny_unknown_fields)]
93pub struct MailAddress {
94    pub owner: AgentId,
95    pub mailbox_id: String,
96    pub routes: Vec<String>,
97}
98#[derive(Clone, Debug, PartialEq)]
99pub enum InboxAcceptance {
100    Accepted(Box<MessagePayload>),
101    Duplicate(Box<MessagePayload>),
102}