#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum OtherOperator {
Parentheses,
FieldSeparator,
IndexRange,
Subscript,
Separator,
Conditional,
ArrayConstant,
LineComment,
LineCommentBasic,
BlockComment,
}
impl OtherOperator {
pub const ALL: [Self; 10] = [
Self::Parentheses,
Self::FieldSeparator,
Self::IndexRange,
Self::Subscript,
Self::Separator,
Self::Conditional,
Self::ArrayConstant,
Self::LineComment,
Self::LineCommentBasic,
Self::BlockComment,
];
#[must_use]
pub const fn symbol(self) -> &'static str {
match self {
Self::Parentheses => "()",
Self::FieldSeparator => ".",
Self::IndexRange => "..",
Self::Subscript => "[]",
Self::Separator => ",",
Self::Conditional => "?:",
Self::ArrayConstant => "{}",
Self::LineComment => "//",
Self::LineCommentBasic => "'",
Self::BlockComment => "/* */",
}
}
#[must_use]
pub const fn is_comment(self) -> bool {
matches!(
self,
Self::LineComment | Self::LineCommentBasic | Self::BlockComment
)
}
}
#[cfg(test)]
mod tests {
use super::OtherOperator;
#[test]
fn comments_are_identified_as_such() {
assert!(OtherOperator::LineComment.is_comment());
assert!(OtherOperator::BlockComment.is_comment());
assert!(!OtherOperator::Subscript.is_comment());
}
#[test]
fn the_range_and_field_separators_are_distinguishable() {
assert_eq!(OtherOperator::FieldSeparator.symbol(), ".");
assert_eq!(OtherOperator::IndexRange.symbol(), "..");
assert_ne!(
OtherOperator::FieldSeparator.symbol(),
OtherOperator::IndexRange.symbol()
);
}
#[test]
fn every_element_has_a_distinct_spelling() {
let mut symbols: Vec<&str> = OtherOperator::ALL.iter().map(|op| op.symbol()).collect();
symbols.sort_unstable();
let count = symbols.len();
symbols.dedup();
assert_eq!(symbols.len(), count);
}
}