I'm using AsRef<T>
and AsMut<T>
to expose an wrapped value in an enum. Can anyone tell me if this is an anti-pattern? I came across Is it considered a bad practice to implement Deref for newtypes?, and it convinced me that Deref
would be a bad idea, but I'm not sure about the approach below.
pub enum Node {
Stmt(Statement),
Expr(Expression),
}
impl AsMut<Expression> for Node {
fn as_mut(&mut self) -> &mut Expression {
match self {
Node::Stmt(_) => panic!("fatal: expected Expression"),
Node::Expr(e) => e,
}
}
}
impl AsMut<Expression> for Box<Node> {
fn as_mut(&mut self) -> &mut Expression {
(**self).as_mut()
}
}
impl AsMut<Expression> for Expression {
fn as_mut(&mut self) -> &mut Expression {
self
}
}
fn check_binop<T: AsMut<Expression>>(
&mut self,
sym: Symbol,
lhs: &mut T,
rhs: &mut T,
ty: &mut Option<Type>,
) -> Result<Type, String> {
let lhs = lhs.as_mut();
let rhs = rhs.as_mut();
...
}
I'm considering just making my own traits (AsExpr<T>
and AsExprMut<T>
) that are just re-implementations of AsRef<T>
and AsMut<T>
. Functionally no different, but I think it would be clearer.