use serde::{Deserialize, Serialize, de::DeserializeOwned};
use super::frame_seq::FrameSeq;
use super::tokens::TokenGrid;
use super::value::{AnyLatent, Latent};
mod sealed {
pub trait Sealed {}
impl Sealed for super::Continuous {}
impl Sealed for super::Tokens {}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum KindTag {
Continuous,
Tokens,
}
impl std::fmt::Display for KindTag {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
KindTag::Continuous => write!(f, "continuous"),
KindTag::Tokens => write!(f, "tokens"),
}
}
}
pub trait Framed {
fn frames(&self) -> usize;
fn slice_frames(&self, start: usize, len: usize) -> Self;
}
pub trait LatentKind: sealed::Sealed + Send + Sync + 'static {
type Repr: Framed
+ Clone
+ PartialEq
+ std::fmt::Debug
+ Serialize
+ DeserializeOwned
+ Send
+ Sync
+ 'static;
const TAG: KindTag;
#[doc(hidden)]
fn wrap_any(latent: Latent<Self>) -> AnyLatent
where
Self: Sized;
#[doc(hidden)]
fn unwrap_any(any: AnyLatent) -> Option<Latent<Self>>
where
Self: Sized;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Continuous {}
impl LatentKind for Continuous {
type Repr = FrameSeq;
const TAG: KindTag = KindTag::Continuous;
fn wrap_any(latent: Latent<Self>) -> AnyLatent {
AnyLatent::Continuous(latent)
}
fn unwrap_any(any: AnyLatent) -> Option<Latent<Self>> {
match any {
AnyLatent::Continuous(latent) => Some(latent),
AnyLatent::Tokens(_) => None,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Tokens {}
impl LatentKind for Tokens {
type Repr = TokenGrid;
const TAG: KindTag = KindTag::Tokens;
fn wrap_any(latent: Latent<Self>) -> AnyLatent {
AnyLatent::Tokens(latent)
}
fn unwrap_any(any: AnyLatent) -> Option<Latent<Self>> {
match any {
AnyLatent::Tokens(latent) => Some(latent),
AnyLatent::Continuous(_) => None,
}
}
}