fend_core/num/
formatting_style.rs

1use std::{fmt, io};
2
3use crate::{
4	error::FendError,
5	result::FResult,
6	serialize::{Deserialize, Serialize},
7};
8
9#[derive(PartialEq, Eq, Clone, Copy, Default)]
10#[must_use]
11pub(crate) enum FormattingStyle {
12	/// Print value as an improper fraction
13	ImproperFraction,
14	/// Print as a mixed fraction, e.g. 1 1/2
15	MixedFraction,
16	/// Print as a float, possibly indicating recurring digits
17	/// with parentheses, e.g. 7/9 => 0.(81)
18	ExactFloat,
19	/// Print with the given number of decimal places
20	DecimalPlaces(usize),
21	/// Print with the given number of significant figures (not including any leading zeroes)
22	SignificantFigures(usize),
23	/// If exact and no recurring digits: `ExactFloat`, if complex/imag: `MixedFraction`,
24	/// otherwise: DecimalPlaces(10)
25	#[default]
26	Auto,
27	/// If not exact: DecimalPlaces(10). If no recurring digits: `ExactFloat`.
28	/// Other numbers: `MixedFraction`, albeit possibly including fractions of pi
29	Exact,
30}
31
32impl fmt::Display for FormattingStyle {
33	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
34		match self {
35			Self::ImproperFraction => write!(f, "fraction"),
36			Self::MixedFraction => write!(f, "mixed_fraction"),
37			Self::ExactFloat => write!(f, "float"),
38			Self::Exact => write!(f, "exact"),
39			Self::DecimalPlaces(d) => write!(f, "{d} dp"),
40			Self::SignificantFigures(s) => write!(f, "{s} sf"),
41			Self::Auto => write!(f, "auto"),
42		}
43	}
44}
45
46impl fmt::Debug for FormattingStyle {
47	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
48		match self {
49			Self::ImproperFraction => write!(f, "improper fraction"),
50			Self::MixedFraction => write!(f, "mixed fraction"),
51			Self::ExactFloat => write!(f, "exact float"),
52			Self::Exact => write!(f, "exact"),
53			Self::DecimalPlaces(d) => write!(f, "{d} dp"),
54			Self::SignificantFigures(s) => write!(f, "{s} sf"),
55			Self::Auto => write!(f, "auto"),
56		}
57	}
58}
59
60impl FormattingStyle {
61	pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FResult<()> {
62		match self {
63			Self::ImproperFraction => 1u8.serialize(write)?,
64			Self::MixedFraction => 2u8.serialize(write)?,
65			Self::ExactFloat => 3u8.serialize(write)?,
66			Self::Exact => 4u8.serialize(write)?,
67			Self::DecimalPlaces(d) => {
68				5u8.serialize(write)?;
69				d.serialize(write)?;
70			}
71			Self::SignificantFigures(s) => {
72				6u8.serialize(write)?;
73				s.serialize(write)?;
74			}
75			Self::Auto => 7u8.serialize(write)?,
76		}
77		Ok(())
78	}
79
80	pub(crate) fn deserialize(read: &mut impl io::Read) -> FResult<Self> {
81		Ok(match u8::deserialize(read)? {
82			1 => Self::ImproperFraction,
83			2 => Self::MixedFraction,
84			3 => Self::ExactFloat,
85			4 => Self::Exact,
86			5 => Self::DecimalPlaces(usize::deserialize(read)?),
87			6 => Self::SignificantFigures(usize::deserialize(read)?),
88			7 => Self::Auto,
89			_ => return Err(FendError::DeserializationError),
90		})
91	}
92}