use alloc::{string::String, vec::Vec};
use crate::{
error::{err, Error},
util::escape,
};
use self::util::{Decimal, DecimalFormatter, Fractional, FractionalFormatter};
mod offset;
pub mod rfc2822;
mod rfc9557;
#[cfg(feature = "serde")]
pub mod serde;
pub mod strtime;
pub mod temporal;
mod util;
#[derive(Clone)]
pub(crate) struct Parsed<'i, V> {
value: V,
input: &'i [u8],
}
impl<'i, V: core::fmt::Display> Parsed<'i, V> {
#[inline]
fn into_full(self) -> Result<V, Error> {
if self.input.is_empty() {
return Ok(self.value);
}
Err(err!(
"parsed value '{value}', but unparsed input {unparsed:?} \
remains (expected no unparsed input)",
value = self.value,
unparsed = escape::Bytes(self.input),
))
}
}
impl<'i, V: core::fmt::Debug> core::fmt::Debug for Parsed<'i, V> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.debug_struct("Parsed")
.field("value", &self.value)
.field("input", &escape::Bytes(self.input))
.finish()
}
}
pub trait Write {
fn write_str(&mut self, string: &str) -> Result<(), Error>;
#[inline]
fn write_char(&mut self, char: char) -> Result<(), Error> {
self.write_str(char.encode_utf8(&mut [0; 4]))
}
}
impl Write for String {
#[inline]
fn write_str(&mut self, string: &str) -> Result<(), Error> {
self.push_str(string);
Ok(())
}
}
impl Write for Vec<u8> {
#[inline]
fn write_str(&mut self, string: &str) -> Result<(), Error> {
self.extend_from_slice(string.as_bytes());
Ok(())
}
}
impl<W: Write> Write for &mut W {
fn write_str(&mut self, string: &str) -> Result<(), Error> {
(**self).write_str(string)
}
#[inline]
fn write_char(&mut self, char: char) -> Result<(), Error> {
(**self).write_char(char)
}
}
#[cfg(feature = "std")]
#[derive(Clone, Debug)]
pub struct StdIoWrite<W>(pub W);
#[cfg(feature = "std")]
impl<W: std::io::Write> Write for StdIoWrite<W> {
#[inline]
fn write_str(&mut self, string: &str) -> Result<(), Error> {
self.0.write_all(string.as_bytes()).map_err(Error::adhoc)
}
}
#[derive(Clone, Debug)]
pub struct StdFmtWrite<W>(pub W);
impl<W: core::fmt::Write> Write for StdFmtWrite<W> {
#[inline]
fn write_str(&mut self, string: &str) -> Result<(), Error> {
self.0.write_str(string).map_err(Error::adhoc)
}
}
trait WriteExt: Write {
#[inline]
fn write_int(
&mut self,
formatter: &DecimalFormatter,
n: impl Into<i64>,
) -> Result<(), Error> {
self.write_decimal(&Decimal::new(formatter, n.into()))
}
#[inline]
fn write_fraction(
&mut self,
formatter: &FractionalFormatter,
n: impl Into<i64>,
) -> Result<(), Error> {
self.write_fractional(&Fractional::new(formatter, n.into()))
}
#[inline]
fn write_decimal(&mut self, decimal: &Decimal) -> Result<(), Error> {
self.write_str(decimal.as_str())
}
#[inline]
fn write_fractional(
&mut self,
fractional: &Fractional,
) -> Result<(), Error> {
self.write_str(fractional.as_str())
}
}
impl<W: Write> WriteExt for W {}