#![cfg(feature = "server")]
use dioxus_lib::prelude::{has_context, provide_context, use_hook};
use serde::Serialize;
use std::{cell::RefCell, rc::Rc};
pub(crate) mod serialize;
#[derive(Default, Clone)]
pub(crate) struct SerializeContext {
data: Rc<RefCell<HTMLData>>,
}
impl SerializeContext {
pub(crate) fn create_entry(&self) -> usize {
self.data.borrow_mut().create_entry()
}
pub(crate) fn insert<T: Serialize>(
&self,
id: usize,
value: &T,
location: &'static std::panic::Location<'static>,
) {
self.data.borrow_mut().insert(id, value, location);
}
pub(crate) fn push<T: Serialize>(
&self,
data: &T,
location: &'static std::panic::Location<'static>,
) {
self.data.borrow_mut().push(data, location);
}
}
pub(crate) fn use_serialize_context() -> SerializeContext {
use_hook(serialize_context)
}
pub(crate) fn serialize_context() -> SerializeContext {
has_context().unwrap_or_else(|| provide_context(SerializeContext::default()))
}
#[derive(Default)]
pub(crate) struct HTMLData {
pub data: Vec<Option<Vec<u8>>>,
#[cfg(debug_assertions)]
pub debug_types: Vec<Option<String>>,
#[cfg(debug_assertions)]
pub debug_locations: Vec<Option<String>>,
}
impl HTMLData {
fn create_entry(&mut self) -> usize {
let id = self.data.len();
self.data.push(None);
#[cfg(debug_assertions)]
{
self.debug_types.push(None);
self.debug_locations.push(None);
}
id
}
fn insert<T: Serialize>(
&mut self,
id: usize,
value: &T,
location: &'static std::panic::Location<'static>,
) {
let mut serialized = Vec::new();
ciborium::into_writer(value, &mut serialized).unwrap();
self.data[id] = Some(serialized);
#[cfg(debug_assertions)]
{
self.debug_types[id] = Some(std::any::type_name::<T>().to_string());
self.debug_locations[id] = Some(location.to_string());
}
}
fn push<T: Serialize>(&mut self, data: &T, location: &'static std::panic::Location<'static>) {
let mut serialized = Vec::new();
ciborium::into_writer(data, &mut serialized).unwrap();
self.data.push(Some(serialized));
#[cfg(debug_assertions)]
{
self.debug_types
.push(Some(std::any::type_name::<T>().to_string()));
self.debug_locations.push(Some(location.to_string()));
}
}
pub(crate) fn extend(&mut self, other: &Self) {
self.data.extend_from_slice(&other.data);
#[cfg(debug_assertions)]
{
self.debug_types.extend_from_slice(&other.debug_types);
self.debug_locations
.extend_from_slice(&other.debug_locations);
}
}
}