use super::{NativeChild, NativeTemplateComponent};
use crate::{embed::EmbedSource, markup::Token};
use vize_l0::Span;
mod failure;
mod origin;
pub use failure::NativeTextValueFailure;
use origin::Origin;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NativeTextValueError {
ForeignComponent,
NotText,
RecoveredComponent,
Verbatim,
RawTextParent,
RcDataParent,
Source(crate::embed::SourceError),
}
pub struct NativeTextValue<'a> {
origin: Origin<'a>,
original: Token<'a>,
source: EmbedSource<'a>,
}
impl<'a> NativeTemplateComponent<'a> {
pub fn observe_text_value(
&self,
child: NativeChild<'_, 'a>,
) -> Result<NativeTextValue<'a>, NativeTextValueFailure<'a>> {
let prepare = || {
let (origin, original) = Origin::original(self, &child)?;
let source = crate::embed::source::prepare_text_value(
self.component().allocator(),
origin.block.root_source(),
origin.span,
)
.map_err(NativeTextValueError::Source)?;
Ok(NativeTextValue {
origin,
original,
source,
})
};
prepare().map_err(|kind| NativeTextValueFailure::original(kind, &child))
}
}
impl<'a> NativeTextValue<'a> {
#[must_use]
pub const fn token(&self) -> &Token<'a> {
&self.original
}
#[must_use]
pub const fn raw_text(&self) -> &'a str {
self.original.text
}
#[must_use]
pub const fn source(&self) -> EmbedSource<'a> {
self.source
}
#[must_use]
pub const fn span(&self) -> Span {
self.origin.span
}
pub fn admitted_for<'s>(
&'s self,
selected: &'s NativeTemplateComponent<'a>,
child: NativeChild<'s, 'a>,
) -> Option<NativeTextValueView<'s, 'a>> {
self.origin
.matches(selected, &child, &self.original)
.then_some(NativeTextValueView {
owner: self,
selected,
child,
})
}
#[must_use]
pub fn into_source(self) -> EmbedSource<'a> {
self.source
}
}
pub struct NativeTextValueView<'s, 'a> {
owner: &'s NativeTextValue<'a>,
selected: &'s NativeTemplateComponent<'a>,
child: NativeChild<'s, 'a>,
}
impl<'s, 'a> NativeTextValueView<'s, 'a> {
#[must_use]
pub fn selected(&self) -> &'s NativeTemplateComponent<'a> {
self.selected
}
#[must_use]
pub fn child(&self) -> &NativeChild<'s, 'a> {
&self.child
}
#[must_use]
pub fn observation(&self) -> &'s NativeTextValue<'a> {
self.owner
}
}
#[cfg(test)]
mod tests;