use crate::ast::{DefinitionBody, MetadataDef, Node};
use crate::parser::lex::{
identification, skip_until_brace_end, take_until_terminator, ws1, ws_and_comments,
};
use crate::parser::node_from_to;
use crate::parser::Input;
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::combinator::{map, opt};
use nom::sequence::preceded;
use nom::IResult;
use nom::Parser;
fn definition_body(input: Input<'_>) -> IResult<Input<'_>, DefinitionBody> {
let (input, _) = ws_and_comments(input)?;
alt((
map(tag(&b";"[..]), |_| DefinitionBody::Semicolon),
map(
nom::sequence::delimited(
tag(&b"{"[..]),
skip_until_brace_end,
preceded(ws_and_comments, tag(&b"}"[..])),
),
|_| DefinitionBody::Brace,
),
))
.parse(input)
}
pub(crate) fn metadata_def(input: Input<'_>) -> IResult<Input<'_>, Node<MetadataDef>> {
let start = input;
let (input, _) = ws_and_comments(input)?;
let (input, is_abstract) = opt(preceded(tag(&b"abstract"[..]), ws1))
.parse(input)
.map(|(i, o)| (i, o.is_some()))?;
let (input, _) = tag(&b"metadata"[..]).parse(input)?;
let (input, _) = ws1(input)?;
let (input, _) = tag(&b"def"[..]).parse(input)?;
let (input, _) = ws1(input)?;
let (input, identification) = identification(input)?;
let (input, _) = ws_and_comments(input)?;
let (input, _) = take_until_terminator(input, b";{")?;
let (input, body) = definition_body(input)?;
Ok((
input,
node_from_to(
start,
input,
MetadataDef {
is_abstract,
identification,
body,
},
),
))
}