use alloc::boxed::Box;
use oxc_ast::ast::{Expression, FormalParameter};
use vize_l0::Span;
use vize_l1::embed::syntax::{NativeForHead, NativeForRefusal};
use vize_l1::embed::{EmbedSource, SourceError};
use crate::resolution::source::ForReferenceSource;
#[derive(Debug)]
pub struct RejectedForHeadInput<'a> {
syntax: NativeForHead<'a>,
pub kind: NativeForRefusal,
pub span: Span,
}
impl<'a> RejectedForHeadInput<'a> {
#[must_use]
pub const fn syntax(&self) -> &NativeForHead<'a> {
&self.syntax
}
#[must_use]
pub fn into_syntax(self) -> NativeForHead<'a> {
self.syntax
}
}
#[derive(Debug)]
pub struct ForHeadInput<'a> {
syntax: NativeForHead<'a>,
aliases: &'a [FormalParameter<'a>],
collection: &'a Expression<'a>,
}
impl<'a> ForHeadInput<'a> {
pub fn new(syntax: NativeForHead<'a>) -> Result<Self, Box<RejectedForHeadInput<'a>>> {
let roots = ForReferenceSource::checked(&syntax)
.map(|source| (source.aliases(), source.collection()));
let Some((aliases, collection)) = roots else {
return Err(Box::new(RejectedForHeadInput {
kind: syntax
.native_refusal()
.unwrap_or(NativeForRefusal::StockProfile),
span: syntax.source().span(),
syntax,
}));
};
Ok(Self {
syntax,
aliases,
collection,
})
}
#[must_use]
pub const fn syntax(&self) -> &NativeForHead<'a> {
&self.syntax
}
#[must_use]
pub fn source(&self) -> EmbedSource<'a> {
self.syntax.source()
}
#[must_use]
pub const fn aliases(&self) -> &'a [FormalParameter<'a>] {
self.aliases
}
#[must_use]
pub const fn collection(&self) -> &'a Expression<'a> {
self.collection
}
pub fn alias_decoded_span(&self, span: oxc_span::Span) -> Result<Span, SourceError> {
self.references()
.ok_or(SourceError::InvalidDecodedSpan)?
.alias_decoded_span(span)
}
pub fn alias_authored_span(&self, span: oxc_span::Span) -> Result<Span, SourceError> {
self.references()
.ok_or(SourceError::InvalidDecodedSpan)?
.alias_authored_span(span)
}
pub fn collection_decoded_span(&self, span: oxc_span::Span) -> Result<Span, SourceError> {
self.references()
.ok_or(SourceError::InvalidDecodedSpan)?
.collection_decoded_span(span)
}
pub fn collection_authored_span(&self, span: oxc_span::Span) -> Result<Span, SourceError> {
self.references()
.ok_or(SourceError::InvalidDecodedSpan)?
.collection_authored_span(span)
}
#[must_use]
pub fn into_syntax(self) -> NativeForHead<'a> {
self.syntax
}
pub(crate) fn references(&self) -> Option<ForReferenceSource<'_, 'a>> {
ForReferenceSource::checked(&self.syntax)
}
}
mod native;
pub use native::{NativeForInput, RejectedNativeForInput};
#[cfg(test)]
mod tests;