use std::{error, fmt::Display, str::FromStr};
use crate::parsing;
use nom::{branch::permutation, combinator::opt};
use num::{Float, Integer};
use serde::de::{self, DeserializeSeed, MapAccess, SeqAccess, Visitor};
use serde::Deserialize;
#[cfg(test)]
use std::collections::HashMap;
#[derive(Eq, PartialEq)]
enum DataType {
STRUCT,
HASHMAP,
SEQ,
}
#[derive(Debug)]
pub struct JaclDeError;
impl Display for JaclDeError {
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
unreachable!();
}
}
impl error::Error for JaclDeError {}
impl de::Error for JaclDeError {
fn custom<T>(_: T) -> Self
where
T: std::fmt::Display,
{
unreachable!();
}
}
pub struct Deserializer<'de> {
pre: Option<char>,
input: &'de str,
post: Option<char>,
}
impl<'de> Deserializer<'de> {
pub fn from_str(input: &'de str) -> Self {
let mut d = Deserializer {
pre: None,
input,
post: None,
};
if d.try_parse_literal() {
if d.try_parse_literal() {
println!("here {}", input);
return Deserializer {
pre: Some('['),
input,
post: Some(']'),
};
} else if let Ok(delim) = d.parse_delim() {
if delim == ':' {
return Deserializer {
pre: Some('{'),
input,
post: Some('}'),
};
}
}
} else if let Ok(_) = d.parse_identifier() {
return Deserializer {
pre: Some('('),
input,
post: Some(')'),
};
}
return Deserializer {
pre: None,
input,
post: None,
};
}
fn try_parse_literal(&mut self) -> bool {
if let Ok(_) = self.parse_bool() {
return true;
}
if let Ok(_) = self.parse_float::<f32>() {
return true;
}
if let Ok(_) = self.parse_int::<i64>() {
return true;
}
if let Ok(_) = self.parse_string() {
return true;
}
return false;
}
}
pub fn from_str<'a, T>(s: &'a str) -> Result<T, JaclDeError>
where
T: Deserialize<'a>,
{
let mut deserializer = Deserializer::from_str(s);
let t = T::deserialize(&mut deserializer)?;
if deserializer.input.is_empty() {
Ok(t)
} else {
Err(JaclDeError)
}
}
impl<'de> Deserializer<'de> {
fn skip_non_tokens(&mut self) -> Result<(), JaclDeError> {
if self.pre.is_some() {
return Err(JaclDeError);
}
self.input = permutation((
opt(parsing::comment::multiline_comment),
opt(parsing::comment::eol_comment),
opt(parsing::whitespace),
))(self.input)
.unwrap_or((self.input, (Some(()), Some(()), Some(()))))
.0;
return Ok(());
}
fn parse_bool(&mut self) -> Result<bool, JaclDeError> {
self.skip_non_tokens()?;
match parsing::literal::boolean(self.input) {
Ok((inp, b)) => {
self.input = inp;
return Ok(b);
}
Err(_) => Err(JaclDeError),
}
}
fn parse_int<T: Integer + FromStr>(&mut self) -> Result<T, JaclDeError> {
self.skip_non_tokens()?;
match parsing::literal::integer(self.input) {
Ok((inp, i)) => {
self.input = inp;
return Ok(i);
}
Err(_) => Err(JaclDeError),
}
}
fn parse_float<T: Float + FromStr>(&mut self) -> Result<T, JaclDeError> {
self.skip_non_tokens()?;
match parsing::literal::float(self.input) {
Ok((inp, f)) => {
self.input = inp;
return Ok(f);
}
Err(_) => Err(JaclDeError),
}
}
fn parse_string(&mut self) -> Result<String, JaclDeError> {
self.skip_non_tokens()?;
match parsing::string::string(self.input) {
Ok((inp, st)) => {
return match st {
Ok(s) => {
self.input = inp;
return Ok(s);
}
Err(_) => Err(JaclDeError),
}
}
Err(_) => Err(JaclDeError),
}
}
fn parse_delim(&mut self) -> Result<char, JaclDeError> {
if let Some(c) = self.pre {
self.pre = None;
return Ok(c);
}
self.skip_non_tokens()?;
if self.input.len() == 0 {
if let Some(c) = self.post {
self.post = None;
return Ok(c);
} else {
return Err(JaclDeError);
}
}
match parsing::delimiter(self.input) {
Ok((inp, c)) => {
self.input = inp;
return Ok(c);
}
Err(_) => Err(JaclDeError),
}
}
fn parse_identifier(&mut self) -> Result<&str, JaclDeError> {
self.skip_non_tokens()?;
match parsing::identifier(self.input) {
Ok((inp, s)) => {
self.input = inp;
return Ok(s);
}
Err(_) => Err(JaclDeError),
}
}
}
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
type Error = JaclDeError;
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
return Err(JaclDeError);
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_bool(self.parse_bool()?)
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_i8(self.parse_int()?)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_i16(self.parse_int()?)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_i32(self.parse_int()?)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_i64(self.parse_int()?)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_u8(self.parse_int()?)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_u16(self.parse_int()?)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_u32(self.parse_int()?)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_u64(self.parse_int()?)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_f32(self.parse_float()?)
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_f32(self.parse_float()?)
}
fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
unimplemented!();
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_string(self.parse_string()?)
}
fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
self.skip_non_tokens()?;
if self.input.starts_with("null") {
self.input = &self.input["null".len()..];
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
self.skip_non_tokens()?;
if self.input.starts_with("null") {
self.input = &self.input["null".len()..];
visitor.visit_unit()
} else {
Err(JaclDeError)
}
}
fn deserialize_unit_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
self.deserialize_unit(visitor)
}
fn deserialize_newtype_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
if self.parse_delim()? == '[' {
return visitor.visit_seq(Separated::new(&mut self, DataType::SEQ));
} else {
Err(JaclDeError)
}
}
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(
self,
_name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_map<V>(mut self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
if self.parse_delim()? == '{' {
return visitor.visit_map(Separated::new(&mut self, DataType::HASHMAP));
} else {
Err(JaclDeError)
}
}
fn deserialize_struct<V>(
mut self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
if self.parse_delim()? == '(' {
return visitor.visit_map(Separated::new(&mut self, DataType::STRUCT));
} else {
Err(JaclDeError)
}
}
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
_visitor: V,
) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
unimplemented!();
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
visitor.visit_str(self.parse_identifier()?)
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, JaclDeError>
where
V: Visitor<'de>,
{
self.deserialize_any(visitor)
}
}
struct Separated<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
datatype: DataType,
}
impl<'a, 'de> Separated<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>, datatype: DataType) -> Self {
Separated { de, datatype }
}
}
impl<'de, 'a> SeqAccess<'de> for Separated<'a, 'de> {
type Error = JaclDeError;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, JaclDeError>
where
T: DeserializeSeed<'de>,
{
if let Ok(val) = self.de.parse_delim() {
if val == ']' {
return Ok(None);
} else {
return Err(JaclDeError);
}
}
seed.deserialize(&mut *self.de).map(Some)
}
}
impl<'de, 'a> MapAccess<'de> for Separated<'a, 'de> {
type Error = JaclDeError;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, JaclDeError>
where
K: DeserializeSeed<'de>,
{
if let Ok(val) = self.de.parse_delim() {
if (val == '}' && self.datatype == DataType::HASHMAP)
|| (val == ')' && self.datatype == DataType::STRUCT)
{
return Ok(None);
} else {
return Err(JaclDeError);
}
}
seed.deserialize(&mut *self.de).map(Some)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, JaclDeError>
where
V: DeserializeSeed<'de>,
{
if let Ok(val) = self.de.parse_delim() {
if val == ':' {
return seed.deserialize(&mut *self.de);
} else {
return Err(JaclDeError);
}
} else {
return Err(JaclDeError);
}
}
}
#[test]
fn test_struct() {
#[derive(Deserialize, PartialEq, Debug)]
struct Test {
int: u32,
vec: Vec<String>,
map: HashMap<String, Test>,
}
let j = r#"
(
int : 1
vec : ["hello","world",]
map : {
"hello" : (
int : 17
vec : ["hello",,,,,
"world",,, ]
map: {}
)
}
)"#;
let vec = vec!["hello".to_string(), "world".to_string()];
let inner = Test {
int: 17,
vec: vec.clone(),
map: HashMap::new(),
};
let mut map = HashMap::new();
map.insert("hello".to_string(), inner);
let expected = Test {
int: 1,
vec: vec.clone(),
map,
};
assert_eq!(expected, from_str(j).unwrap());
}
#[test]
fn test_vec() {
let v: Vec<u8> = vec![1, 2, 3, 4];
assert_eq!(v, from_str::<Vec<u8>>("1 2 3 4,").unwrap());
let v: Vec<String> = vec!["hello".to_string(), "world".to_string()];
assert_eq!(
v,
from_str::<Vec<String>>(r#" "hello" "world" "#).unwrap()
);
}
#[test]
fn test_comments() {
let v: Vec<u8> = vec![1, 2, 3, 4];
assert_eq!(
v,
from_str::<Vec<u8>>(
"
// single line comment
1
2
/* multiline
comment */
3
4
"
)
.unwrap()
);
}