use crate::model::{Adf, Prospect};
use crate::{Result, validate};
use std::borrow::Cow;
use std::io::Write;
use std::ops::Range;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Span {
pub start: usize,
pub end: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Attribute<'a> {
pub name: Cow<'a, str>,
pub value: Cow<'a, str>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct XmlElement<'a> {
pub name: Cow<'a, str>,
pub attributes: Vec<Attribute<'a>>,
pub children: Vec<XmlNode<'a>>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum XmlNode<'a> {
Element(XmlElement<'a>),
Text(Cow<'a, str>),
CData(Cow<'a, str>),
EntityRef(Cow<'a, str>),
Comment(Cow<'a, str>),
ProcessingInstruction(Cow<'a, str>),
Declaration(Cow<'a, str>),
DocType(Cow<'a, str>),
}
#[derive(Debug, Clone)]
pub struct AdfDocument<'a> {
pub(crate) original: &'a str,
pub(crate) root: XmlElement<'a>,
pub(crate) adf: Adf<'a>,
pub(crate) prospect_spans: Vec<Range<usize>>,
pub(crate) dirty_prospects: Vec<bool>,
pub(crate) dirty_all: bool,
}
impl<'a> AdfDocument<'a> {
pub(crate) fn new(
original: &'a str,
root: XmlElement<'a>,
adf: Adf<'a>,
prospect_spans: Vec<Range<usize>>,
) -> Self {
let dirty_prospects = vec![false; prospect_spans.len()];
Self {
original,
root,
adf,
prospect_spans,
dirty_prospects,
dirty_all: false,
}
}
pub fn original(&self) -> &'a str {
self.original
}
pub fn root(&self) -> &XmlElement<'a> {
&self.root
}
pub fn adf(&self) -> &Adf<'a> {
&self.adf
}
pub fn adf_mut(&mut self) -> &mut Adf<'a> {
self.dirty_all = true;
&mut self.adf
}
pub fn prospect_mut(&mut self, index: usize) -> Option<&mut Prospect<'a>> {
if let Some(dirty) = self.dirty_prospects.get_mut(index) {
*dirty = true;
}
self.adf.prospects.get_mut(index)
}
pub fn is_dirty(&self) -> bool {
self.dirty_all || self.dirty_prospects.iter().any(|dirty| *dirty)
}
pub fn validate(&self) -> validate::ValidationReport<'a> {
validate::validate(&self.adf)
}
pub fn validate_strict(&self) -> validate::ValidationReport<'a> {
validate::validate_with(&self.adf, validate::ValidationOptions { strict: true })
}
pub fn write_original_preserving<W: Write>(&self, writer: W) -> Result<()> {
crate::write::write_original_preserving(writer, self)
}
pub fn write_typed<W: Write>(&self, writer: W) -> Result<()> {
crate::write::write_adf(writer, &self.adf)
}
pub fn to_original_preserving_string(&self) -> Result<String> {
let mut bytes = Vec::new();
self.write_original_preserving(&mut bytes)?;
Ok(String::from_utf8(bytes).expect("ADF writer only emits UTF-8"))
}
pub fn to_typed_string(&self) -> Result<String> {
let mut bytes = Vec::new();
self.write_typed(&mut bytes)?;
Ok(String::from_utf8(bytes).expect("ADF writer only emits UTF-8"))
}
}