break: change RenderError into enum

This commit is contained in:
Kogia-sima 2020-12-20 21:55:55 +09:00
parent b58a51a1ae
commit 8deecff5fe
3 changed files with 72 additions and 78 deletions

View File

@ -70,7 +70,7 @@ impl<'a, T: Render> Render for Upper<'a, T> {
let content = b
.as_str()
.get(old_len..)
.ok_or_else(|| RenderError::new("buffer size shrinked while rendering"))?;
.ok_or_else(|| RenderError::BufSize)?;
let s = content.to_uppercase();
unsafe { b._set_len(old_len) };
b.push_str(&*s);
@ -107,7 +107,7 @@ impl<'a, T: Render> Render for Lower<'a, T> {
let content = b
.as_str()
.get(old_len..)
.ok_or_else(|| RenderError::new("buffer size shrinked while rendering"))?;
.ok_or_else(|| RenderError::BufSize)?;
let s = content.to_lowercase();
unsafe { b._set_len(old_len) };
b.push_str(&*s);
@ -166,7 +166,7 @@ fn trim_impl(b: &mut Buffer, old_len: usize) -> Result<(), RenderError> {
let new_contents = b
.as_str()
.get(old_len..)
.ok_or_else(|| RenderError::new("buffer size shrinked while rendering"))?;
.ok_or_else(|| RenderError::BufSize)?;
let trimmed = new_contents.trim();
let trimmed_len = trimmed.len();
@ -243,7 +243,7 @@ fn truncate_impl(
let new_contents = b
.as_str()
.get(old_len..)
.ok_or_else(|| RenderError::new("buffer size shrinked while rendering"))?;
.ok_or_else(|| RenderError::BufSize)?;
if let Some(idx) = new_contents.char_indices().nth(limit).map(|(i, _)| i) {
unsafe { b._set_len(old_len.wrapping_add(idx)) };

View File

@ -10,79 +10,9 @@ mod macros;
mod render;
mod size_hint;
pub use buffer::*;
pub use render::*;
pub use size_hint::*;
use std::fmt;
pub use buffer::Buffer;
pub use render::{Render, RenderError, RenderResult};
pub use size_hint::SizeHint;
#[doc(hidden)]
pub use crate::{render, render_escaped, render_noop, render_text};
#[derive(Clone, Debug)]
enum RenderErrorKind {
Msg(String),
Fmt(fmt::Error),
}
/// The error type which is returned from template function
#[derive(Clone, Debug)]
pub struct RenderError {
// currently RenderError simply wraps the fmt::Error
kind: RenderErrorKind,
}
impl RenderError {
/// Construct a new error with custom message
pub fn new(msg: &str) -> Self {
Self {
kind: RenderErrorKind::Msg(msg.to_owned()),
}
}
}
impl fmt::Display for RenderError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.kind {
RenderErrorKind::Msg(ref s) => f.write_str(&**s),
RenderErrorKind::Fmt(ref e) => fmt::Display::fmt(e, f),
}
}
}
impl std::error::Error for RenderError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self.kind {
RenderErrorKind::Msg(_) => None,
RenderErrorKind::Fmt(ref e) => Some(e),
}
}
}
impl From<fmt::Error> for RenderError {
#[inline]
fn from(other: fmt::Error) -> Self {
Self {
kind: RenderErrorKind::Fmt(other),
}
}
}
/// Result type returned from `TemplateOnce::render_once` method
pub type RenderResult = Result<String, RenderError>;
#[cfg(test)]
mod tests {
use super::*;
use std::error::Error;
#[test]
fn render_error() {
let err = RenderError::new("custom error");
assert!(err.source().is_none());
assert_eq!(format!("{}", err), "custom error");
let err = RenderError::from(std::fmt::Error::default());
assert!(err.source().is_some());
}
}

View File

@ -1,5 +1,6 @@
use std::borrow::Cow;
use std::cell::{Ref, RefMut};
use std::fmt;
use std::num::{
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize,
NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping,
@ -9,7 +10,7 @@ use std::rc::Rc;
use std::sync::{Arc, MutexGuard, RwLockReadGuard, RwLockWriteGuard};
use super::buffer::Buffer;
use super::{escape, RenderError};
use super::escape;
/// types which can be rendered inside buffer block (`<%= %>`)
///
@ -361,9 +362,62 @@ impl<T: Render> Render for Wrapping<T> {
}
}
/// The error type which is returned from template function
#[derive(Clone, Debug)]
pub enum RenderError {
/// Custom error message
Msg(String),
/// fmt::Error was raised during rendering
Fmt(fmt::Error),
/// Buffer size shrinked during rendering
///
/// This method won't be raised unless you implement `Render` trait for custom type.
///
/// Also there is no guarentee that this error will be returned whenever the buffer
/// size shrinked.
BufSize,
}
impl RenderError {
/// Construct a new error with custom message
pub fn new(msg: &str) -> Self {
RenderError::Msg(msg.to_owned())
}
}
impl fmt::Display for RenderError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
RenderError::Msg(ref s) => f.pad(&**s),
RenderError::Fmt(ref e) => fmt::Display::fmt(e, f),
RenderError::BufSize => f.pad("buffer size shrinked while rendering"),
}
}
}
impl std::error::Error for RenderError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
RenderError::Msg(_) | RenderError::BufSize => None,
RenderError::Fmt(ref e) => Some(e),
}
}
}
impl From<fmt::Error> for RenderError {
#[inline]
fn from(other: fmt::Error) -> Self {
RenderError::Fmt(other)
}
}
/// Result type returned from `TemplateOnce::render_once` method
pub type RenderResult = Result<String, RenderError>;
#[cfg(test)]
mod tests {
use super::*;
use std::error::Error;
#[test]
fn receiver_coercion() {
@ -430,4 +484,14 @@ mod tests {
Render::render_escaped(&std::f32::NAN, &mut b).unwrap();
assert_eq!(b.as_str(), "0.0inf-infNaN");
}
#[test]
fn render_error() {
let err = RenderError::new("custom error");
assert!(err.source().is_none());
assert_eq!(format!("{}", err), "custom error");
let err = RenderError::from(std::fmt::Error::default());
assert!(err.source().is_some());
}
}