fosk 0.1.13

In-memory SQL-like query engine and lightweight data store for testing and prototyping.
Documentation
#[derive(Debug, Default, Clone)]
pub enum ExpansionChain {
    #[default]
    None,
    Single(String),
    Child(String, Box<ExpansionChain>),
}

impl From<&str> for ExpansionChain {
    fn from(value: &str) -> Self {
        let parts: Vec<_> = value.split(".").collect();
        let mut last = None;
        for part in parts.iter().rev() {
            if !part.is_empty() {
                last = match last {
                    Some(exp) => Some(ExpansionChain::Child(part.to_string(), Box::new(exp))),
                    None => Some(ExpansionChain::Single(part.to_string())),
                }
            }
        }

        match last {
            Some(expansion_type) => expansion_type,
            None => ExpansionChain::None,
        }
    }
}

#[cfg(test)]
mod test {
    use super::ExpansionChain;

    #[test]
    fn test_from_single() {
        let exp = ExpansionChain::from("orders");
        if let ExpansionChain::Single(s) = exp {
            assert_eq!(s, "orders");
        } else {
            panic!("Expected ExpansionChain::Single variant");
        }
    }

    #[test]
    fn test_from_two_levels() {
        let exp = ExpansionChain::from("orders.order_items");
        if let ExpansionChain::Child(p1, boxed) = exp {
            assert_eq!(p1, "orders");
            if let ExpansionChain::Single(s) = *boxed {
                assert_eq!(s, "order_items");
            } else {
                panic!("Expected nested ExpansionChain::Single variant");
            }
        } else {
            panic!("Expected ExpansionChain::Child variant");
        }
    }

    #[test]
    fn test_from_three_levels() {
        let exp = ExpansionChain::from("orders.order_items.products");
        if let ExpansionChain::Child(p1, boxed1) = exp {
            assert_eq!(p1, "orders");
            if let ExpansionChain::Child(p2, boxed2) = *boxed1 {
                assert_eq!(p2, "order_items");
                if let ExpansionChain::Single(s) = *boxed2 {
                    assert_eq!(s, "products");
                } else {
                    panic!("Expected innermost ExpansionChain::Single variant");
                }
            } else {
                panic!("Expected nested ExpansionChain::Child variant");
            }
        } else {
            panic!("Expected root ExpansionChain::Child variant");
        }
    }

    #[test]
    fn test_from_empty() {
        let exp = ExpansionChain::from("");
        match exp {
            ExpansionChain::None => {},
            _ => panic!("Expected ExpansionChain::None variant for empty input"),
        }
    }
}