From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/handlebars/src/error.rs | 272 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 vendor/handlebars/src/error.rs (limited to 'vendor/handlebars/src/error.rs') diff --git a/vendor/handlebars/src/error.rs b/vendor/handlebars/src/error.rs new file mode 100644 index 000000000..f4721623f --- /dev/null +++ b/vendor/handlebars/src/error.rs @@ -0,0 +1,272 @@ +use std::error::Error; +use std::fmt; +use std::io::Error as IOError; +use std::num::ParseIntError; +use std::string::FromUtf8Error; + +use serde_json::error::Error as SerdeError; +#[cfg(feature = "dir_source")] +use walkdir::Error as WalkdirError; + +#[cfg(feature = "script_helper")] +use rhai::{EvalAltResult, ParseError}; + +/// Error when rendering data on template. +#[derive(Debug, Default)] +pub struct RenderError { + pub desc: String, + pub template_name: Option, + pub line_no: Option, + pub column_no: Option, + cause: Option>, + unimplemented: bool, +} + +impl fmt::Display for RenderError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match (self.line_no, self.column_no) { + (Some(line), Some(col)) => write!( + f, + "Error rendering \"{}\" line {}, col {}: {}", + self.template_name.as_deref().unwrap_or("Unnamed template"), + line, + col, + self.desc + ), + _ => write!(f, "{}", self.desc), + } + } +} + +impl Error for RenderError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + self.cause + .as_ref() + .map(|e| e.as_ref() as &(dyn Error + 'static)) + } +} + +impl From for RenderError { + fn from(e: IOError) -> RenderError { + RenderError::from_error("Cannot generate output.", e) + } +} + +impl From for RenderError { + fn from(e: SerdeError) -> RenderError { + RenderError::from_error("Failed to access JSON data.", e) + } +} + +impl From for RenderError { + fn from(e: FromUtf8Error) -> RenderError { + RenderError::from_error("Failed to generate bytes.", e) + } +} + +impl From for RenderError { + fn from(e: ParseIntError) -> RenderError { + RenderError::from_error("Cannot access array/vector with string index.", e) + } +} + +impl From for RenderError { + fn from(e: TemplateError) -> RenderError { + RenderError::from_error("Failed to parse template.", e) + } +} + +#[cfg(feature = "script_helper")] +impl From> for RenderError { + fn from(e: Box) -> RenderError { + RenderError::from_error("Cannot convert data to Rhai dynamic", e) + } +} + +#[cfg(feature = "script_helper")] +impl From for RenderError { + fn from(e: ScriptError) -> RenderError { + RenderError::from_error("Failed to load rhai script", e) + } +} + +impl RenderError { + pub fn new>(desc: T) -> RenderError { + RenderError { + desc: desc.as_ref().to_owned(), + ..Default::default() + } + } + + pub(crate) fn unimplemented() -> RenderError { + RenderError { + unimplemented: true, + ..Default::default() + } + } + + pub fn strict_error(path: Option<&String>) -> RenderError { + let msg = match path { + Some(path) => format!("Variable {:?} not found in strict mode.", path), + None => "Value is missing in strict mode".to_owned(), + }; + RenderError::new(&msg) + } + + pub fn from_error(error_info: &str, cause: E) -> RenderError + where + E: Error + Send + Sync + 'static, + { + let mut e = RenderError::new(error_info); + e.cause = Some(Box::new(cause)); + + e + } + + #[inline] + pub(crate) fn is_unimplemented(&self) -> bool { + self.unimplemented + } +} + +quick_error! { +/// Template parsing error + #[derive(Debug)] + pub enum TemplateErrorReason { + MismatchingClosedHelper(open: String, closed: String) { + display("helper {:?} was opened, but {:?} is closing", + open, closed) + } + MismatchingClosedDecorator(open: String, closed: String) { + display("decorator {:?} was opened, but {:?} is closing", + open, closed) + } + InvalidSyntax { + display("invalid handlebars syntax.") + } + InvalidParam (param: String) { + display("invalid parameter {:?}", param) + } + NestedSubexpression { + display("nested subexpression is not supported") + } + IoError(err: IOError, name: String) { + display("Template \"{}\": {}", name, err) + } + #[cfg(feature = "dir_source")] + WalkdirError(err: WalkdirError) { + display("Walk dir error: {}", err) + } + } +} + +/// Error on parsing template. +#[derive(Debug)] +pub struct TemplateError { + pub reason: TemplateErrorReason, + pub template_name: Option, + pub line_no: Option, + pub column_no: Option, + segment: Option, +} + +impl TemplateError { + pub fn of(e: TemplateErrorReason) -> TemplateError { + TemplateError { + reason: e, + template_name: None, + line_no: None, + column_no: None, + segment: None, + } + } + + pub fn at(mut self, template_str: &str, line_no: usize, column_no: usize) -> TemplateError { + self.line_no = Some(line_no); + self.column_no = Some(column_no); + self.segment = Some(template_segment(template_str, line_no, column_no)); + self + } + + pub fn in_template(mut self, name: String) -> TemplateError { + self.template_name = Some(name); + self + } +} + +impl Error for TemplateError {} + +impl From<(IOError, String)> for TemplateError { + fn from(err_info: (IOError, String)) -> TemplateError { + let (e, name) = err_info; + TemplateError::of(TemplateErrorReason::IoError(e, name)) + } +} + +#[cfg(feature = "dir_source")] +impl From for TemplateError { + fn from(e: WalkdirError) -> TemplateError { + TemplateError::of(TemplateErrorReason::WalkdirError(e)) + } +} + +fn template_segment(template_str: &str, line: usize, col: usize) -> String { + let range = 3; + let line_start = if line >= range { line - range } else { 0 }; + let line_end = line + range; + + let mut buf = String::new(); + for (line_count, line_content) in template_str.lines().enumerate() { + if line_count >= line_start && line_count <= line_end { + buf.push_str(&format!("{:4} | {}\n", line_count, line_content)); + if line_count == line - 1 { + buf.push_str(" |"); + for c in 0..line_content.len() { + if c != col { + buf.push('-'); + } else { + buf.push('^'); + } + } + buf.push('\n'); + } + } + } + + buf +} + +impl fmt::Display for TemplateError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match (self.line_no, self.column_no, &self.segment) { + (Some(line), Some(col), &Some(ref seg)) => writeln!( + f, + "Template error: {}\n --> Template error in \"{}\":{}:{}\n |\n{} |\n = reason: {}", + self.reason, + self.template_name + .as_ref() + .unwrap_or(&"Unnamed template".to_owned()), + line, + col, + seg, + self.reason + ), + _ => write!(f, "{}", self.reason), + } + } +} + +#[cfg(feature = "script_helper")] +quick_error! { + #[derive(Debug)] + pub enum ScriptError { + IoError(err: IOError) { + from() + source(err) + } + ParseError(err: ParseError) { + from() + source(err) + } + } +} -- cgit v1.2.3