1use std::{fmt, num::ParseIntError, str::FromStr};
32
33use const_macros::{const_early, const_ok, const_try};
34
35#[cfg(feature = "diagnostics")]
36use miette::Diagnostic;
37
38#[cfg(feature = "serde")]
39use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
40
41use thiserror::Error;
42
43use crate::{encoding, length::Length};
44
45pub const MIN: usize = 32;
47
48pub const DEFAULT: usize = 64;
50
51pub const MAX: usize = 96;
53
54#[derive(Debug, Error)]
58#[error("unexpected count `{value}`; expected in range `[{MIN}, {MAX}]`")]
59pub struct Error {
60 pub value: usize,
62}
63
64impl Error {
65 pub const fn new(value: usize) -> Self {
67 Self { value }
68 }
69}
70
71#[derive(Debug, Error)]
73#[cfg_attr(feature = "diagnostics", derive(Diagnostic))]
74pub enum ParseError {
75 #[error("invalid count")]
77 #[cfg_attr(
78 feature = "diagnostics",
79 diagnostic(
80 code(pkce_std::count::parse),
81 help("make sure the count is in the valid range")
82 )
83 )]
84 Length(#[from] Error),
85 #[error("parse integer error")]
87 #[cfg_attr(
88 feature = "diagnostics",
89 diagnostic(code(pkce_std::count::parse::int), help("check the string"))
90 )]
91 Int(#[from] ParseIntError),
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
110pub struct Count {
111 value: usize,
112}
113
114#[cfg(feature = "serde")]
115impl Serialize for Count {
116 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
117 self.get().serialize(serializer)
118 }
119}
120
121#[cfg(feature = "serde")]
122impl<'de> Deserialize<'de> for Count {
123 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
124 let value = usize::deserialize(deserializer)?;
125
126 Self::new(value).map_err(de::Error::custom)
127 }
128}
129
130impl TryFrom<usize> for Count {
131 type Error = Error;
132
133 fn try_from(value: usize) -> Result<Self, Self::Error> {
134 Self::new(value)
135 }
136}
137
138impl From<Count> for usize {
139 fn from(count: Count) -> Self {
140 count.get()
141 }
142}
143
144impl From<Count> for Length {
145 fn from(count: Count) -> Self {
146 unsafe { Self::new_unchecked(count.encoded()) }
148 }
149}
150
151impl fmt::Display for Count {
152 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
153 self.get().fmt(formatter)
154 }
155}
156
157impl Default for Count {
158 fn default() -> Self {
159 Self::DEFAULT
160 }
161}
162
163impl FromStr for Count {
164 type Err = ParseError;
165
166 fn from_str(string: &str) -> Result<Self, Self::Err> {
167 let value = string.parse()?;
168
169 let count = Self::new(value)?;
170
171 Ok(count)
172 }
173}
174
175impl Count {
176 pub const fn new(value: usize) -> Result<Self, Error> {
184 const_try!(Self::check(value));
185
186 Ok(unsafe { Self::new_unchecked(value) })
188 }
189
190 pub const fn new_ok(value: usize) -> Option<Self> {
194 const_ok!(Self::new(value))
195 }
196
197 pub const fn check(value: usize) -> Result<(), Error> {
203 const_early!(value < MIN || value > MAX => Error::new(value));
204
205 Ok(())
206 }
207
208 pub const unsafe fn new_unchecked(value: usize) -> Self {
214 Self { value }
215 }
216
217 pub const fn get(self) -> usize {
219 self.value
220 }
221
222 pub const fn encoded(self) -> usize {
224 encoding::length(self.get())
225 }
226
227 pub const MIN: Self = Self::new_ok(MIN).unwrap();
229
230 pub const DEFAULT: Self = Self::new_ok(DEFAULT).unwrap();
232
233 pub const MAX: Self = Self::new_ok(MAX).unwrap();
235}