Source code

Revision control

Copy as Markdown

Other Tools

use core::fmt::{self, Display};
/// Describes how a TOML integer should be formatted.
///
/// # Example
///
/// ```rust
/// # #[cfg(feature = "alloc")] {
/// # use toml_writer::ToTomlValue as _;
/// let format = toml_writer::TomlIntegerFormat::new().as_hex_lower();
/// let number = 10;
/// let number = format.format(number).unwrap_or(toml_writer::TomlInteger::new(number));
/// let number = number.to_toml_value();
/// assert_eq!(number, "0xa");
/// # }
/// ```
#[derive(Copy, Clone, Debug)]
pub struct TomlIntegerFormat {
radix: Radix,
}
impl TomlIntegerFormat {
/// Creates a new integer format (decimal).
pub fn new() -> Self {
Self {
radix: Radix::Decimal,
}
}
/// Sets the format to decimal.
pub fn as_decimal(mut self) -> Self {
self.radix = Radix::Decimal;
self
}
/// Sets the format to hexadecimal with all characters in uppercase.
pub fn as_hex_upper(mut self) -> Self {
self.radix = Radix::Hexadecimal {
case: HexCase::Upper,
};
self
}
/// Sets the format to hexadecimal with all characters in lowercase.
pub fn as_hex_lower(mut self) -> Self {
self.radix = Radix::Hexadecimal {
case: HexCase::Lower,
};
self
}
/// Sets the format to octal.
pub fn as_octal(mut self) -> Self {
self.radix = Radix::Octal;
self
}
/// Sets the format to binary.
pub fn as_binary(mut self) -> Self {
self.radix = Radix::Binary;
self
}
/// Formats `value` as a TOML integer.
///
/// Returns `None` if the value cannot be formatted
/// (e.g. value is negative and the radix is not decimal).
pub fn format<N: PartialOrd<i32>>(self, value: N) -> Option<TomlInteger<N>>
where
TomlInteger<N>: crate::WriteTomlValue,
{
match self.radix {
Radix::Decimal => (),
Radix::Hexadecimal { .. } | Radix::Octal | Radix::Binary => {
if value < 0 {
return None;
}
}
}
Some(TomlInteger {
value,
format: self,
})
}
}
impl Default for TomlIntegerFormat {
fn default() -> Self {
Self::new()
}
}
/// Helper struct for formatting TOML integers.
///
/// This may be constructed by calling [`TomlIntegerFormat::format()`].
#[derive(Copy, Clone, Debug)]
pub struct TomlInteger<N> {
value: N,
format: TomlIntegerFormat,
}
impl<N> TomlInteger<N>
where
Self: crate::WriteTomlValue,
{
/// Apply default formatting
pub fn new(value: N) -> Self {
Self {
value,
format: TomlIntegerFormat::new(),
}
}
}
impl crate::WriteTomlValue for TomlInteger<u8> {
fn write_toml_value<W: crate::TomlWrite + ?Sized>(&self, writer: &mut W) -> fmt::Result {
write_toml_value(self.value, &self.format, writer)
}
}
impl crate::WriteTomlValue for TomlInteger<i8> {
fn write_toml_value<W: crate::TomlWrite + ?Sized>(&self, writer: &mut W) -> fmt::Result {
write_toml_value(self.value, &self.format, writer)
}
}
impl crate::WriteTomlValue for TomlInteger<u16> {
fn write_toml_value<W: crate::TomlWrite + ?Sized>(&self, writer: &mut W) -> fmt::Result {
write_toml_value(self.value, &self.format, writer)
}
}
impl crate::WriteTomlValue for TomlInteger<i16> {
fn write_toml_value<W: crate::TomlWrite + ?Sized>(&self, writer: &mut W) -> fmt::Result {
write_toml_value(self.value, &self.format, writer)
}
}
impl crate::WriteTomlValue for TomlInteger<u32> {
fn write_toml_value<W: crate::TomlWrite + ?Sized>(&self, writer: &mut W) -> fmt::Result {
write_toml_value(self.value, &self.format, writer)
}
}
impl crate::WriteTomlValue for TomlInteger<i32> {
fn write_toml_value<W: crate::TomlWrite + ?Sized>(&self, writer: &mut W) -> fmt::Result {
write_toml_value(self.value, &self.format, writer)
}
}
impl crate::WriteTomlValue for TomlInteger<u64> {
fn write_toml_value<W: crate::TomlWrite + ?Sized>(&self, writer: &mut W) -> fmt::Result {
write_toml_value(self.value, &self.format, writer)
}
}
impl crate::WriteTomlValue for TomlInteger<i64> {
fn write_toml_value<W: crate::TomlWrite + ?Sized>(&self, writer: &mut W) -> fmt::Result {
write_toml_value(self.value, &self.format, writer)
}
}
impl crate::WriteTomlValue for TomlInteger<u128> {
fn write_toml_value<W: crate::TomlWrite + ?Sized>(&self, writer: &mut W) -> fmt::Result {
write_toml_value(self.value, &self.format, writer)
}
}
impl crate::WriteTomlValue for TomlInteger<i128> {
fn write_toml_value<W: crate::TomlWrite + ?Sized>(&self, writer: &mut W) -> fmt::Result {
write_toml_value(self.value, &self.format, writer)
}
}
impl crate::WriteTomlValue for TomlInteger<usize> {
fn write_toml_value<W: crate::TomlWrite + ?Sized>(&self, writer: &mut W) -> fmt::Result {
write_toml_value(self.value, &self.format, writer)
}
}
impl crate::WriteTomlValue for TomlInteger<isize> {
fn write_toml_value<W: crate::TomlWrite + ?Sized>(&self, writer: &mut W) -> fmt::Result {
write_toml_value(self.value, &self.format, writer)
}
}
#[derive(Copy, Clone, Debug)]
enum Radix {
Decimal,
Hexadecimal { case: HexCase },
Octal,
Binary,
}
#[derive(Copy, Clone, Debug)]
enum HexCase {
Upper,
Lower,
}
fn write_toml_value<
N: Display + fmt::UpperHex + fmt::LowerHex + fmt::Octal + fmt::Binary,
W: crate::TomlWrite + ?Sized,
>(
value: N,
format: &TomlIntegerFormat,
writer: &mut W,
) -> fmt::Result {
match format.radix {
Radix::Decimal => write!(writer, "{value}")?,
Radix::Hexadecimal { case } => match case {
HexCase::Upper => write!(writer, "0x{value:X}")?,
HexCase::Lower => write!(writer, "0x{value:x}")?,
},
Radix::Octal => write!(writer, "0o{value:o}")?,
Radix::Binary => write!(writer, "0b{value:b}")?,
}
Ok(())
}