use std::path::Path;
use cotis::cotis_app::UiFn;
use cotis::element_configuring::{ConfigureElements, ConfiguredParentElement};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use crate::layout_module_debugger::isolated_replay::replay_instructions;
use crate::serialize_targets::leaf_serialization::{LeafConfigData, LeafConfigListCompatible};
pub mod leaf_serialization;
#[derive(Serialize, Deserialize, Debug)]
pub enum SerializableInterfaceInstructions<ConfigType> {
Start,
Open,
Configure(ConfigType),
LeafConfig(LeafConfigData),
Close,
End,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SerializedInterfaceDeclaration<ConfigType> {
configs: Vec<SerializableInterfaceInstructions<ConfigType>>,
}
impl<Config> SerializedInterfaceDeclaration<Config> {
pub fn new() -> Self {
Self { configs: vec![] }
}
pub fn start(&mut self) {
self.configs.push(SerializableInterfaceInstructions::Start);
}
pub fn end(&mut self) {
self.configs.push(SerializableInterfaceInstructions::End);
}
pub fn open(&mut self) {
self.configs.push(SerializableInterfaceInstructions::Open);
}
pub fn add_config(&mut self, config: Config) {
self.configs
.push(SerializableInterfaceInstructions::Configure(config));
}
pub fn close(&mut self) {
self.configs.push(SerializableInterfaceInstructions::Close);
}
pub fn add_leaf_config<LeafConfig: Serialize>(&mut self, config: &LeafConfig) {
self.configs
.push(SerializableInterfaceInstructions::LeafConfig(
LeafConfigData::new(config),
));
}
pub fn iter_over(&self) -> impl Iterator<Item = &SerializableInterfaceInstructions<Config>> {
self.configs.iter()
}
}
impl<Config> Default for SerializedInterfaceDeclaration<Config> {
fn default() -> Self {
Self::new()
}
}
pub struct LeafedInterfaceDeclaration<ConfigType, List: Copy> {
serialized: SerializedInterfaceDeclaration<ConfigType>,
leaf_types: List,
}
pub struct LeafedInterfaceInstructions<ConfigType, List: Copy> {
pub instruction: ConfigType,
pub list: List,
}
impl<ConfigType, List: Copy> LeafedInterfaceDeclaration<ConfigType, List> {
pub fn new(serialized: SerializedInterfaceDeclaration<ConfigType>, leaf_types: List) -> Self {
Self {
serialized,
leaf_types,
}
}
pub fn start(&mut self) {
self.serialized.start();
}
pub fn end(&mut self) {
self.serialized.end();
}
pub fn open(&mut self) {
self.serialized.open();
}
pub fn add_config(&mut self, config: ConfigType) {
self.serialized.add_config(config);
}
pub fn close(&mut self) {
self.serialized.close();
}
pub fn add_leaf_config<LeafConfig: Serialize>(&mut self, config: &LeafConfig) {
self.serialized.add_leaf_config(config);
}
pub fn iter_over(
&self,
) -> impl Iterator<
Item = LeafedInterfaceInstructions<&SerializableInterfaceInstructions<ConfigType>, List>,
> {
let list = self.leaf_types;
self.serialized
.iter_over()
.map(move |instruction| LeafedInterfaceInstructions { instruction, list })
}
}
impl<ConfigType: Serialize + DeserializeOwned, List: Copy>
LeafedInterfaceDeclaration<ConfigType, List>
{
pub fn store_in(&self, file: &Path) -> Result<(), Box<dyn std::error::Error>> {
let bytes = serde_json::to_vec(&self.serialized)?;
std::fs::write(file, bytes)?;
Ok(())
}
pub fn load_from(file: &Path, leaf_types: List) -> Result<Self, Box<dyn std::error::Error>> {
let bytes = std::fs::read(file)?;
let serialized: SerializedInterfaceDeclaration<ConfigType> =
serde_json::from_slice(&bytes)?;
Ok(Self {
serialized,
leaf_types,
})
}
}
impl<
'inside,
Configurer: ConfigureElements<ConfigType>,
ConfigType: Clone,
List: Copy + LeafConfigListCompatible<Configurer, ConfigType>,
> UiFn<'inside, Configurer, ConfigType> for &LeafedInterfaceDeclaration<ConfigType, List>
{
fn draw_in(self, layout: &mut ConfiguredParentElement<'inside, Configurer, ConfigType>) {
replay_instructions(&mut self.iter_over(), layout);
}
}