tlpt 0.8.0

A set of protocols for building local-first distributed systems
Documentation
use std::pin::Pin;

use futures::{Stream, Future};
use endr::{ObjectID, Diff};

use crate::doc::WeakDoc;

use self::{jmbl_content::JMBLContent, json_stream_content::JsonStreamContent, binary_stream_content::BinaryStreamContent};

pub mod jmbl_content;
pub mod json_stream_content;
pub mod binary_stream_content;

pub trait ContentType {
    fn content_type(&self) -> &'static str;
    // TODO: require_into is only here for profille bootstrapping, we should get rid of it
    fn connect_and_init(&self, weak_doc: WeakDoc, require_intro: bool);
    fn follow_new_log(&self, log_id: ObjectID, diffs: Pin<Box<dyn Stream<Item = ContentDiff>>>) -> Pin<Box<dyn Future<Output = ()>>>;
}

#[derive(Clone)]
pub enum AnyContentType {
    JMBL(JMBLContent),
    JsonStream(JsonStreamContent),
    BinaryStream(BinaryStreamContent),
}

impl ContentType for AnyContentType {
    fn content_type(&self) -> &'static str {
        match self {
            AnyContentType::JMBL(jmbl) => jmbl.content_type(),
            AnyContentType::JsonStream(json_stream) => json_stream.content_type(),
            AnyContentType::BinaryStream(binary_stream) => binary_stream.content_type(),
        }
    }

    fn connect_and_init(&self, weak_doc: WeakDoc, require_intro: bool) {
        match self {
            AnyContentType::JMBL(jmbl) => jmbl.connect_and_init(weak_doc, require_intro),
            AnyContentType::JsonStream(json_stream) => json_stream.connect_and_init(weak_doc, require_intro),
            AnyContentType::BinaryStream(binary_stream) => binary_stream.connect_and_init(weak_doc, require_intro),
        }
    }

    fn follow_new_log(&self, log_id: ObjectID, diffs: Pin<Box<dyn Stream<Item = ContentDiff>>>) -> Pin<Box<dyn Future<Output = ()>>> {
        match self {
            AnyContentType::JMBL(jmbl) => jmbl.follow_new_log(log_id, diffs),
            AnyContentType::JsonStream(json_stream) => json_stream.follow_new_log(log_id, diffs),
            AnyContentType::BinaryStream(binary_stream) => binary_stream.follow_new_log(log_id, diffs),
        }
    }
}

impl From<JMBLContent> for AnyContentType {
    fn from(jmbl: JMBLContent) -> AnyContentType {
        AnyContentType::JMBL(jmbl)
    }
}

impl From<JsonStreamContent> for AnyContentType {
    fn from(json_stream: JsonStreamContent) -> AnyContentType {
        AnyContentType::JsonStream(json_stream)
    }
}

impl From<BinaryStreamContent> for AnyContentType {
    fn from(binary_stream: BinaryStreamContent) -> AnyContentType {
        AnyContentType::BinaryStream(binary_stream)
    }
}

impl AnyContentType {
    pub fn expect_jmbl(&self) -> JMBLContent {
        match self {
            AnyContentType::JMBL(jmbl) => jmbl.clone(),
            _ => panic!("Expected JMBL"),
        }
    }

    pub fn expect_json_stream(&self) -> JsonStreamContent {
        match self {
            AnyContentType::JsonStream(json_stream) => json_stream.clone(),
            _ => panic!("Expected JsonStream"),
        }
    }

    pub fn expect_binary_stream(&self) -> BinaryStreamContent {
        match self {
            AnyContentType::BinaryStream(binary_stream) => binary_stream.clone(),
            _ => panic!("Expected BinaryStream"),
        }
    }
}

#[derive(Debug)]
pub struct ContentDiff{pub decrypted_entries: Vec<litl::Val>, pub raw_diff: Diff}


pub fn empty_for_content_type_string(content_type_str: &str) -> Option<AnyContentType> {
    match content_type_str {
        "jmbl1" => Some(AnyContentType::JMBL(jmbl_content::JMBLContent::new_empty())),
        "json_stream1" => Some(AnyContentType::JsonStream(json_stream_content::JsonStreamContent::new_empty())),
        "binary_stream1" => Some(AnyContentType::BinaryStream(binary_stream_content::BinaryStreamContent::new_empty())),
        _ => None,
    }
}