ipldfs 0.1.0

Virtual filesystem for ipld
Documentation
use libipld::{Cid, DagCbor};

use lru_mem::HeapSize;
use serde::{Deserialize, Serialize};
use std::{
    future::Future,
    io::Result,
    time::{Duration, SystemTime},
};

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

impl HeapSize for Multipart {
    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>),
}
/// Ipld fs entry
pub struct IpldEntry {
    /// multipart object cid
    pub cid: Cid,
    /// multipart object total size in bytes
    pub length: u64,
    /// Created [`time`](SystemTime) of fs entry.
    pub created: SystemTime,
    /// multipart object expired [`time`](SystemTime)
    pub expired: SystemTime,
}

/// [`poll_write`](IpldFS::poll_write) returns result.
pub struct IpldWrite {
    /// Cid
    pub cid: Cid,
    pub unlinked: Vec<Cid>,
}

///[`ipld`](https://ipld.io/) virtual fs trait.
pub trait IpldFS {
    type ReadEntry<'cx>: Future<Output = Result<IpldEntry>> + Send + Unpin + 'cx
    where
        Self: 'cx;

    type Write<'cx>: Future<Output = Result<Vec<Cid>>> + Send + Unpin + 'cx
    where
        Self: 'cx;

    type Read<'cx>: Future<Output = Result<Multipart>> + Send + Unpin + 'cx
    where
        Self: 'cx;

    /// Read multipart object metadata by [`cid`](Cid). returns [`NotFound`](std::io::ErrorKind::NotFound) if cid not exists.
    fn read_entry<'cx, 'a>(&'a mut self, cid: Cid) -> Self::ReadEntry<'cx>
    where
        'a: 'cx;

    /// Put multipart object into local storage and returns unlink multipart cids.
    /// # parameters
    ///
    /// - `lease` The multipart object's maximum lease for storage.
    /// - `cid` multipart object's cid, the implementation must check if the cid is a valid cid for the `mime` object
    ///
    fn write<'cx, 'a>(
        &'a mut self,
        cid: Cid,
        multipart: Multipart,
        lease: Duration,
    ) -> Self::Write<'cx>
    where
        'a: 'cx;

    /// Read multipart object content, returns [`NotFound`](std::io::ErrorKind::NotFound) if cid not exists.
    fn read<'cx, 'a>(&'a mut self, cid: &'cx Cid) -> Self::Read<'cx>
    where
        'a: 'cx;
}