1 use std::{fmt, io};
2 
3 use crate::{
4 	error::FendError,
5 	result::FResult,
6 	serialize::{Deserialize, Serialize},
7 };
8 
9 #[derive(PartialEq, Eq, Clone, Copy, Default)]
10 #[must_use]
11 pub(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 
32 impl fmt::Display for FormattingStyle {
fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error>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 
46 impl fmt::Debug for FormattingStyle {
fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error>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 
60 impl FormattingStyle {
serialize(&self, write: &mut impl io::Write) -> FResult<()>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 
deserialize(read: &mut impl io::Read) -> FResult<Self>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 }
93