1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
use crate::node::{ChainNode, CommandNode, Nodes, PipeNode}; use gtmpl_value::{FuncError, Value}; use std::{fmt, num::ParseIntError, string::FromUtf8Error}; use thiserror::Error; #[derive(Debug)] pub struct ErrorContext { pub name: String, pub line: usize, } impl fmt::Display for ErrorContext { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}:{}", self.name, self.line) } } #[derive(Error, Debug)] pub enum ParseError { #[error("unexpected {0} in define clause")] UnexpectedInDefineClause(Nodes), #[error("unexpected end")] UnexpectedEnd, #[error("template: {0}:{1}")] WithContext(ErrorContext, String), #[error("no tree")] NoTree, #[error(transparent)] NodeError(#[from] NodeError), #[error("enable gtmpl_dynamic_template to use a pipeline as name")] NoDynamicTemplate, #[error("unable to parse string: {0}")] UnableToParseString(String), } impl ParseError { pub fn with_context(name: impl ToString, line: usize, msg: impl ToString) -> Self { Self::WithContext( ErrorContext { name: name.to_string(), line, }, msg.to_string(), ) } } #[derive(Error, Debug)] pub enum NodeError { #[error("unable to unquote")] UnquoteError, #[error("NaN")] NaN, #[error("not a tree node")] NaTN, } #[derive(Error, Debug)] pub enum PrintError { #[error("unable to process verb: {0}")] UnableToProcessVerb(String), #[error("{0:X} is not a valid char")] NotAValidChar(i128), #[error("unable to format {0} as {1}")] UnableToFormat(Value, char), #[error("unable to terminate format arg: {0}")] UnableToTerminateFormatArg(String), #[error("missing ] in {0}")] MissingClosingBracket(String), #[error("unable to parse index: {0}")] UnableToParseIndex(ParseIntError), #[error("unable to parse width: {0}")] UnableToParseWidth(ParseIntError), #[error("width after index (e.g. %[3]2d)")] WithAfterIndex, #[error("precision after index (e.g. %[3].2d)")] PrecisionAfterIndex, } #[derive(Error, Debug)] pub enum ExecError { #[error("{0} is an incomplete or empty template")] IncompleteTemplate(String), #[error("{0}")] IOError(#[from] std::io::Error), #[error("unknown node: {0}")] UnknownNode(Nodes), #[error("expected if or with node, got {0}")] ExpectedIfOrWith(Nodes), #[error("unable to convert output to uft-8: {0}")] Utf8ConversionFailed(FromUtf8Error), #[error("empty var stack")] EmptyStack, #[error("var context smaller than {0}")] VarContextToSmall(usize), #[error("invalid range {0:?}")] InvalidRange(Value), #[error("pipeline must yield a String")] PipelineMustYieldString, #[error("template {0} not defined")] TemplateNotDefined(String), #[error("exceeded max template depth")] MaxTemplateDepth, #[error("error evaluating pipe: {0}")] ErrorEvaluatingPipe(PipeNode), #[error("no arguments for command node: {0}")] NoArgsForCommandNode(CommandNode), #[error("cannot evaluate command: {0}")] CannotEvaluateCommand(Nodes), #[error("field chain without fields :/")] FieldChainWithoutFields, #[error("{0} has arguments but cannot be invoked as function")] NotAFunctionButArguments(String), #[error("no fields in eval_chain_node")] NoFieldsInEvalChainNode, #[error("indirection through explicit nul in {0}")] NullInChain(ChainNode), #[error("cannot handle {0} as argument")] InvalidArgument(Nodes), #[error("{0} is not a defined function")] UndefinedFunction(String), #[error(transparent)] FuncError(#[from] FuncError), #[error("can't give argument to non-function {0}")] ArgumentForNonFunction(Nodes), #[error("only maps and objects have fields")] OnlyMapsAndObjectsHaveFields, #[error("no field {0} for {1}")] NoFiledFor(String, Value), #[error("variable {0} not found")] VariableNotFound(String), } #[derive(Error, Debug)] pub enum TemplateError { #[error(transparent)] ExecError(#[from] ExecError), #[error(transparent)] ParseError(#[from] ParseError), }