use crate::substitution_context::Evaluation;
use crate::substitution_text::Text;
use crate::{Diagnostic, Inline, Span};
#[derive(Clone)]
pub(crate) struct Read {
expanded: Text,
refs: Vec<crate::inline_attributes::Reference>,
pub value: String,
pub references: Vec<Span>,
}
pub(crate) fn read(
value: &str,
base: usize,
evaluation: &mut Evaluation<'_>,
diagnostics: &mut Vec<Diagnostic>,
) -> Read {
let mut source = Text::default();
source.append_source(value, true, 0, Span::new(base, base + value.len()));
let (expanded, refs) = crate::inline_attributes::apply(source, evaluation, diagnostics);
let references = refs.iter().map(|r| r.span).collect();
let lexical = expanded.text.clone();
Read {
expanded,
refs,
value: lexical,
references,
}
}
impl Read {
pub fn source(value: &str, base: usize) -> Self {
let mut expanded = Text::default();
expanded.append_source(value, true, 0, Span::new(base, base + value.len()));
Self::expanded(expanded, Vec::new())
}
pub fn expanded(expanded: Text, refs: Vec<crate::inline_attributes::Reference>) -> Self {
Read {
value: expanded.text.clone(),
references: refs.iter().map(|r| r.span).collect(),
expanded,
refs,
}
}
pub fn snapshot(&self, attributes: &crate::Attributes) -> Vec<Inline> {
self.clone()
.finish(&mut Evaluation::read_only(attributes), &mut Vec::new())
}
pub fn finish(
self,
evaluation: &mut Evaluation<'_>,
diagnostics: &mut Vec<Diagnostic>,
) -> Vec<Inline> {
let mut protected = Text::default();
for fragment in self.expanded.into_fragments() {
protected.append_source(&fragment.text, false, fragment.owner, fragment.span);
}
let mut quotes = Vec::new();
let compat = evaluation.get("compat-mode").is_some();
let text = crate::attribute_quotes::apply_text(
protected,
compat,
evaluation,
&mut quotes,
true,
diagnostics,
);
let text = crate::replacements::apply_text(text, true, true);
let nodes = crate::inline_attributes::nodes(text, self.refs);
let templates = quotes
.into_iter()
.filter(|q| !q.decorated)
.filter_map(|q| crate::inline_quotes::node(q.format?, q.span))
.collect();
crate::attribute_macros::rebuild(nodes, templates)
}
}