#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ComparisonOp {
Lt,
Gt,
Le,
Ge,
Eq,
}
#[derive(Debug, Clone, PartialEq)]
pub enum SelectionExpr {
Chain(String),
Name(String),
Resname(String),
Resid(i32),
ResidRange {
start: i32,
end: i32,
},
Element(String),
Bfactor(ComparisonOp, f64),
Occupancy(ComparisonOp, f64),
Backbone,
Protein,
Nucleic,
Water,
Hetero,
Hydrogen,
And(Box<SelectionExpr>, Box<SelectionExpr>),
Or(Box<SelectionExpr>, Box<SelectionExpr>),
Not(Box<SelectionExpr>),
All,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ast_construction() {
let expr = SelectionExpr::And(
Box::new(SelectionExpr::Chain("A".to_string())),
Box::new(SelectionExpr::Name("CA".to_string())),
);
assert!(matches!(expr, SelectionExpr::And(_, _)));
}
#[test]
fn test_resid_range() {
let expr = SelectionExpr::ResidRange { start: 1, end: 100 };
if let SelectionExpr::ResidRange { start, end } = expr {
assert_eq!(start, 1);
assert_eq!(end, 100);
} else {
panic!("Expected ResidRange");
}
}
#[test]
fn test_comparison_op() {
let expr = SelectionExpr::Bfactor(ComparisonOp::Lt, 30.0);
if let SelectionExpr::Bfactor(op, val) = expr {
assert_eq!(op, ComparisonOp::Lt);
assert!((val - 30.0).abs() < f64::EPSILON);
} else {
panic!("Expected Bfactor");
}
}
}