use crate::parser::Parser;
use plugx_input::Input;
use std::fmt::{Debug, Display, Formatter};
pub type BoxedParserFn = Box<dyn Fn(&[u8]) -> anyhow::Result<Input> + Send + Sync>;
pub type BoxedValidatorFn = Box<dyn Fn(&[u8]) -> Option<bool> + Send + Sync>;
pub struct Closure {
name: String,
parser: BoxedParserFn,
validator: BoxedValidatorFn,
supported_format_list: Vec<String>,
}
impl Display for Closure {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(self.name.as_str())
}
}
impl Debug for Closure {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ConfigurationParserFn")
.field("name", &self.name)
.field("supported_format_list", &self.supported_format_list)
.finish()
}
}
impl Closure {
pub fn new<N: AsRef<str>, F: AsRef<str>>(
name: N,
supported_format: F,
parser: BoxedParserFn,
) -> Self {
Self {
name: name.as_ref().to_string(),
parser,
validator: Box::new(|_| None),
supported_format_list: [supported_format.as_ref().to_string()].to_vec(),
}
}
pub fn set_parser(&mut self, parser: BoxedParserFn) {
self.parser = parser;
}
pub fn with_parser(mut self, parser: BoxedParserFn) -> Self {
self.set_parser(parser);
self
}
pub fn set_validator(&mut self, validator: BoxedValidatorFn) {
self.validator = validator;
}
pub fn with_validator(mut self, validator: BoxedValidatorFn) -> Self {
self.set_validator(validator);
self
}
pub fn set_format_list<N: AsRef<str>>(&mut self, format_list: &[N]) {
self.supported_format_list = format_list
.iter()
.map(|format| format.as_ref().to_string())
.collect();
}
pub fn with_format_list<N: AsRef<str>>(mut self, format_list: &[N]) -> Self {
self.set_format_list(format_list);
self
}
}
impl Parser for Closure {
fn supported_format_list(&self) -> Vec<String> {
self.supported_format_list.clone()
}
fn try_parse(&self, bytes: &[u8]) -> anyhow::Result<Input> {
(self.parser)(bytes)
}
fn is_format_supported(&self, bytes: &[u8]) -> Option<bool> {
(self.validator)(bytes)
}
}