pub mod impls;
pub mod parser;
use std::{hash::Hash, fmt::Display};
use nom::{error::Error, IResult};
pub type SimpleWrapper = String;
pub type ComplexWrapper = Vec<Vec<String>>;
#[derive(Debug,Clone,Default)]
pub struct GroupWrapper{
pub title: Vec<String>,
pub attr_list: Vec<(String, AttriValue)>,
}
pub type UndefinedAttributes=Vec<(String, AttriValue)>;
#[derive(Debug,Clone)]
pub enum AttriValue {
Simple(SimpleWrapper),
Complex(ComplexWrapper),
Group(GroupWrapper),
}
pub trait SimpleAttri: Sized + Display{
type Error: std::error::Error;
fn parse(s: &str)->Result<Self, Self::Error>;
#[inline]
fn nom_parse<'a>(i: &'a str, line_num: &mut usize) -> IResult<&'a str, Result<Self,(Self::Error,AttriValue)>, Error<&'a str>>{
let (input,simple) = parser::simple(i,line_num)?;
match Self::parse(simple){
Ok(s) => Ok((input,Ok(s))),
Err(e) => Ok((
input,
Err((e,AttriValue::Simple(simple.to_string())))
)),
}
}
#[inline]
fn to_wrapper(&self) -> SimpleWrapper{
format!("{self}")
}
}
pub trait ComplexAttri: Sized {
type Error: std::error::Error;
fn parse(v: &Vec<Vec<&str>>)->Result<Self,Self::Error>;
fn to_wrapper(&self) -> ComplexWrapper;
fn is_empty(&self) -> bool;
#[inline]
fn nom_parse<'a>(i: &'a str, line_num: &mut usize) -> IResult<&'a str, Result<Self,(Self::Error,AttriValue)>, Error<&'a str>>{
let (input,complex) = parser::complex(i,line_num)?;
match Self::parse(&complex){
Ok(s) => Ok((input,Ok(s))),
Err(e) => Ok((
input,
Err((e, AttriValue::Complex(
complex.into_iter()
.map(|vec_string| vec_string.into_iter().map(|s| s.to_string()).collect())
.collect()
)))
)),
}
}
}
pub trait HashedGroup: Sized {
type Idx: Sized+Hash;
fn title(&self) -> Vec<String>;
fn idx(&self) -> Self::Idx;
fn gen_idx(&self, title: Vec<String>) -> Result<Self::Idx,IdxError>;
}
pub trait GroupAttri: Sized {
type Set;
fn add_undefine_attri(&mut self, key: &str, attri: AttriValue);
fn nom_parse<'a>(i: &'a str, line_num: &mut usize) -> IResult<&'a str, Result<Self,IdxError>, Error<&'a str>>;
fn to_wrapper(&self) -> GroupWrapper;
}
#[derive(Debug)]
#[derive(thiserror::Error)]
pub enum IdxError {
#[error("title length mismatch (want={0},got={1}), title={2:?}")]
TitleLenMismatch(usize,usize,Vec<String>),
#[error("replace same idx")]
RepeatIdx,
#[error("{0}")]
Other(String),
}
#[derive(Debug)]
#[derive(thiserror::Error)]
pub enum ParserError<'a> {
#[error("Line:{0}, error:{1}")]
IdxError(usize,IdxError),
#[error("replace same idx")]
NomError(usize,nom::Err<Error<&'a str>>),
#[error("{0}")]
Other(usize,String),
}