onefig 1.3.4

The only configuration language you need; a configuration language for configuration files.
Documentation
use flexar::prelude::*;
use crate::{lexer::Token, errors::SyntaxError};
use super::ident::Ident;

#[derive(Debug, Clone)]
pub enum Path {
    Head(Box<str>, Box<Node<Path>>),
    Tail(Box<str>),
}

impl Path {
    pub fn flatten(mut this: Node<Path>) -> Box<[(Position, Box<str>)]> {
        let mut out = Vec::new();
        loop {
            match this.node {
                Path::Tail(x) => { out.push((this.position, x)); break },
                Path::Head(x, y) => {
                    out.push((this.position, x));
                    this = *y;
                }
            }
        }

        out.into_boxed_slice()
    }
}

flexar::parser! {
    [[Path] parxt: Token]
    parse {
        [head: Ident::parse] => {
            (Dot) => {
                [tail: Self::parse] => (Head(head.node.0, Box::new(tail)));
            } (else Err(SY006: parxt.current_token()))
        } (else Ok(Self::Tail(head.node.0)))
    } else Err(SY005: parxt.current_token());

    parse_w_error {
        (Ident(head)) => {
            (Dot) => {
                [tail: Self::parse] => (Head(head.clone(), Box::new(tail)));
            } (else Err(SY006: parxt.current_token()))
        } (else Ok(Self::Tail(head.clone())))
    } else Err(SY009: parxt.current_token(), parxt.current_token());

    path_ident {
        (Ident(x)) => (Tail(x.clone()));
        (Str(x)) => (Tail(x.clone()));
        (Int(x)) => (Tail(x.to_string().into_boxed_str()));
        (Bool(x)) => (Tail(x.to_string().into_boxed_str()));
    } else Err(SY009: parxt.current_token(), parxt.current_token());
}