mod impls;
use core::fmt::{self, Arguments};
use crate::borrow::TryToOwned;
use crate::error::Error;
use crate::string::String;
pub trait TryWrite {
fn try_write_str(&mut self, s: &str) -> Result<(), Error>;
#[inline]
fn try_write_char(&mut self, c: char) -> Result<(), Error> {
self.try_write_str(c.encode_utf8(&mut [0; 4]))
}
#[inline]
#[doc(hidden)]
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> Result<(), Error> {
struct Writer<'a, T>
where
T: ?Sized,
{
target: &'a mut T,
error: Option<Error>,
}
impl<T> fmt::Write for Writer<'_, T>
where
T: ?Sized + TryWrite,
{
#[inline]
fn write_str(&mut self, s: &str) -> fmt::Result {
if let Err(error) = (*self.target).try_write_str(s) {
self.error = Some(error);
}
Ok(())
}
#[inline]
fn write_char(&mut self, c: char) -> fmt::Result {
if let Err(error) = (*self.target).try_write_char(c) {
self.error = Some(error);
}
Ok(())
}
}
let mut writer = Writer {
target: self,
error: None,
};
if let Err(fmt::Error) = fmt::write(&mut writer, args) {
return Err(Error::FormatError);
}
if let Some(error) = writer.error {
Err(error)
} else {
Ok(())
}
}
}
#[inline]
pub fn try_format(args: Arguments<'_>) -> Result<String, Error> {
#[cfg(rune_nightly)]
fn estimated_capacity(args: &Arguments<'_>) -> usize {
args.estimated_capacity()
}
#[cfg(not(rune_nightly))]
fn estimated_capacity(_: &Arguments<'_>) -> usize {
0
}
fn format_inner(args: Arguments<'_>) -> Result<String, Error> {
let capacity = estimated_capacity(&args);
let mut output = String::try_with_capacity(capacity)?;
output.write_fmt(args)?;
Ok(output)
}
match args.as_str() {
Some(string) => string.try_to_owned(),
None => format_inner(args),
}
}