1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
use std::fmt; use std::fmt::{Display, Formatter}; use joker::track::{Span, TrackingRef}; use expr::Expr; use patt::{Patt, AssignTarget, CompoundPatt, PropPatt}; use obj::{Prop, PropVal}; #[derive(Debug, PartialEq)] pub enum Error { InvalidAssignTarget(Option<Span>), InvalidPropPatt(Option<Span>) } impl Display for Error { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { match self { &Error::InvalidAssignTarget(_) => { fmt.write_str("invalid assignment pattern") } &Error::InvalidPropPatt(_) => { fmt.write_str("invalid object property in assignment pattern") } } } } pub trait IntoAssignPatt { fn into_assign_patt(self) -> Result<Patt<AssignTarget>, Error>; } impl IntoAssignPatt for Expr { fn into_assign_patt(self) -> Result<Patt<AssignTarget>, Error> { Ok(match self { Expr::Id(id) => Patt::Simple(AssignTarget::Id(id)), Expr::Dot(location, obj, key) => Patt::Simple(AssignTarget::Dot(location, obj, key)), Expr::Brack(location, obj, prop) => Patt::Simple(AssignTarget::Brack(location, obj, prop)), Expr::Obj(location, props) => { let mut prop_patts = Vec::with_capacity(props.len()); for prop in props { prop_patts.push(try!(prop.into_assign_prop())); } Patt::Compound(CompoundPatt::Obj(location, prop_patts)) } Expr::Arr(location, exprs) => { let mut patts = Vec::with_capacity(exprs.len()); for expr in exprs { patts.push(match expr { Some(expr) => Some(try!(expr.into_assign_patt())), None => None }); } Patt::Compound(CompoundPatt::Arr(location, patts)) } _ => { return Err(Error::InvalidAssignTarget(*self.tracking_ref())); } }) } } pub trait IntoAssignProp { fn into_assign_prop(self) -> Result<PropPatt<AssignTarget>, Error>; } impl IntoAssignProp for Prop { fn into_assign_prop(self) -> Result<PropPatt<AssignTarget>, Error> { let location = *self.tracking_ref(); let key = self.key; let patt = match self.val { PropVal::Init(expr) => try!(expr.into_assign_patt()), _ => { return Err(Error::InvalidPropPatt(*self.val.tracking_ref())); } }; Ok(PropPatt { location: location, key: key, patt: patt }) } }