xref: /aosp_15_r20/external/cronet/third_party/rust/chromium_crates_io/vendor/fend-core-1.4.6/src/num/base.rs (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 use std::{fmt, io};
2 
3 use crate::{
4 	error::FendError,
5 	result::FResult,
6 	serialize::{Deserialize, Serialize},
7 };
8 
9 #[derive(Copy, Clone, PartialEq, Eq)]
10 pub(crate) struct Base(BaseEnum);
11 
12 #[derive(Copy, Clone, PartialEq, Eq)]
13 enum BaseEnum {
14 	/// Binary with 0b prefix
15 	Binary,
16 	/// Octal with 0o prefix
17 	Octal,
18 	/// Hex with 0x prefix
19 	Hex,
20 	/// Custom base between 2 and 36 (inclusive), written as base#number
21 	Custom(u8),
22 	/// Plain (no prefix)
23 	Plain(u8),
24 }
25 
26 impl Base {
27 	pub(crate) const HEX: Self = Self(BaseEnum::Hex);
28 
base_as_u8(self) -> u829 	pub(crate) const fn base_as_u8(self) -> u8 {
30 		match self.0 {
31 			BaseEnum::Binary => 2,
32 			BaseEnum::Octal => 8,
33 			BaseEnum::Hex => 16,
34 			BaseEnum::Custom(b) | BaseEnum::Plain(b) => b,
35 		}
36 	}
37 
from_zero_based_prefix_char(ch: char) -> FResult<Self>38 	pub(crate) const fn from_zero_based_prefix_char(ch: char) -> FResult<Self> {
39 		Ok(match ch {
40 			'x' => Self(BaseEnum::Hex),
41 			'o' => Self(BaseEnum::Octal),
42 			'b' => Self(BaseEnum::Binary),
43 			_ => return Err(FendError::InvalidBasePrefix),
44 		})
45 	}
46 
from_plain_base(base: u8) -> FResult<Self>47 	pub(crate) const fn from_plain_base(base: u8) -> FResult<Self> {
48 		if base < 2 {
49 			return Err(FendError::BaseTooSmall);
50 		} else if base > 36 {
51 			return Err(FendError::BaseTooLarge);
52 		}
53 		Ok(Self(BaseEnum::Plain(base)))
54 	}
55 
from_custom_base(base: u8) -> FResult<Self>56 	pub(crate) const fn from_custom_base(base: u8) -> FResult<Self> {
57 		if base < 2 {
58 			return Err(FendError::BaseTooSmall);
59 		} else if base > 36 {
60 			return Err(FendError::BaseTooLarge);
61 		}
62 		Ok(Self(BaseEnum::Custom(base)))
63 	}
64 
write_prefix(self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error>65 	pub(crate) fn write_prefix(self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
66 		match self.0 {
67 			BaseEnum::Binary => write!(f, "0b")?,
68 			BaseEnum::Octal => write!(f, "0o")?,
69 			BaseEnum::Hex => write!(f, "0x")?,
70 			BaseEnum::Custom(b) => write!(f, "{b}#")?,
71 			BaseEnum::Plain(_) => (),
72 		}
73 		Ok(())
74 	}
75 
has_prefix(self) -> bool76 	pub(crate) const fn has_prefix(self) -> bool {
77 		!matches!(self.0, BaseEnum::Plain(_))
78 	}
79 
digit_as_char(digit: u64) -> Option<char>80 	pub(crate) const fn digit_as_char(digit: u64) -> Option<char> {
81 		Some(match digit {
82 			0 => '0',
83 			1 => '1',
84 			2 => '2',
85 			3 => '3',
86 			4 => '4',
87 			5 => '5',
88 			6 => '6',
89 			7 => '7',
90 			8 => '8',
91 			9 => '9',
92 			10 => 'a',
93 			11 => 'b',
94 			12 => 'c',
95 			13 => 'd',
96 			14 => 'e',
97 			15 => 'f',
98 			16 => 'g',
99 			17 => 'h',
100 			18 => 'i',
101 			19 => 'j',
102 			20 => 'k',
103 			21 => 'l',
104 			22 => 'm',
105 			23 => 'n',
106 			24 => 'o',
107 			25 => 'p',
108 			26 => 'q',
109 			27 => 'r',
110 			28 => 's',
111 			29 => 't',
112 			30 => 'u',
113 			31 => 'v',
114 			32 => 'w',
115 			33 => 'x',
116 			34 => 'y',
117 			35 => 'z',
118 			_ => return None,
119 		})
120 	}
121 
serialize(self, write: &mut impl io::Write) -> FResult<()>122 	pub(crate) fn serialize(self, write: &mut impl io::Write) -> FResult<()> {
123 		match self.0 {
124 			BaseEnum::Binary => 1u8.serialize(write)?,
125 			BaseEnum::Octal => 2u8.serialize(write)?,
126 			BaseEnum::Hex => 3u8.serialize(write)?,
127 			BaseEnum::Custom(b) => {
128 				4u8.serialize(write)?;
129 				b.serialize(write)?;
130 			}
131 			BaseEnum::Plain(b) => {
132 				5u8.serialize(write)?;
133 				b.serialize(write)?;
134 			}
135 		}
136 		Ok(())
137 	}
138 
deserialize(read: &mut impl io::Read) -> FResult<Self>139 	pub(crate) fn deserialize(read: &mut impl io::Read) -> FResult<Self> {
140 		Ok(Self(match u8::deserialize(read)? {
141 			1 => BaseEnum::Binary,
142 			2 => BaseEnum::Octal,
143 			3 => BaseEnum::Hex,
144 			4 => BaseEnum::Custom(u8::deserialize(read)?),
145 			5 => BaseEnum::Plain(u8::deserialize(read)?),
146 			_ => return Err(FendError::DeserializationError),
147 		}))
148 	}
149 }
150 
151 impl Default for Base {
default() -> Self152 	fn default() -> Self {
153 		Self(BaseEnum::Plain(10))
154 	}
155 }
156 
157 impl fmt::Debug for Base {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result158 	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159 		match self.0 {
160 			BaseEnum::Binary => write!(f, "binary"),
161 			BaseEnum::Octal => write!(f, "octal"),
162 			BaseEnum::Hex => write!(f, "hex"),
163 			BaseEnum::Custom(b) => write!(f, "base {b} (with prefix)"),
164 			BaseEnum::Plain(b) => write!(f, "base {b}"),
165 		}
166 	}
167 }
168