use winnow::ModalResult as PResult;
use winnow::combinator::{alt, cut_err};
use winnow::prelude::*;
use crate::lexer::Token;
use crate::parser::{ParsedField, Stream, parse_mac, parse_u16, tag};
pub(crate) mod arp;
pub(crate) mod eapol;
pub(crate) mod lacp;
pub(crate) mod lldp;
pub(crate) mod mpls;
pub(crate) mod qinq;
pub(crate) mod stp;
pub(crate) mod vlan;
pub(crate) use arp::*;
pub(crate) use eapol::*;
pub(crate) use lacp::*;
pub(crate) use lldp::*;
pub(crate) use mpls::*;
pub(crate) use qinq::*;
pub(crate) use stp::*;
pub(crate) use vlan::*;
pub(crate) fn parse_l2_field<'i, 'a>(input: &mut Stream<'i, 'a>) -> PResult<ParsedField<'a>> {
alt((
parse_arp_field,
parse_vlan_field,
parse_qinq_field,
parse_lldp_field,
parse_stp_field,
parse_lacp_field,
parse_eapol_field,
parse_mpls_field,
alt((
(tag(Token::SrcMac), cut_err(parse_mac))
.map(|((_, s), v)| ParsedField::SrcMac(v, (s.start, s.end - s.start))),
(tag(Token::DstMac), cut_err(parse_mac))
.map(|((_, s), v)| ParsedField::DstMac(v, (s.start, s.end - s.start))),
(tag(Token::EtherType), cut_err(parse_u16))
.map(|((_, s), v)| ParsedField::EtherType(v, (s.start, s.end - s.start))),
)),
))
.parse_next(input)
}