refactor(tvix/eval): rewrite xml emitter to be simple-stupid

In order to be compatible with the nix XML generator, it’s easier to
generate the XML directly, instead of going through a library which we
have to bend to do what we need.

Removes dependency on `xml-rs`, which came with a full XML parser that
we didn’t use. Only takes a tiny bit of code for the XML escaping,
somewhat simplified.

I add a little escaping value, to make sure we have the same behaviour
as nix proper.

Interestingly enough, we never need to escape XML attribute names,
because the `builtins.toXML` format encodes user-defined values as
attribute keys only. So we only escape attribute values.

Fixes: https://b.tvl.fyi/issues/399
Change-Id: If4d407d324864b3bb9aa3160e2ec6889f7727127
Reviewed-on: https://cl.tvl.fyi/c/depot/+/11697
Tested-by: BuildkiteCI
Reviewed-by: flokli <flokli@flokli.de>
Autosubmit: Profpatsch <mail@profpatsch.de>
This commit is contained in:
Profpatsch 2024-05-20 15:50:33 +02:00 committed by clbot
parent e7be342256
commit 5b2ba0efa1
9 changed files with 205 additions and 89 deletions

View file

@ -10,7 +10,6 @@ use std::{fmt::Debug, fmt::Display, num::ParseIntError};
use codemap::{File, Span};
use codemap_diagnostic::{ColorConfig, Diagnostic, Emitter, Level, SpanLabel, SpanStyle};
use smol_str::SmolStr;
use xml::writer::Error as XmlError;
use crate::spans::ToSpan;
use crate::value::{CoercionKind, NixString};
@ -194,9 +193,6 @@ pub enum ErrorKind {
/// Invalid UTF-8 was encoutered somewhere
Utf8,
/// Errors while serialising to XML.
Xml(Rc<XmlError>),
/// Variant for errors that bubble up to eval from other Tvix
/// components.
TvixError(Rc<dyn error::Error>),
@ -248,7 +244,6 @@ impl error::Error for Error {
errors.first().map(|e| e as &dyn error::Error)
}
ErrorKind::IO { error, .. } => Some(error.as_ref()),
ErrorKind::Xml(error) => Some(error.as_ref()),
ErrorKind::TvixError(error) => Some(error.as_ref()),
_ => None,
}
@ -285,12 +280,6 @@ impl From<bstr::FromUtf8Error> for ErrorKind {
}
}
impl From<XmlError> for ErrorKind {
fn from(err: XmlError) -> Self {
Self::Xml(Rc::new(err))
}
}
impl From<io::Error> for ErrorKind {
fn from(e: io::Error) -> Self {
ErrorKind::IO {
@ -506,8 +495,6 @@ to a missing value in the attribute set(s) included via `with`."#,
write!(f, "Invalid UTF-8 in string")
}
ErrorKind::Xml(error) => write!(f, "failed to serialise to XML: {error}"),
ErrorKind::TvixError(inner_error) => {
write!(f, "{inner_error}")
}
@ -823,7 +810,6 @@ impl Error {
| ErrorKind::JsonError(_)
| ErrorKind::NotSerialisableToJson(_)
| ErrorKind::FromTomlError(_)
| ErrorKind::Xml(_)
| ErrorKind::Utf8
| ErrorKind::TvixError(_)
| ErrorKind::TvixBug { .. }
@ -870,7 +856,6 @@ impl Error {
ErrorKind::UnexpectedArgument { .. } => "E031",
ErrorKind::RelativePathResolution(_) => "E032",
ErrorKind::DivisionByZero => "E033",
ErrorKind::Xml(_) => "E034",
ErrorKind::FromTomlError(_) => "E035",
ErrorKind::NotSerialisableToJson(_) => "E036",
ErrorKind::UnexpectedContext => "E037",