1use std::{fmt, num::ParseIntError, str::FromStr};
18
19use const_macros::{const_early, const_ok, const_try};
20
21#[cfg(feature = "diagnostics")]
22use miette::Diagnostic;
23
24#[cfg(feature = "serde")]
25use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
26
27use thiserror::Error;
28
29use crate::{count, encoding};
30
31pub const MIN: usize = encoding::length(count::MIN);
33
34pub const DEFAULT: usize = encoding::length(count::DEFAULT);
36
37pub const MAX: usize = encoding::length(count::MAX);
39
40#[derive(Debug, Error)]
44#[error("expected length in `[{MIN}, {MAX}]` range, got `{value}`")]
45#[cfg_attr(
46 feature = "diagnostics",
47 derive(Diagnostic),
48 diagnostic(
49 code(pkce_std::length),
50 help("make sure the length is at least `{MIN}` and at most `{MAX}`")
51 )
52)]
53pub struct Error {
54 pub value: usize,
56}
57
58impl Error {
59 pub const fn new(value: usize) -> Self {
61 Self { value }
62 }
63}
64
65#[derive(Debug, Error)]
67#[cfg_attr(feature = "diagnostics", derive(Diagnostic))]
68pub enum ParseError {
69 #[error("invalid length")]
71 #[cfg_attr(
72 feature = "diagnostics",
73 diagnostic(
74 code(pkce_std::length::parse),
75 help("make sure the length is in the valid range")
76 )
77 )]
78 Length(#[from] Error),
79 #[error("parse integer error")]
81 #[cfg_attr(
82 feature = "diagnostics",
83 diagnostic(code(pkce_std::length::parse::int), help("check the string"))
84 )]
85 Int(#[from] ParseIntError),
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
104pub struct Length {
105 value: usize,
106}
107
108impl TryFrom<usize> for Length {
109 type Error = Error;
110
111 fn try_from(value: usize) -> Result<Self, Self::Error> {
112 Self::new(value)
113 }
114}
115
116impl From<Length> for usize {
117 fn from(length: Length) -> Self {
118 length.get()
119 }
120}
121
122impl fmt::Display for Length {
123 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
124 self.get().fmt(formatter)
125 }
126}
127
128#[cfg(feature = "serde")]
129impl Serialize for Length {
130 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
131 self.get().serialize(serializer)
132 }
133}
134
135#[cfg(feature = "serde")]
136impl<'de> Deserialize<'de> for Length {
137 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
138 let value = usize::deserialize(deserializer)?;
139
140 Self::new(value).map_err(de::Error::custom)
141 }
142}
143
144impl Default for Length {
145 fn default() -> Self {
146 Self::DEFAULT
147 }
148}
149
150impl FromStr for Length {
151 type Err = ParseError;
152
153 fn from_str(string: &str) -> Result<Self, Self::Err> {
154 let value = string.parse()?;
155
156 let length = Self::new(value)?;
157
158 Ok(length)
159 }
160}
161
162impl Length {
163 pub const fn new(value: usize) -> Result<Self, Error> {
171 const_try!(Self::check(value));
172
173 Ok(unsafe { Self::new_unchecked(value) })
175 }
176
177 pub const fn new_ok(value: usize) -> Option<Self> {
181 const_ok!(Self::new(value))
182 }
183
184 pub const fn check(value: usize) -> Result<(), Error> {
190 const_early!(value < MIN || value > MAX => Error::new(value));
191
192 Ok(())
193 }
194
195 pub const unsafe fn new_unchecked(value: usize) -> Self {
201 Self { value }
202 }
203
204 pub const fn get(self) -> usize {
206 self.value
207 }
208
209 pub const MIN: Self = Self::new_ok(MIN).unwrap();
211
212 pub const DEFAULT: Self = Self::new_ok(DEFAULT).unwrap();
214
215 pub const MAX: Self = Self::new_ok(MAX).unwrap();
217}