Skip to main content

twig/
error.rs

1use std::fmt;
2
3use crate::ffi;
4
5/// Error is non_exhaustive so future additions
6/// are not major semver bumps
7#[derive(Debug, Clone, Copy, Eq, PartialEq)]
8#[non_exhaustive]
9pub enum Error {
10    InvalidArgument,
11    ParseError,
12    OutOfMemory,
13    UnsupportedFormat,
14    /// A locator resolved to no node (editor).
15    NotFound,
16    /// A selector locator matched more than one node (editor).
17    Ambiguous,
18    /// The target node has no editable span/interior (editor).
19    NotEditable,
20    /// The edit produced a document that no longer parses; it was rolled back
21    /// (editor).
22    EditConflict,
23    /// A metadata block's body contains `</script`, so it can't be emitted into
24    /// a raw-text `<script>` HTML data island without an injection risk; the
25    /// HTML printer refused (render/serialize-to-HTML).
26    UnsafeMetadata,
27    /// A language was refused at registration; [`crate::RegisterError`]
28    /// carries why.
29    InvalidLanguage,
30    Internal,
31}
32
33impl Error {
34    pub(crate) fn from_status(status: ffi::TwigStatus) -> Result<(), Self> {
35        match status.0 {
36            ffi::TwigStatus::OK => Ok(()),
37            ffi::TwigStatus::INVALID_ARGUMENT => Err(Self::InvalidArgument),
38            ffi::TwigStatus::PARSE_ERROR => Err(Self::ParseError),
39            ffi::TwigStatus::OUT_OF_MEMORY => Err(Self::OutOfMemory),
40            ffi::TwigStatus::UNSUPPORTED_FORMAT => Err(Self::UnsupportedFormat),
41            ffi::TwigStatus::NOT_FOUND => Err(Self::NotFound),
42            ffi::TwigStatus::AMBIGUOUS => Err(Self::Ambiguous),
43            ffi::TwigStatus::NOT_EDITABLE => Err(Self::NotEditable),
44            ffi::TwigStatus::EDIT_CONFLICT => Err(Self::EditConflict),
45            ffi::TwigStatus::UNSAFE_METADATA => Err(Self::UnsafeMetadata),
46            ffi::TwigStatus::INVALID_LANGUAGE => Err(Self::InvalidLanguage),
47            _ => Err(Self::Internal),
48        }
49    }
50}
51
52impl fmt::Display for Error {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        match self {
55            Error::InvalidArgument => f.write_str("invalid argument"),
56            Error::ParseError => f.write_str("parse error"),
57            Error::OutOfMemory => f.write_str("out of memory"),
58            Error::UnsupportedFormat => f.write_str("unsupported format"),
59            Error::NotFound => f.write_str("locator matched no node"),
60            Error::Ambiguous => f.write_str("selector matched more than one node"),
61            Error::NotEditable => f.write_str("node has no editable span"),
62            Error::EditConflict => f.write_str("edit produced an unparseable document"),
63            Error::UnsafeMetadata => {
64                f.write_str("metadata contains </script; unsafe to embed in HTML")
65            }
66            Error::InvalidLanguage => f.write_str("language refused at registration"),
67            Error::Internal => f.write_str("internal error"),
68        }
69    }
70}
71
72impl std::error::Error for Error {}