use crate::internal::{ast::Family, errors::ParseError, lexer::Token};
pub fn parse_family<'a>(
tokens: &'a [(Token, &'a str)],
pos: &mut usize,
) -> Result<Family, ParseError> {
let (tok, _) = crate::internal::expect::expect(
tokens,
pos,
|t| matches!(t, Token::Gaussian | Token::Binomial | Token::Poisson),
"gaussian | binomial | poisson",
)?;
let fam = match tok {
Token::Gaussian => Family::Gaussian,
Token::Binomial => Family::Binomial,
Token::Poisson => Family::Poisson,
_ => unreachable!(),
};
Ok(fam)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::internal::lexer::Token;
#[test]
fn test_parse_family_gaussian() {
let tokens = vec![
(Token::Gaussian, "gaussian")
];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_ok());
assert_eq!(result.unwrap(), Family::Gaussian);
assert_eq!(pos, 1);
}
#[test]
fn test_parse_family_binomial() {
let tokens = vec![
(Token::Binomial, "binomial")
];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_ok());
assert_eq!(result.unwrap(), Family::Binomial);
assert_eq!(pos, 1);
}
#[test]
fn test_parse_family_poisson() {
let tokens = vec![
(Token::Poisson, "poisson")
];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_ok());
assert_eq!(result.unwrap(), Family::Poisson);
assert_eq!(pos, 1);
}
#[test]
fn test_parse_family_invalid_token() {
let tokens = vec![
(Token::ColumnName, "x")
];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_err());
assert_eq!(pos, 0); }
#[test]
fn test_parse_family_end_of_input() {
let tokens: Vec<(Token, &str)> = vec![];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_err());
assert_eq!(pos, 0); }
#[test]
fn test_parse_family_with_plus_token() {
let tokens = vec![
(Token::Plus, "+")
];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_err());
assert_eq!(pos, 0); }
#[test]
fn test_parse_family_with_tilde_token() {
let tokens = vec![
(Token::Tilde, "~")
];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_err());
assert_eq!(pos, 0); }
#[test]
fn test_parse_family_with_comma_token() {
let tokens = vec![
(Token::Comma, ",")
];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_err());
assert_eq!(pos, 0); }
#[test]
fn test_parse_family_with_equal_token() {
let tokens = vec![
(Token::Equal, "=")
];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_err());
assert_eq!(pos, 0); }
#[test]
fn test_parse_family_with_function_tokens() {
let tokens = vec![
(Token::Poly, "poly")
];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_err());
assert_eq!(pos, 0); }
#[test]
fn test_parse_family_with_numeric_tokens() {
let tokens = vec![
(Token::Integer, "42")
];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_err());
assert_eq!(pos, 0); }
#[test]
fn test_parse_family_with_one_token() {
let tokens = vec![
(Token::One, "1")
];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_err());
assert_eq!(pos, 0); }
#[test]
fn test_parse_family_advances_position_on_success() {
let tokens = vec![
(Token::Gaussian, "gaussian"),
(Token::Comma, ",")
];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_ok());
assert_eq!(result.unwrap(), Family::Gaussian);
assert_eq!(pos, 1); }
#[test]
fn test_parse_family_all_variants() {
let families = vec![
(Token::Gaussian, Family::Gaussian),
(Token::Binomial, Family::Binomial),
(Token::Poisson, Family::Poisson),
];
for (token, expected_family) in families {
let tokens = vec![(token, "dummy")];
let mut pos = 0;
let result = parse_family(&tokens, &mut pos);
assert!(result.is_ok());
assert_eq!(result.unwrap(), expected_family);
assert_eq!(pos, 1);
}
}
}