xee_interpreter/
error.rs

1use ibig::error::OutOfBoundsError;
2use strum::{Display, EnumMessage};
3use xee_xpath_ast::ParserError;
4use xot::xmlname::NameStrInfo;
5
6use crate::span::SourceSpan;
7
8/// An error code with an optional source span.
9///
10/// Also known as `SpannedError` internally.
11#[derive(Debug, PartialEq)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize))]
13pub struct SpannedError {
14    /// The error code
15    pub error: Error,
16    /// The source span where the error occurred
17    pub span: Option<SourceSpan>,
18}
19
20/// XPath/XSLT error code
21///
22/// These are specified by the XPath and XSLT specifications.
23///
24/// Xee extends them with a few additional error codes.
25///
26/// Also known as `Error` internally.
27#[derive(Debug, Clone, PartialEq, Display, EnumMessage)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize))]
29pub enum Error {
30    /// Stack overflow.
31    ///
32    /// Internal stack overflow.
33    StackOverflow,
34
35    /// Unsupported XPath feature.
36    ///
37    /// This XPath feature is not supported by Xee.
38    Unsupported,
39
40    /// Used query with wrong queries.
41    ///
42    /// The query was created with a different queries collection.
43    UsedQueryWithWrongQueries,
44
45    // XPath error conditions: https://www.w3.org/TR/xpath-31/#id-errors
46    /// Component absent in static context.
47    ///  
48    /// It is a static error if analysis of an expression relies on some
49    /// component of the static context that is absent.
50    XPST0001,
51    /// Component absent in dynamic context.
52    ///
53    /// It is a dynamic error if evaluation of an expression relies on some
54    /// part of the dynamic context that is absent.
55    XPDY0002,
56    /// Parse error.
57    ///
58    /// It is a static error if an expression is not a valid instance of the
59    /// grammar defined in A.1 EBNF.
60    XPST0003,
61    /// Type error.
62    ///
63    /// It is a type error if, during the static analysis phase, an expression
64    /// is found to have a static type that is not appropriate for the context
65    /// in which the expression occurs, or during the dynamic evaluation phase,
66    /// the dynamic type of a value does not match a required type as specified
67    /// by the matching rules in 2.5.5 SequenceType Matching.
68    XPTY0004,
69    /// Empty Sequence type error.
70    ///
71    /// During the analysis phase, it is a static error if the static type
72    /// assigned to an expression other than the expression `()` or `data(())`
73    /// is `empty-sequence()`.
74    XPST0005,
75    /// Name not defined.
76    ///
77    /// It is a static error if an expression refers to an element name,
78    /// attribute name, schema type name, namespace prefix, or variable name
79    /// that is not defined in the static context, except for an ElementName in
80    /// an ElementTest or an AttributeName in an AttributeTest.
81    XPST0008,
82    /// Namespace axis not supported.
83    ///
84    /// An implementation that does not support the namespace axis must raise a
85    /// static error if it encounters a reference to the namespace axis and
86    /// XPath 1.0 compatibility mode is false.
87    XPST0010,
88    /// Type error: incorrect function name or number of arguments.
89    ///
90    /// It is a static error if the expanded QName and number of arguments in a
91    /// static function call do not match the name and arity of a function
92    /// signature in the static context.
93    XPST0017,
94    /// Type error: inconsistent sequence.
95    ///
96    /// It is a type error if the result of a path operator contains both nodes
97    /// and non-nodes.
98    XPTY0018,
99    /// Type error: path operator must be applied to node sequence
100    ///
101    /// It is a type error if E1 in a path expression E1/E2 does not evaluate to a
102    /// sequence of nodes.
103    XPTY0019,
104    /// Type error: context item is not a node in an axis step.
105    ///
106    /// It is a type error if, in an axis step, the context item is not a node.
107    XPTY0020,
108    /// Multiple parameters with same name.
109    ///
110    /// It is a static error for an inline function expression to have more
111    /// than one parameter with the same name.
112    XQST0039,
113    /// Invalid Braced URI Literal.
114    ///
115    /// An implementation MAY raise a static error if the value of a
116    /// BracedURILiteral is of nonzero length and is neither an absolute URI
117    /// nor a relative URI.
118    XQST0046,
119    /// Treat type does not match sequence type.
120    ///
121    /// It is a dynamic error if the dynamic type of the operand of a treat
122    /// expression does not match the sequence type specified by the treat
123    /// expression. This error might also be raised by a path expression
124    /// beginning with "/" or "//" if the context node is not in a tree that is
125    /// rooted at a document node. This is because a leading "/" or "//" in a
126    /// path expression is an abbreviation for an initial step that includes
127    /// the clause `treat as document-node()`.
128    XPDY0050,
129    /// Undefined type reference
130    ///
131    /// It is a static error if the expanded QName for an AtomicOrUnionType in
132    /// a SequenceType is not defined in the in-scope schema types as a
133    /// generalized atomic type.
134    XPST0051,
135    /// Invalid type named in cast or castable expression.
136    ///
137    /// The type named in a cast or castable expression must be the name of a
138    /// type defined in the in-scope schema types, and the type must be simple.
139    XQST0052,
140    /// Illegal prefix
141    ///
142    /// A static error is raised if any of the following conditions is
143    /// statically detected in any expression:
144    ///
145    /// - The prefix xml is bound to some namespace URI other than
146    ///   `http://www.w3.org/XML/1998/namespace`.
147    /// - A prefix other than xml is bound to the namespace URI
148    ///   `http://www.w3.org/XML/1998/namespace`.
149    /// - The prefix xmlns is bound to any namespace URI.
150    /// - A prefix other than xmlns is bound to the namespace URI
151    ///   `http://www.w3.org/2000/xmlns/`.
152    XQST0070,
153    /// Invalid target type of cast or castable expression.
154    ///
155    /// It is a static error if the target type of a cast or castable
156    /// expression is xs:NOTATION, xs:anySimpleType, or xs:anyAtomicType.
157    XPST0080,
158    /// Unknown namespace prefix.
159    ///
160    /// It is a static error if a QName used in an expression contains a
161    /// namespace prefix that cannot be expanded into a namespace URI by using
162    /// the statically known namespaces.
163    XPST0081,
164    /// Type error: namespace-sensitive type expected.
165    ///
166    /// When applying the function conversion rules, if an item is of type
167    /// xs:untypedAtomic and the expected type is namespace-sensitive, a type
168    /// error is raised.
169    XPTY0117,
170    /// Implementation-dependent limit exceeded.
171    ///
172    /// An implementation-dependent limit has been exceeded.
173    XPDY0130,
174    /// Namespace axis not supported.
175    ///
176    /// The namespace axis is not supported.
177    XQST0134,
178    /// Duplicate key values in a map.
179    ///
180    /// No two keys in a map may have the same key value.
181    XQDY0137,
182    // XPath errors and functions: https://www.w3.org/TR/xpath-functions-31/#error-summary
183    /// Wrong number of arguments.
184    ///
185    /// Raised when fn:apply is called and the arity of the supplied function
186    /// is not the same as the number of members in the supplied array.
187    FOAP0001,
188    /// Division by zero.
189    ///
190    /// This error is raised whenever an attempt is made to divide by zero.
191    FOAR0001,
192    /// Numeric operation overflow/underflow.
193    ///
194    /// This error is raised whenever numeric operations result in an overflow or underflow.
195    FOAR0002,
196    /// Array index out of bounds.
197    ///
198    /// This error is raised when an integer used to select a member of an array is outside the range of values for that array.
199    FOAY0001,
200    /// Negative array length.
201    ///
202    /// This error is raised when the $length argument to array:subarray is negative.
203    FOAY0002,
204    /// Input value too large for decimal.
205    ///
206    /// Raised when casting to xs:decimal if the supplied value exceeds the implementation-defined limits for the datatype.
207    FOCA0001,
208    /// Invalid lexical value.
209    ///
210    /// Raised by fn:resolve-QName and fn:QName when a supplied value does not
211    /// have the lexical form of a QName or URI respectively; and when casting
212    /// to decimal, if the supplied value is NaN or Infinity.
213    FOCA0002,
214    /// Input too large for integer.
215    ///
216    /// Raised when casting to xs:integer if the supplied value exceeds the implementation-defined limits for the datatype.
217    FOCA0003,
218    /// NaN supplied as float/double value.
219    ///
220    /// Raised when multiplying or dividing a duration by a number, if the
221    /// number supplied is NaN.
222    FOCA0005,
223    /// String to be cast to decimal has too many digits of precision.
224    ///
225    /// Raised when casting a string to xs:decimal if the string has more
226    /// digits of precision than the implementation can represent (the
227    /// implementation also has the option of rounding).
228    FOCA0006,
229    /// Codepoint not valid.
230    ///
231    /// Raised by fn:codepoints-to-string if the input contains an integer that is not the codepoint of a valid XML character.
232    FOCH0001,
233    /// Unsupported collation.
234    ///
235    /// Raised by any function that uses a collation if the requested collation
236    /// is not recognized.
237    FOCH0002,
238    /// Unsupported normalization form.
239    ///
240    /// Raised by fn:normalize-unicode if the requested normalization form is
241    /// not supported by the implementation.
242    FOCH0003,
243    /// Collation does not support collation units.
244    ///
245    /// Raised by functions such as fn:contains if the requested collation does
246    /// not operate on a character-by-character basis.
247    FOCH0004,
248    /// No context document.
249    ///
250    /// Raised by fn:id, fn:idref, and fn:element-with-id if the node that
251    /// identifies the tree to be searched is a node in a tree whose root is
252    /// not a document node.
253    FODC0001,
254    /// Error retrieving resource.
255    ///
256    /// Raised by fn:doc, fn:collection, and fn:uri-collection to indicate that
257    /// either the supplied URI cannot be dereferenced to obtain a resource, or
258    /// the resource that is returned is not parseable as XML.
259    FODC0002,
260    /// Function not defined as deterministic.
261    ///
262    /// Raised by fn:doc, fn:collection, and fn:uri-collection to indicate that
263    /// it is not possible to return a result that is guaranteed deterministic.
264    FODC0003,
265    /// Invalid collection URI.
266    ///
267    /// Raised by fn:collection and fn:uri-collection if the argument is not
268    /// a valid xs:anyURI.
269    FODC0004,
270    /// Invalid argument to fn:doc or fn:doc-available.
271    ///
272    /// Raised (optionally) by fn:doc and fn:doc-available if the argument is
273    /// not a valid URI reference.
274    FODC0005,
275    /// String passed to fn:parse-xml is not a well-formed XML document.
276    ///
277    /// Raised by fn:parse-xml if the supplied string is not a well-formed and
278    /// namespace-well-formed XML document; or if DTD validation is requested
279    /// and the document is not valid against its DTD.
280    FODC0006,
281    /// The processor does not support serialization.
282    ///
283    /// Raised when fn:serialize is called and the processor does not support
284    /// serialization, in cases where the host language makes serialization an
285    /// optional feature.
286    FODC0010,
287    /// Invalid decimal format name.
288    ///
289    /// This error is raised if the decimal format name supplied to
290    /// fn:format-number is not a valid QName, or if the prefix in the QName is
291    /// undeclared, or if there is no decimal format in the static context with
292    /// a matching name.
293    FODF1280,
294    /// Invalid decimal format picture string.
295    ///
296    /// This error is raised if the picture string supplied to fn:format-number
297    /// or fn:format-integer has invalid syntax.
298    FODF1310,
299    /// Overflow/underflow in date/time operation.
300    ///
301    /// Raised when casting to date/time datatypes, or performing arithmetic
302    /// with date/time values, if arithmetic overflow or underflow occurs.
303    FODT0001,
304    /// err:FODT0002, Overflow/underflow in duration operation.
305    ///
306    /// Raised when casting to duration datatypes, or performing arithmetic
307    /// with duration values, if arithmetic overflow or underflow occurs.
308    FODT0002,
309    /// Invalid timezone value.
310    ///
311    /// Raised by adjust-date-to-timezone and related functions if the supplied
312    /// timezone is invalid.
313    FODT0003,
314    /// Unidentified error.
315    ///
316    /// Error code used by fn:error when no other error code is provided.
317    FOER0000,
318    /// Invalid date/time formatting parameters.
319    ///
320    /// This error is raised if the picture string or calendar supplied to
321    /// fn:format-date, fn:format-time, or fn:format-dateTime has invalid
322    /// syntax.
323    FOFD1340,
324    /// Invalid date/time formatting component.
325    ///
326    /// This error is raised if the picture string supplied to fn:format-date
327    /// selects a component that is not present in a date, or if the picture
328    /// string supplied to fn:format-time selects a component that is not
329    /// present in a time.
330    FOFD1350,
331    /// JSON syntax error.
332    ///
333    /// Raised by functions such as fn:json-doc, fn:parse-json or
334    /// fn:json-to-xml if the string supplied as input does not conform to the
335    /// JSON grammar (optionally with implementation-defined extensions).
336    FOJS0001,
337    /// JSON duplicate keys.
338    ///
339    /// Raised by functions such as map:merge, fn:json-doc, fn:parse-json or
340    /// fn:json-to-xml if the input contains duplicate keys, when the chosen
341    /// policy is to reject duplicates.
342    FOJS0003,
343    /// JSON: not schema-aware.
344    ///
345    /// Raised by fn:json-to-xml if validation is requested when the processor
346    /// does not support schema validation or typed nodes.
347    FOJS0004,
348    /// Invalid options.
349    ///
350    /// Raised by functions such as map:merge, fn:parse-json, and
351    /// fn:xml-to-json if the $options map contains an invalid entry.
352    FOJS0005,
353    /// Invalid XML representation of JSON.
354    ///
355    /// Raised by fn:xml-to-json if the XML input does not conform to the rules
356    /// for the XML representation of JSON.
357    FOJS0006,
358    /// Bad JSON escape sequence.
359    ///
360    /// Raised by fn:xml-to-json if the XML input uses the attribute
361    /// escaped="true" or escaped-key="true", and the corresponding string or
362    /// key contains an invalid JSON escape sequence.
363    FOJS0007,
364    /// No namespace found for prefix.
365    ///
366    /// Raised by fn:resolve-QName and analogous functions if a supplied QName
367    /// has a prefix that has no binding to a namespace.
368    FONS0004,
369    /// Base-uri not defined in the static context.
370    ///
371    /// Raised by fn:resolve-uri if no base URI is available for resolving a
372    /// relative URI.
373    FONS0005,
374    /// Module URI is a zero-length string.
375    ///
376    /// Raised by fn:load-xquery-module if the supplied module URI is zero-length.
377    FOQM0001,
378    /// Module URI not found.
379    ///
380    /// Raised by fn:load-xquery-module if no module can be found with the
381    /// supplied module URI.
382    FOQM0002,
383    /// Static error in dynamically-loaded XQuery module.
384    ///
385    /// Raised by fn:load-xquery-module if a static error (including a
386    /// statically-detected type error) is encountered when processing the
387    /// library module.
388    FOQM0003,
389    /// Parameter for dynamically-loaded XQuery module has incorrect type.
390    ///
391    /// Raised by fn:load-xquery-module if a value is supplied for the initial
392    /// context item or for an external variable, and the value does not
393    /// conform to the required type declared in the dynamically loaded module.
394    FOQM0005,
395    /// No suitable XQuery processor available.
396    ///
397    /// Raised by fn:load-xquery-module if no XQuery processor is available
398    /// supporting the requested XQuery version (or if none is available at
399    /// all).
400    FOQM0006,
401    /// Invalid value for cast/constructor.
402    ///
403    /// A general-purpose error raised when casting, if a cast between two
404    /// datatypes is allowed in principle, but the supplied value cannot be
405    /// converted: for example when attempting to cast the string "nine" to an
406    /// integer.
407    FORG0001,
408    /// Invalid argument to fn:resolve-uri().
409    ///
410    /// Raised when either argument to fn:resolve-uri is not a valid URI/IRI.
411    FORG0002,
412    /// fn:zero-or-one called with a sequence containing more than one item.
413    ///
414    /// Raised by fn:zero-or-one if the supplied value contains more than one item.
415    FORG0003,
416    /// fn:one-or-more called with a sequence containing no items.
417    ///
418    /// Raised by fn:one-or-more if the supplied value is an empty sequence.
419    FORG0004,
420    /// fn:exactly-one called with a sequence containing zero or more than one item.
421    ///
422    /// Raised by fn:exactly-one if the supplied value is not a singleton sequence.
423    FORG0005,
424    /// Invalid argument type.
425    ///
426    /// Raised by functions such as fn:max, fn:min, fn:avg, fn:sum if the
427    /// supplied sequence contains values inappropriate to this function.
428    FORG0006,
429    /// The two arguments to fn:dateTime have inconsistent timezones.
430    ///
431    /// Raised by fn:dateTime if the two arguments both have timezones and the
432    /// timezones are different.
433    FORG0008,
434    /// Error in resolving a relative URI against a base URI in fn:resolve-uri.
435    ///
436    /// A catch-all error for fn:resolve-uri, recognizing that the
437    /// implementation can choose between a variety of algorithms and that some
438    /// of these may fail for a variety of reasons.
439    FORG0009,
440    /// Invalid date/time.
441    ///
442    /// Raised when the input to fn:parse-ietf-date does not match the
443    /// prescribed grammar, or when it represents an invalid date/time such as
444    /// 31 February.
445    FORG0010,
446    /// Invalid regular expression flags.
447    ///
448    /// Raised by regular expression functions such as fn:matches and
449    /// fn:replace if the regular expression flags contain a character other
450    /// than i, m, q, s, or x.
451    FORX0001,
452    /// Invalid regular expression.
453    ///
454    /// Raised by regular expression functions such as fn:matches and
455    /// fn:replace if the regular expression is syntactically invalid.
456    FORX0002,
457    /// Regular expression matches zero-length string.
458    ///
459    /// For functions such as fn:replace and fn:tokenize, raises an error if
460    /// the supplied regular expression is capable of matching a zero length
461    /// string.
462    FORX0003,
463    /// Invalid replacement string.
464    ///
465    /// Raised by fn:replace to report errors in the replacement string.
466    FORX0004,
467    /// Argument to fn:data() contains a node that does not have a typed value.
468    ///
469    /// Raised by fn:data, or by implicit atomization, if applied to a node
470    /// with no typed value, the main example being an element validated
471    /// against a complex type that defines it to have element-only content.
472    FOTY0012,
473    /// The argument to fn:data() contains a function item.
474    ///
475    /// Raised by fn:data, or by implicit atomization, if the sequence to be
476    /// atomized contains a function item.
477    FOTY0013,
478    /// The argument to fn:string() is a function item.
479    ///
480    /// Raised by fn:string, or by implicit string conversion, if the input
481    /// sequence contains a function item.
482    FOTY0014,
483    /// An argument to fn:deep-equal() contains a function item.
484    ///
485    /// Raised by fn:deep-equal if either input sequence contains a function
486    /// item.
487    FOTY0015,
488    /// Invalid $href argument to fn:unparsed-text() (etc.)
489    ///
490    /// A dynamic error is raised if the $href argument contains a fragment
491    /// identifier, or if it cannot be used to retrieve a resource containing
492    /// text.
493    FOUT1170,
494    /// Cannot decode resource retrieved by fn:unparsed-text() (etc.)
495    ///
496    /// A dynamic error is raised if the retrieved resource contains octets
497    /// that cannot be decoded into Unicode ·characters· using the specified
498    /// encoding, or if the resulting characters are not permitted XML
499    /// characters. This includes the case where the processor does not support
500    /// the requested encoding.
501    FOUT1190,
502    /// Cannot infer encoding of resource retrieved by fn:unparsed-text()
503    /// (etc.)
504    ///
505    /// A dynamic error is raised if $encoding is absent and the processor
506    /// cannot infer the encoding using external information and the encoding
507    /// is not UTF-8.
508    FOUT1200,
509    /// No suitable XSLT processor available
510    ///
511    /// A dynamic error is raised if no XSLT processor suitable for evaluating
512    /// a call on fn:transform is available.
513    FOXT0001,
514    /// Invalid parameters to XSLT transformation
515    ///
516    /// A dynamic error is raised if the parameters supplied to fn:transform
517    /// are invalid, for example if two mutually-exclusive parameters are
518    /// supplied. If a suitable XSLT error code is available (for example in
519    /// the case where the requested initial-template does not exist in the
520    /// stylesheet), that error code should be used in preference.
521    FOXT0002,
522    /// XSLT transformation failed
523    ///
524    /// A dynamic error is raised if an XSLT transformation invoked using
525    /// fn:transform fails with a static or dynamic error. The XSLT error code
526    /// is used if available; this error code provides a fallback when no XSLT
527    /// error code is returned, for example because the processor is an XSLT
528    /// 1.0 processor.
529    FOXT0003,
530    /// XSLT transformation has been disabled
531    ///
532    /// A dynamic error is raised if the fn:transform function is invoked when
533    /// XSLT transformation (or a specific transformation option) has been
534    /// disabled for security or other reasons.
535    FOXT0004,
536    /// XSLT output contains non-accepted characters
537    ///
538    /// A dynamic error is raised if the result of the fn:transform function
539    /// contains characters available only in XML 1.1 and the calling processor
540    /// cannot handle such characters.
541    FOXT0006,
542
543    /// Duplicate global variable name.
544    ///
545    /// It is a static error if a package contains more than one non-hidden
546    /// binding of a global variable with the same name and same import
547    /// precedence, unless it also contains another binding with the same name
548    /// and higher import precedence.
549    XTSE0630,
550    /// Circularity
551    ///
552    /// Circularity in global declarations is now allowed.
553    XTDE0640,
554    /// Shallow copy
555    ///
556    /// Shallow copy of sequence of more than one item is not allowed.
557    XTTE3180,
558    /// Function item in complex content
559    ///
560    /// The result sequence to be added as content cannot contain a function
561    /// item.
562    XTDE0450,
563
564    /// Function cannot be normalized for serialization.
565    ///
566    /// It is an error if an item in S in sequence normalization is an
567    /// attribute node or a namespace node.
568    SENR0001,
569
570    /// Entity serialization error
571    ///
572    /// The serializer is unable to satisfy the rules for either a well-formed
573    /// XML document entity or a well-formed XML external general parsed
574    /// entity, or both, except for content modified by the character expansion
575    /// phase of serialization.
576    SERE0003,
577
578    /// Standalone or doctype-system parameter disallowed for XML fragment.
579    ///
580    /// It's not allowed to specify the doctype-system parameter, or to specify
581    /// the standalone parameter with a value other than omit, if the instance
582    /// of the data model contains text nodes or multiple element nodes as
583    /// children of the root node.
584    SEPM0004,
585
586    /// Invalid character in NCName according to namespaces version.
587    ///
588    /// It is an error if the serialized result would contain an NCNameNames
589    /// that contains a character that is not permitted by the version of
590    /// Namespaces in XML specified by the version parameter.
591    SERE0005,
592
593    /// Invalid character according to XML version
594    ///
595    /// It is an error if the serialized result would contain a character that
596    /// is not permitted by the version of XML specified by the version
597    /// parameter.
598    SERE0006,
599
600    /// Invalid encoding
601    ///
602    /// It is an error if an output encoding other than UTF-8 or UTF-16 is
603    /// requested and the serializer does not support that encoding.
604    SESU0007,
605
606    /// Illegal character for encoding
607    ///
608    /// It is an error if a character that cannot be represented in the
609    /// encoding that the serializer is using for output appears in a context
610    /// where character references are not allowed (for example if the
611    /// character occurs in the name of an element).
612    SERE0008,
613
614    /// standalone even though XML declaration is omitted
615    ///
616    /// It is an error if the omit-xml-declaration parameter has the value yes,
617    /// true or 1, and the standalone attribute has a value other than omit; or
618    /// the version parameter has a value other than 1.0 and the doctype-system
619    /// parameter is specified.
620    SEPM0009,
621
622    /// undeclare-prefixes is not allowed in XML version 1.0
623    ///
624    /// It is an error if the output method is xml or xhtml, the value of the
625    /// undeclare-prefixes parameter is one of, yes, true or 1, and the value
626    /// of the version parameter is 1.0.
627    SEPM0010,
628
629    /// Unsupported normalization form
630    ///
631    /// It is an error if the value of the normalization-form parameter
632    /// specifies a normalization form that is not supported by the serializer.
633    SESU0011,
634
635    /// Combining character at start of fully-normalized result
636    ///
637    /// It is an error if the value of the normalization-form parameter is
638    /// fully-normalized and any relevant construct of the result begins with a
639    /// combining character.
640    SERE0012,
641
642    /// Unsupported version
643    ///
644    /// It is an error if the serializer does not support the version of XML or
645    /// HTML specified by the version parameter.
646    SESU0013,
647
648    /// Illegal characters in HTML output.
649    ///
650    /// It is an error to use the HTML output method if characters which are
651    /// permitted in XML but not in HTML appear in the instance of the data
652    /// model.
653    SERE0014,
654
655    /// Illegal characters in processing instruction for HTML output.
656    ///
657    /// It is an error to use the HTML output method when > appears within a
658    /// processing instruction in the data model instance being serialized.
659    SERE0015,
660
661    /// Parameter value is invalid for the defined domain.
662    SEPM0016,
663
664    /// Error evaluating serialization parameter expression.
665    ///
666    /// It is an error if evaluating an expression in order to extract the
667    /// setting of a serialization parameter from a data model instance would
668    /// yield an error.
669    SEPM0017,
670
671    /// Multiple values for use-character-maps serialization parameter.
672    ///
673    /// It is an error if evaluating an expression in order to extract the
674    /// setting of the use-character-maps serialization parameter from a data
675    /// model instance would yield a sequence of length greater than one.
676    SEPM0018,
677
678    /// Multiple values for serialization parameter.
679    ///
680    /// It is an error if an instance of the data model used to specify the
681    /// settings of serialization parameters specifies the value of the same
682    /// parameter more than once.
683    SEPM0019,
684
685    /// Invalid numeric value in JSON.
686    ///
687    /// It is an error if a numeric value being serialized using the JSON
688    /// output method cannot be represented in the JSON grammar (e.g. +INF,
689    /// -INF, NaN).
690    SERE0020,
691
692    /// Item not allowed in JSON output.
693    ///
694    /// It is an error if a sequence being serialized using the JSON output
695    /// method includes items for which no rules are provided in the
696    /// appropriate section of the serialization rules.
697    SERE0021,
698
699    /// Duplicate key in JSON output.
700    ///
701    /// It is an error if a map being serialized using the JSON output method
702    /// has two keys with the same string value, unless the
703    /// allow-duplicate-names has the value yes, true or 1.
704    SERE0022,
705
706    /// Sequence of length greater than one in JSON output.
707    ///
708    /// It is an error if a sequence being serialized using the JSON output
709    /// method is of length greater than one.
710    SERE0023,
711
712    /// An application generated error
713    Application(Box<ApplicationError>),
714}
715
716#[derive(Debug, Clone, PartialEq)]
717#[cfg_attr(feature = "serde", derive(serde::Serialize))]
718pub struct ApplicationError {
719    qname: xot::xmlname::OwnedName,
720    description: String,
721    // FIXME: error object is not supported right now
722    // it would require storing an arbitrary sequence in here,
723    // but that's not really supported by this simple error.
724}
725
726impl ApplicationError {
727    pub fn new(qname: xot::xmlname::OwnedName, description: String) -> Self {
728        Self { qname, description }
729    }
730
731    pub fn qname(&self) -> &xot::xmlname::OwnedName {
732        &self.qname
733    }
734
735    pub fn description(&self) -> &str {
736        &self.description
737    }
738}
739
740impl Error {
741    pub fn with_span(self, span: SourceSpan) -> SpannedError {
742        SpannedError {
743            error: self,
744            span: Some(span),
745        }
746    }
747    pub fn with_ast_span(self, span: xee_xpath_ast::ast::Span) -> SpannedError {
748        Self::with_span(self, span.into())
749    }
750
751    pub fn code(&self) -> String {
752        match self {
753            Error::Application(application_error) => {
754                application_error.qname.local_name().to_string()
755            }
756            _ => self.to_string(),
757        }
758    }
759
760    pub fn code_qname(&self) -> xot::xmlname::OwnedName {
761        match self {
762            Error::Application(application_error) => application_error.qname.clone(),
763            _ => xot::xmlname::OwnedName::new(
764                self.code(),
765                "http://www.w3.org/2005/xqt-errors".to_string(),
766                "".to_string(),
767            ),
768        }
769    }
770
771    pub fn message(&self) -> &str {
772        match self {
773            Error::Application(app_error) => &app_error.description(),
774            _ => self.documentation_pieces().0,
775        }
776    }
777
778    pub fn note(&self) -> &str {
779        self.documentation_pieces().1
780    }
781
782    fn documentation_pieces(&self) -> (&str, &str) {
783        if let Some(documentation) = self.get_documentation() {
784            let mut pieces = documentation.splitn(2, "\n\n");
785            let first = pieces.next().unwrap_or("");
786            let second = pieces.next().unwrap_or("");
787            (first, second)
788        } else {
789            ("", "")
790        }
791    }
792}
793impl std::error::Error for Error {}
794
795impl std::fmt::Display for SpannedError {
796    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
797        if let Some(span) = self.span {
798            let span = span.range();
799            write!(f, "{} ({}..{})", self.error, span.start, span.end)
800        } else {
801            write!(f, "{}", self.error)
802        }
803    }
804}
805
806impl std::error::Error for SpannedError {}
807
808// note: this is only used for internal conversions of names
809// for now, not the full grammar.
810impl From<xee_xpath_ast::ParserError> for Error {
811    fn from(e: xee_xpath_ast::ParserError) -> Self {
812        let spanned_error: SpannedError = e.into();
813        spanned_error.error
814    }
815}
816
817impl From<xee_xpath_ast::ParserError> for SpannedError {
818    fn from(e: xee_xpath_ast::ParserError) -> Self {
819        let span = e.span();
820        let error = match e {
821            ParserError::ExpectedFound { .. } => Error::XPST0003,
822            // this is what fn-function-arity-017 expects, even though
823            // implementation limit exceeded (XPST00130) seems reasonable to me.
824            ParserError::ArityOverflow { .. } => Error::FOAR0002,
825            ParserError::Reserved { .. } => Error::XPST0003,
826            ParserError::UnknownPrefix { .. } => Error::XPST0081,
827            ParserError::UnknownType { .. } => Error::XPST0051,
828            // TODO: this this the right error code?
829            ParserError::IllegalFunctionInPattern { .. } => Error::XPST0003,
830        };
831        SpannedError {
832            error,
833            span: Some(span.into()),
834        }
835    }
836}
837
838impl From<regexml::Error> for Error {
839    fn from(e: regexml::Error) -> Self {
840        use regexml::Error::*;
841        // TODO: pass more error details into error codes
842        match e {
843            Internal => panic!("Internal error in regexml engine"),
844            InvalidFlags(_) => Error::FORX0001,
845            Syntax(_) => Error::FORX0002,
846            MatchesEmptyString => Error::FORX0003,
847            InvalidReplacementString(_) => Error::FORX0004,
848        }
849    }
850}
851
852impl From<xot::Error> for Error {
853    fn from(e: xot::Error) -> Self {
854        match e {
855            xot::Error::MissingPrefix(_) => Error::XPST0081,
856            // TODO: are there other xot errors that need to be translated?
857            _ => Error::XPST0003,
858        }
859    }
860}
861
862impl From<Error> for SpannedError {
863    fn from(e: Error) -> Self {
864        SpannedError {
865            error: e,
866            span: None,
867        }
868    }
869}
870
871// impl From<xee_name::Error> for Error {
872//     fn from(e: xee_name::Error) -> Self {
873//         match e {
874//             xee_name::Error::MissingPrefix => Error::XPST0081,
875//         }
876//     }
877// }
878
879impl From<OutOfBoundsError> for Error {
880    fn from(_e: OutOfBoundsError) -> Self {
881        Error::FOCA0003
882    }
883}
884
885/// The result type for errors without span information.
886pub type Result<T> = std::result::Result<T, Error>;
887
888/// The result type for errors with (optional) source spans.
889///
890/// Also known as `SpannedResult` internally.
891pub type SpannedResult<T> = std::result::Result<T, SpannedError>;
892
893impl SpannedError {
894    /// get the underlying [`Error`] value
895    pub fn value(self) -> Error {
896        self.error
897    }
898}