use crate::rewritable_units::{Comment, Doctype, DocumentEnd, Element, EndTag, TextChunk};
use crate::selectors_vm::Selector;
use super::AsciiCompatibleEncoding;
use std::borrow::Cow;
use std::error::Error;
pub type HandlerResult = Result<(), Box<dyn Error + Send + Sync>>;
pub type DoctypeHandler<'h> = Box<dyn FnMut(&mut Doctype) -> HandlerResult + 'h>;
pub type CommentHandler<'h> = Box<dyn FnMut(&mut Comment) -> HandlerResult + 'h>;
pub type TextHandler<'h> = Box<dyn FnMut(&mut TextChunk) -> HandlerResult + 'h>;
pub type ElementHandler<'h> = Box<dyn FnMut(&mut Element) -> HandlerResult + 'h>;
pub type EndTagHandler<'h> = Box<dyn FnOnce(&mut EndTag) -> HandlerResult + 'h>;
pub type EndHandler<'h> = Box<dyn FnOnce(&mut DocumentEnd) -> HandlerResult + 'h>;
#[derive(Default)]
pub struct ElementContentHandlers<'h> {
pub element: Option<ElementHandler<'h>>,
pub comments: Option<CommentHandler<'h>>,
pub text: Option<TextHandler<'h>>,
}
impl<'h> ElementContentHandlers<'h> {
#[inline]
pub fn element(mut self, handler: impl FnMut(&mut Element) -> HandlerResult + 'h) -> Self {
self.element = Some(Box::new(handler));
self
}
#[inline]
pub fn comments(mut self, handler: impl FnMut(&mut Comment) -> HandlerResult + 'h) -> Self {
self.comments = Some(Box::new(handler));
self
}
#[inline]
pub fn text(mut self, handler: impl FnMut(&mut TextChunk) -> HandlerResult + 'h) -> Self {
self.text = Some(Box::new(handler));
self
}
}
#[derive(Default)]
pub struct DocumentContentHandlers<'h> {
pub doctype: Option<DoctypeHandler<'h>>,
pub comments: Option<CommentHandler<'h>>,
pub text: Option<TextHandler<'h>>,
pub end: Option<EndHandler<'h>>,
}
impl<'h> DocumentContentHandlers<'h> {
#[inline]
pub fn doctype(mut self, handler: impl FnMut(&mut Doctype) -> HandlerResult + 'h) -> Self {
self.doctype = Some(Box::new(handler));
self
}
#[inline]
pub fn comments(mut self, handler: impl FnMut(&mut Comment) -> HandlerResult + 'h) -> Self {
self.comments = Some(Box::new(handler));
self
}
#[inline]
pub fn text(mut self, handler: impl FnMut(&mut TextChunk) -> HandlerResult + 'h) -> Self {
self.text = Some(Box::new(handler));
self
}
#[inline]
pub fn end(mut self, handler: impl FnMut(&mut DocumentEnd) -> HandlerResult + 'h) -> Self {
self.end = Some(Box::new(handler));
self
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! __element_content_handler {
($selector:expr, $handler_name:ident, $handler:expr) => {
(
::std::borrow::Cow::Owned($selector.parse::<$crate::Selector>().unwrap()),
$crate::ElementContentHandlers::default().$handler_name($handler),
)
};
}
#[macro_export(local_inner_macros)]
macro_rules! element {
($selector:expr, $handler:expr) => {
__element_content_handler!($selector, element, $handler)
};
}
#[macro_export(local_inner_macros)]
macro_rules! text {
($selector:expr, $handler:expr) => {
__element_content_handler!($selector, text, $handler)
};
}
#[macro_export(local_inner_macros)]
macro_rules! comments {
($selector:expr, $handler:expr) => {
__element_content_handler!($selector, comments, $handler)
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __document_content_handler {
($handler_name:ident, $handler:expr) => {
$crate::DocumentContentHandlers::default().$handler_name($handler)
};
}
#[macro_export(local_inner_macros)]
macro_rules! doctype {
($handler:expr) => {
__document_content_handler!(doctype, $handler)
};
}
#[macro_export(local_inner_macros)]
macro_rules! doc_text {
($handler:expr) => {
__document_content_handler!(text, $handler)
};
}
#[macro_export(local_inner_macros)]
macro_rules! doc_comments {
($handler:expr) => {
__document_content_handler!(comments, $handler)
};
}
#[macro_export(local_inner_macros)]
macro_rules! end {
($handler:expr) => {
__document_content_handler!(end, $handler)
};
}
#[repr(C)]
pub struct MemorySettings {
pub preallocated_parsing_buffer_size: usize,
pub max_allowed_memory_usage: usize,
}
impl Default for MemorySettings {
#[inline]
fn default() -> Self {
MemorySettings {
preallocated_parsing_buffer_size: 1024,
max_allowed_memory_usage: std::usize::MAX,
}
}
}
pub struct Settings<'h, 's> {
pub element_content_handlers: Vec<(Cow<'s, Selector>, ElementContentHandlers<'h>)>,
pub document_content_handlers: Vec<DocumentContentHandlers<'h>>,
pub encoding: AsciiCompatibleEncoding,
pub memory_settings: MemorySettings,
pub strict: bool,
pub enable_esi_tags: bool,
pub adjust_charset_on_meta_tag: bool,
}
impl Default for Settings<'_, '_> {
#[inline]
fn default() -> Self {
Settings {
element_content_handlers: vec![],
document_content_handlers: vec![],
encoding: AsciiCompatibleEncoding(encoding_rs::UTF_8),
memory_settings: MemorySettings::default(),
strict: true,
enable_esi_tags: false,
adjust_charset_on_meta_tag: false,
}
}
}
impl<'h, 's> From<RewriteStrSettings<'h, 's>> for Settings<'h, 's> {
#[inline]
fn from(settings: RewriteStrSettings<'h, 's>) -> Self {
Settings {
element_content_handlers: settings.element_content_handlers,
document_content_handlers: settings.document_content_handlers,
strict: settings.strict,
enable_esi_tags: settings.enable_esi_tags,
..Settings::default()
}
}
}
pub struct RewriteStrSettings<'h, 's> {
pub element_content_handlers: Vec<(Cow<'s, Selector>, ElementContentHandlers<'h>)>,
pub document_content_handlers: Vec<DocumentContentHandlers<'h>>,
pub strict: bool,
pub enable_esi_tags: bool,
}
impl Default for RewriteStrSettings<'_, '_> {
#[inline]
fn default() -> Self {
RewriteStrSettings {
element_content_handlers: vec![],
document_content_handlers: vec![],
strict: true,
enable_esi_tags: true,
}
}
}