use crate::spanned::expr::{Expr, Prop};
use crate::spanned::Ident;
use super::{AssignOp, ListEntry, Node, Slice, SourceLocation};
#[derive(Debug, Clone, PartialEq)]
pub enum Pat<'a> {
Ident(Ident<'a>),
Obj(ObjPat<'a>),
Array(ArrayPat<'a>),
Assign(AssignPat<'a>),
}
impl<'a> From<Pat<'a>> for crate::pat::Pat<'a> {
fn from(other: Pat<'a>) -> Self {
match other {
Pat::Ident(inner) => Self::Ident(inner.into()),
Pat::Obj(inner) => Self::Obj(inner.into()),
Pat::Array(inner) => Self::Array(inner.into()),
Pat::Assign(inner) => Self::Assign(inner.into()),
}
}
}
impl<'a> Node for Pat<'a> {
fn loc(&self) -> super::SourceLocation {
match self {
Pat::Ident(inner) => inner.loc(),
Pat::Obj(inner) => inner.loc(),
Pat::Array(inner) => inner.loc(),
Pat::Assign(inner) => inner.loc(),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ArrayPat<'a> {
pub open_bracket: Slice<'a>,
pub elements: Vec<ListEntry<'a, Option<ArrayPatPart<'a>>>>,
pub close_bracket: Slice<'a>,
}
impl<'a> Node for ArrayPat<'a> {
fn loc(&self) -> super::SourceLocation {
SourceLocation {
start: self.open_bracket.loc.start,
end: self.close_bracket.loc.end,
}
}
}
impl<'a> From<ArrayPat<'a>> for Vec<Option<crate::pat::ArrayPatPart<'a>>> {
fn from(other: ArrayPat<'a>) -> Self {
other
.elements
.into_iter()
.map(|e| e.item.map(Into::into))
.collect()
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ArrayElement<'a> {
pub part: Option<ArrayPatPart<'a>>,
pub comma: Option<Slice<'a>>,
}
impl<'a> From<ArrayElement<'a>> for Option<crate::pat::ArrayPatPart<'a>> {
fn from(other: ArrayElement<'a>) -> Self {
other.part.map(From::from)
}
}
#[derive(PartialEq, Debug, Clone)]
pub enum ArrayPatPart<'a> {
Pat(Pat<'a>),
Expr(Expr<'a>),
Rest(RestPat<'a>),
}
impl<'a> From<ArrayPatPart<'a>> for crate::pat::ArrayPatPart<'a> {
fn from(other: ArrayPatPart<'a>) -> Self {
match other {
ArrayPatPart::Pat(inner) => Self::Pat(inner.into()),
ArrayPatPart::Expr(inner) => Self::Expr(inner.into()),
ArrayPatPart::Rest(inner) => {
Self::Pat(crate::pat::Pat::RestElement(Box::new(inner.pat.into())))
}
}
}
}
impl<'a> Node for ArrayPatPart<'a> {
fn loc(&self) -> SourceLocation {
match self {
ArrayPatPart::Pat(inner) => inner.loc(),
ArrayPatPart::Expr(inner) => inner.loc(),
ArrayPatPart::Rest(inner) => inner.loc(),
}
}
}
type ObjEntry<'a> = ListEntry<'a, ObjPatPart<'a>>;
#[derive(PartialEq, Debug, Clone)]
pub struct ObjPat<'a> {
pub open_brace: Slice<'a>,
pub props: Vec<ObjEntry<'a>>,
pub close_brace: Slice<'a>,
}
impl<'a> Node for ObjPat<'a> {
fn loc(&self) -> SourceLocation {
SourceLocation {
start: self.open_brace.loc.start,
end: self.close_brace.loc.end,
}
}
}
impl<'a> From<ObjPat<'a>> for crate::pat::ObjPat<'a> {
fn from(other: ObjPat<'a>) -> Self {
other.props.into_iter().map(|e| e.item.into()).collect()
}
}
#[derive(PartialEq, Debug, Clone)]
pub enum ObjPatPart<'a> {
Assign(Prop<'a>),
Rest(Box<RestPat<'a>>),
}
impl<'a> Node for ObjPatPart<'a> {
fn loc(&self) -> SourceLocation {
match self {
ObjPatPart::Assign(prop) => prop.loc(),
ObjPatPart::Rest(inner) => inner.loc(),
}
}
}
impl<'a> From<ObjPatPart<'a>> for crate::pat::ObjPatPart<'a> {
fn from(other: ObjPatPart<'a>) -> Self {
match other {
ObjPatPart::Assign(prop) => Self::Assign(prop.into()),
ObjPatPart::Rest(inner) => Self::Rest(Box::new(From::from(inner.pat))),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct RestPat<'a> {
pub dots: Slice<'a>,
pub pat: Pat<'a>,
}
impl<'a> Node for RestPat<'a> {
fn loc(&self) -> SourceLocation {
SourceLocation {
start: self.dots.loc.start,
end: self.pat.loc().end,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct AssignPat<'a> {
pub left: Box<Pat<'a>>,
pub operator: AssignOp<'a>,
pub right: Box<Expr<'a>>,
}
impl<'a> Node for AssignPat<'a> {
fn loc(&self) -> SourceLocation {
SourceLocation {
start: self.left.loc().start,
end: self.right.loc().end,
}
}
}
impl<'a> From<AssignPat<'a>> for crate::pat::AssignPat<'a> {
fn from(other: AssignPat<'a>) -> Self {
Self {
left: Box::new(From::from(*other.left)),
right: Box::new(From::from(*other.right)),
}
}
}