use std::{convert::Infallible, str::FromStr};
use crate::{
ast::{
node::{roots::Roots, TypeExpr},
RootEntry, Value,
},
parse::Span,
Spanned,
};
mod kind;
pub use kind::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FileKind {
Prop,
Patch,
Unknown,
}
impl FromStr for FileKind {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"PROP" => Self::Prop,
"PTCH" => Self::Patch,
_ => Self::Unknown,
})
}
}
#[derive(Debug, Clone, Copy)]
pub struct KnownRoot<V> {
pub(crate) idx: usize,
pub value: V,
}
impl<V> KnownRoot<V> {
pub fn original<'a>(&self, roots: &'a Roots) -> &'a Root {
&roots.all[self.idx]
}
pub fn into_inner(self) -> V {
self.value
}
}
#[derive(Debug, Clone)]
pub struct Root {
pub idx: usize,
pub name: Spanned<RootKind>,
pub type_expr: Spanned<Option<TypeExpr>>,
pub value: Option<RootValue>,
}
impl Root {
#[inline(always)]
#[must_use]
pub fn span(&self) -> Span {
self.name.span.cover(
self.value
.as_ref()
.map(RootValue::span)
.unwrap_or(self.type_expr.span),
)
}
}
#[derive(Debug, Clone)]
pub enum RootValue {
Value(Value),
Entries(Spanned<Vec<RootEntry>>),
}
impl RootValue {
pub fn as_value(&self) -> Option<&Value> {
match self {
RootValue::Value(v) => Some(v),
_ => None,
}
}
pub fn span(&self) -> Span {
match self {
RootValue::Value(v) => v.span(),
RootValue::Entries(e) => e.span,
}
}
}