use chumsky::prelude::*;
use crate::typ::Type;
use super::types::{Extra, MapExtra};
pub fn parser<'a>() -> impl Parser<'a, &'a str, &'a Type<'a>, Extra<'a>> {
recursive(|rec_typ| {
choice((
text::keyword("integer")
.ignored()
.map_with(|_, e: &mut MapExtra<'a, '_>| {
let state = e.state();
Type::integer(state.arena)
}),
text::keyword("bool")
.ignored()
.map_with(|_, e: &mut MapExtra<'a, '_>| {
let state = e.state();
Type::bool(state.arena)
}),
text::keyword("bytestring")
.ignored()
.map_with(|_, e: &mut MapExtra<'a, '_>| {
let state = e.state();
Type::byte_string(state.arena)
}),
text::keyword("string")
.ignored()
.map_with(|_, e: &mut MapExtra<'a, '_>| {
let state = e.state();
Type::string(state.arena)
}),
text::keyword("pair")
.padded()
.ignore_then(rec_typ.clone().padded())
.then(rec_typ.clone().padded())
.delimited_by(just('('), just(')'))
.map_with(|(fst_type, snd_type), e: &mut MapExtra<'a, '_>| {
let state = e.state();
Type::pair(state.arena, fst_type, snd_type)
}),
text::keyword("list")
.padded()
.ignore_then(rec_typ.clone().padded())
.delimited_by(just('('), just(')'))
.map_with(|typ, e: &mut MapExtra<'a, '_>| {
let state = e.state();
Type::list(state.arena, typ)
}),
text::keyword("array")
.padded()
.ignore_then(rec_typ.clone().padded())
.delimited_by(just('('), just(')'))
.map_with(|typ, e: &mut MapExtra<'a, '_>| {
let state = e.state();
Type::array(state.arena, typ)
}),
text::keyword("data")
.ignored()
.map_with(|_, e: &mut MapExtra<'a, '_>| {
let state = e.state();
Type::data(state.arena)
}),
text::keyword("unit")
.ignored()
.map_with(|_, e: &mut MapExtra<'a, '_>| {
let state = e.state();
Type::unit(state.arena)
}),
text::keyword("bls12_381_G1_element").ignored().map_with(
|_, e: &mut MapExtra<'a, '_>| {
let state = e.state();
Type::g1(state.arena)
},
),
text::keyword("bls12_381_G2_element").ignored().map_with(
|_, e: &mut MapExtra<'a, '_>| {
let state = e.state();
Type::g2(state.arena)
},
),
))
.boxed()
})
}