use crate::utils::OwnedOrRefMut;
use std::marker::PhantomData;
pub trait ConfigureElements<ConfigType> {
fn open_new_element(&mut self, _: Seal);
fn set_config(&mut self, config: ConfigType, _: Seal);
fn close_element(&mut self, _: Seal);
}
pub trait ConfigureLeafElements<ConfigType> {
fn set_leaf_config(&mut self, config: ConfigType, _: Seal);
}
pub struct Seal(());
pub struct ConfiguredParentElement<'element, Configurer: ConfigureElements<ConfigType>, ConfigType>
{
layout: OwnedOrRefMut<'element, Configurer>,
phantom_data: PhantomData<ConfigType>,
}
impl<'element, Configurer: ConfigureElements<ConfigType>, ConfigType>
ConfiguredParentElement<'element, Configurer, ConfigType>
{
pub fn new(layout: OwnedOrRefMut<'element, Configurer>) -> Self {
Self {
layout,
phantom_data: Default::default(),
}
}
pub fn new_element(&'_ mut self) -> OpenElement<'_, Configurer, ConfigType>
where
Self: Sized,
{
self.layout.as_mut().open_new_element(Seal(()));
OpenElement {
layout: Some(self.layout.reborrow()),
phantom_data: Default::default(),
}
}
pub fn close_element(self) {
drop(self)
}
}
pub struct OpenElement<'element, Configurer: ConfigureElements<ConfigType>, ConfigType> {
layout: Option<OwnedOrRefMut<'element, Configurer>>,
phantom_data: PhantomData<ConfigType>,
}
impl<'element, ConfigType, Configurer: ConfigureElements<ConfigType>>
OpenElement<'element, Configurer, ConfigType>
{
pub fn set_config(&mut self, config: ConfigType) {
self.layout
.as_mut()
.unwrap()
.as_mut()
.set_config(config, Seal(()));
}
pub fn make_parent(mut self) -> ConfiguredParentElement<'element, Configurer, ConfigType> {
ConfiguredParentElement {
layout: self.layout.take().unwrap(),
phantom_data: Default::default(),
}
}
pub fn close_element(self) {
drop(self)
}
pub fn set_leaf_config<LeafConfig>(mut self, config: LeafConfig)
where
Configurer: ConfigureLeafElements<LeafConfig>,
{
self.layout
.as_mut()
.unwrap()
.as_mut()
.set_leaf_config(config, Seal(()));
}
}
pub struct OpenLeafElement<'element, Configurer: ConfigureElements<ConfigType>, ConfigType> {
layout: OwnedOrRefMut<'element, Configurer>,
phantom_data: PhantomData<ConfigType>,
}
impl<'element, ConfigType, Configurer: ConfigureElements<ConfigType>>
OpenLeafElement<'element, Configurer, ConfigType>
{
pub fn set_config(&mut self, config: ConfigType) {
self.layout.as_mut().set_config(config, Seal(()));
}
pub fn set_leaf_config<LeafConfig>(&mut self, config: LeafConfig)
where
Configurer: ConfigureLeafElements<LeafConfig>,
{
self.layout.as_mut().set_leaf_config(config, Seal(()));
}
pub fn close_element(self) {
drop(self)
}
}
impl<'element, Configurer: ConfigureElements<ConfigType>, ConfigType> Drop
for OpenElement<'element, Configurer, ConfigType>
{
fn drop(&mut self) {
if let Some(layout) = &mut self.layout {
layout.as_mut().close_element(Seal(()));
}
}
}
impl<'element, ConfigType, Configurer: ConfigureElements<ConfigType>> Drop
for ConfiguredParentElement<'element, Configurer, ConfigType>
{
fn drop(&mut self) {
self.layout.as_mut().close_element(Seal(()));
}
}
impl<'element, ConfigType, Configurer: ConfigureElements<ConfigType>> Drop
for OpenLeafElement<'element, Configurer, ConfigType>
{
fn drop(&mut self) {
self.layout.as_mut().close_element(Seal(()));
}
}