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;
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,
}
}