ipmail 0.1.0

Rust implementation of SP-centric decentralized instant message synchronization protocol(DIMSP)
Documentation
use libipld::{Cid, DagCbor};
use lru_mem::HeapSize;
use serde::{Deserialize, Serialize};

/// Mail brief variant.
pub enum Message {
    /// Deliver mail message
    Deliver(Mail),
    /// Delivery reply message.
    Reply(Reply),
}

/// Mail reply message
#[derive(Debug, DagCbor, Clone, Serialize, Deserialize)]
pub struct Reply {
    pub cid: Cid,
    pub send_uid: u64,
    pub status: Status,
}

#[derive(Debug, DagCbor, Clone, Serialize, Deserialize)]
pub enum Status {
    /// Mail delivery success
    Success,
    /// Mail delivery is rejected on the receiving blacklist.
    Blacklist,
}

#[derive(Debug, DagCbor, Clone, Serialize, Deserialize)]
pub struct Mail {
    pub cid: Cid,
    pub sender_uid: u64,
    pub routing_uids: Vec<u64>,
    pub receiver_uid: u64,
    pub root_content: MailContent,
}

/// Multipart type of instant message.
#[derive(Debug, DagCbor, Clone, Serialize, Deserialize)]
pub struct MailContent {
    /// Multipart total size in bytes.
    pub length: u64,
    /// Multipart content,
    pub content: ContentType,
}

impl HeapSize for MailContent {
    fn heap_size(&self) -> usize {
        match &self.content {
            ContentType::Mixed(cids) => cids.len() * 64 + 8,
            ContentType::Related(cids) => cids.len() * 64 + 8,
            ContentType::Alternative(_, _) => 2 * 64 + 8,
            ContentType::Blocks(cids) => cids.len() * 64 + 8,
            ContentType::Mime(name, data) => data.len() + name.len() + 8,
        }
    }
}

#[derive(Debug, DagCbor, Clone, Serialize, Deserialize)]
pub enum ContentType {
    /// Has the same semantic meaning as [`multipart/Mixed`](https://www.rfc-editor.org/rfc/rfc2046#page-17)
    Mixed(Vec<Cid>),
    /// Has the same semantic meaning as [`multipart/Related`](https://www.rfc-editor.org/rfc/rfc2046#page-17)
    Related(Vec<Cid>),
    /// Has the same semantic meaning as [`multipart/alternative`](https://www.rfc-editor.org/rfc/rfc2046#page-17)
    Alternative(Cid, Cid),
    /// Split a large data into several smaller blocks
    Blocks(Vec<Cid>),
    /// Other mime type content.
    Mime(String, Vec<u8>),
}