Let FastWritable propagate custom errors

This commit is contained in:
René Kijewski 2024-11-02 02:12:41 +01:00
parent a9bf11bb7d
commit fa29e2ab61
9 changed files with 57 additions and 50 deletions

View File

@ -64,6 +64,13 @@ impl From<fmt::Error> for Error {
}
}
impl From<Error> for fmt::Error {
#[inline]
fn from(_: Error) -> Self {
Self
}
}
#[cfg(feature = "serde_json")]
impl From<serde_json::Error> for Error {
#[inline]

View File

@ -377,7 +377,7 @@ impl<S: fmt::Display> fmt::Display for TruncateFilter<S> {
impl<S: FastWritable> FastWritable for TruncateFilter<S> {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
self.source
.write_into(&mut TruncateWriter::new(dest, self.remaining))
}
@ -924,7 +924,7 @@ impl<S: fmt::Display, P: fmt::Display> fmt::Display for Pluralize<S, P> {
impl<S: FastWritable, P: FastWritable> FastWritable for Pluralize<S, P> {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
match self {
Pluralize::Singular(value) => value.write_into(dest),
Pluralize::Plural(value) => value.write_into(dest),

View File

@ -80,7 +80,7 @@ impl<T: fmt::Display, E: Escaper> fmt::Display for EscapeDisplay<T, E> {
impl<T: FastWritable, E: Escaper> FastWritable for EscapeDisplay<T, E> {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
self.0.write_into(&mut EscapeWriter(dest, self.1))
}
}
@ -301,7 +301,7 @@ const _: () = {
// This is the fallback. The filter is not the last element of the filter chain.
impl<T: FastWritable> FastWritable for MaybeSafe<T> {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
let inner = match self {
MaybeSafe::Safe(inner) => inner,
MaybeSafe::NeedsEscaping(inner) => inner,
@ -336,7 +336,7 @@ const _: () = {
}
impl<T: FastWritable + ?Sized, E: Escaper> FastWritable for Wrapped<'_, T, E> {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
match *self {
Wrapped::Safe(t) => t.write_into(dest),
Wrapped::NeedsEscaping(t, e) => EscapeDisplay(t, e).write_into(dest),
@ -407,7 +407,7 @@ const _: () = {
// This is the fallback. The filter is not the last element of the filter chain.
impl<T: FastWritable> FastWritable for Safe<T> {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
self.0.write_into(dest)
}
}
@ -492,7 +492,7 @@ pub struct Writable<'a, S: ?Sized>(pub &'a S);
/// Used internally by rinja to select the appropriate [`write!()`] mechanism
pub trait WriteWritable {
/// Used internally by rinja to select the appropriate [`write!()`] mechanism
fn rinja_write<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result;
fn rinja_write<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()>;
}
/// Used internally by rinja to speed up writing some types.
@ -500,14 +500,14 @@ pub trait WriteWritable {
/// Types implementing this trait can be written without needing to employ an [`fmt::Formatter`].
pub trait FastWritable {
/// Used internally by rinja to speed up writing some types.
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result;
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()>;
}
const _: () = {
crate::impl_for_ref! {
impl FastWritable for T {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
<T>::write_into(self, dest)
}
}
@ -519,14 +519,14 @@ const _: () = {
<T as Deref>::Target: FastWritable,
{
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
self.as_ref().get_ref().write_into(dest)
}
}
impl<T: FastWritable + ToOwned> FastWritable for borrow::Cow<'_, T> {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
T::write_into(self.as_ref(), dest)
}
}
@ -536,8 +536,8 @@ const _: () = {
($($ty:ty)*) => { $(
impl FastWritable for $ty {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
dest.write_str(itoa::Buffer::new().format(*self))
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
itoa::Buffer::new().format(*self).write_into(dest)
}
}
)* };
@ -553,8 +553,8 @@ const _: () = {
($($id:ident)*) => { $(
impl FastWritable for core::num::$id {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
dest.write_str(itoa::Buffer::new().format(self.get()))
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
self.get().write_into(dest)
}
}
)* };
@ -567,55 +567,55 @@ const _: () = {
impl FastWritable for str {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
dest.write_str(self)
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
Ok(dest.write_str(self)?)
}
}
impl FastWritable for String {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
dest.write_str(self)
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
self.as_str().write_into(dest)
}
}
impl FastWritable for bool {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
dest.write_str(match self {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
Ok(dest.write_str(match self {
true => "true",
false => "false",
})
})?)
}
}
impl FastWritable for char {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
dest.write_char(*self)
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
Ok(dest.write_char(*self)?)
}
}
impl FastWritable for fmt::Arguments<'_> {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
match self.as_str() {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
Ok(match self.as_str() {
Some(s) => dest.write_str(s),
None => dest.write_fmt(*self),
}
}?)
}
}
impl<'a, S: FastWritable + ?Sized> WriteWritable for &Writable<'a, S> {
#[inline]
fn rinja_write<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
fn rinja_write<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
self.0.write_into(dest)
}
}
impl<'a, S: fmt::Display + ?Sized> WriteWritable for &&Writable<'a, S> {
#[inline]
fn rinja_write<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
write!(dest, "{}", self.0)
fn rinja_write<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
Ok(write!(dest, "{}", self.0)?)
}
}
};

View File

@ -33,15 +33,15 @@ pub struct FilesizeFormatFilter(f32);
impl fmt::Display for FilesizeFormatFilter {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.write_into(f)
Ok(self.write_into(f)?)
}
}
impl FastWritable for FilesizeFormatFilter {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
if self.0 < 1e3 {
(self.0 as u32).write_into(dest)?;
dest.write_str(" B")
Ok(dest.write_str(" B")?)
} else if let Some((prefix, factor)) = SI_PREFIXES
.iter()
.copied()
@ -50,7 +50,7 @@ impl FastWritable for FilesizeFormatFilter {
// u32 is big enough to hold the number 999_999
let scaled = (self.0 * factor) as u32;
(scaled / 100).write_into(dest)?;
dest.write_str(format_frac(&mut MaybeUninit::uninit(), prefix, scaled))
format_frac(&mut MaybeUninit::uninit(), prefix, scaled).write_into(dest)
} else {
too_big(self.0, dest)
}
@ -81,9 +81,9 @@ fn format_frac(buffer: &mut MaybeUninit<[u8; 8]>, prefix: u8, scaled: u32) -> &s
}
#[cold]
fn too_big<W: fmt::Write + ?Sized>(value: f32, dest: &mut W) -> fmt::Result {
fn too_big<W: fmt::Write + ?Sized>(value: f32, dest: &mut W) -> crate::Result<()> {
// the value exceeds 999 QB, so we omit the decimal places
write!(dest, "{:.0} QB", value / 1e30)
Ok(write!(dest, "{:.0} QB", value / 1e30)?)
}
/// `((si_prefix, factor), limit)`, the factor is offset by 10**2 to account for 2 decimal places

View File

@ -168,7 +168,7 @@ where
impl<S: Serialize> FastWritable for ToJson<S> {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W) -> crate::Result<()> {
fmt_json(f, &self.value)
}
}
@ -176,35 +176,36 @@ impl<S: Serialize> FastWritable for ToJson<S> {
impl<S: Serialize> fmt::Display for ToJson<S> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt_json(f, &self.value)
Ok(self.write_into(f)?)
}
}
impl<S: Serialize, I: AsIndent> FastWritable for ToJsonPretty<S, I> {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W) -> crate::Result<()> {
fmt_json_pretty(f, &self.value, self.indent.as_indent())
}
}
impl<S: Serialize, I: AsIndent> fmt::Display for ToJsonPretty<S, I> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt_json_pretty(f, &self.value, self.indent.as_indent())
Ok(self.write_into(f)?)
}
}
fn fmt_json<S: Serialize, W: fmt::Write + ?Sized>(dest: &mut W, value: &S) -> fmt::Result {
to_writer(JsonWriter(dest), value).map_err(|_| fmt::Error)
fn fmt_json<S: Serialize, W: fmt::Write + ?Sized>(dest: &mut W, value: &S) -> crate::Result<()> {
Ok(to_writer(JsonWriter(dest), value)?)
}
fn fmt_json_pretty<S: Serialize, W: fmt::Write + ?Sized>(
dest: &mut W,
value: &S,
indent: &str,
) -> fmt::Result {
) -> crate::Result<()> {
let formatter = PrettyFormatter::with_indent(indent.as_bytes());
let mut serializer = Serializer::with_formatter(JsonWriter(dest), formatter);
value.serialize(&mut serializer).map_err(|_| fmt::Error)
Ok(value.serialize(&mut serializer)?)
}
struct JsonWriter<'a, W: fmt::Write + ?Sized>(&'a mut W);

View File

@ -110,7 +110,7 @@ impl<T: fmt::Display> fmt::Display for UrlencodeFilter<T> {
impl<T: FastWritable> FastWritable for UrlencodeFilter<T> {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W) -> crate::Result<()> {
self.0.write_into(&mut UrlencodeWriter(f, self.1))
}
}

View File

@ -188,7 +188,7 @@ impl fmt::Display for Empty {
impl FastWritable for Empty {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, _: &mut W) -> fmt::Result {
fn write_into<W: fmt::Write + ?Sized>(&self, _: &mut W) -> crate::Result<()> {
Ok(())
}
}

View File

@ -216,12 +216,11 @@ impl<'a> Generator<'a> {
buf.write(
"\
#[inline]\
fn write_into<RinjaW>(&self, dest: &mut RinjaW) -> rinja::helpers::core::fmt::Result \
fn write_into<RinjaW>(&self, dest: &mut RinjaW) -> rinja::Result<()> \
where \
RinjaW: rinja::helpers::core::fmt::Write + ?rinja::helpers::core::marker::Sized,\
{\
rinja::Template::render_into(self, dest)\
.map_err(|_| rinja::helpers::core::fmt::Error)\
}\
}",
);

View File

@ -72,11 +72,11 @@ struct Foo {{ {} }}"##,
impl rinja::filters::FastWritable for Foo {
#[inline]
fn write_into<RinjaW>(&self, dest: &mut RinjaW) -> rinja::helpers::core::fmt::Result
fn write_into<RinjaW>(&self, dest: &mut RinjaW) -> rinja::Result<()>
where
RinjaW: rinja::helpers::core::fmt::Write + ?rinja::helpers::core::marker::Sized,
{
rinja::Template::render_into(self, dest).map_err(|_| rinja::helpers::core::fmt::Error)
rinja::Template::render_into(self, dest)
}
}
};