use std::collections::LinkedList; use crate::{token::Literal, join}; use super::{Identifier, value::Value}; #[derive(Clone, Debug)] pub enum Pattern { Literal(Literal), Binding(Identifier), Variant(Identifier, Vec), } impl Pattern { pub fn matches<'a, 'b>(&'a self, value: &'b Value) -> Option> { match (value, self) { (Value::Int(x1), Pattern::Literal(Literal::Int(x2))) => if *x1 as u64 == *x2 { Some(LinkedList::new()) } else { None }, (Value::Structural(ident1, values1), Pattern::Variant(ident2, patterns2)) => if ident1 == ident2 && values1.len() == patterns2.len() { values1.into_iter() .zip(patterns2) .fold(Some(LinkedList::new()), |bindings, (v1, p2)| bindings.and_then(|bindings| p2.matches(v1).map(|new_bindings| join( bindings, new_bindings, ) ) ) ) } else { None }, _ => None, } } }