1use num_traits::Bounded;
2use std::fmt::Debug;
3
4#[cfg(feature = "serde_support")]
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Copy)]
44#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
45pub enum UnsafeEnum<T, I> {
46 Valid(T),
47 Invalid(I),
48}
49
50impl<T, I> Default for UnsafeEnum<T, I>
51where
52 T: Default,
53{
54 fn default() -> Self {
55 UnsafeEnum::Valid(Default::default())
56 }
57}
58
59impl<E, T> crate::traits::ToPrimitive for UnsafeEnum<E, T>
60where
61 E: crate::traits::ToPrimitive<Output = T>,
62 T: Copy,
63{
64 type Output = T;
65
66 fn to_primitive(&self) -> T {
67 match self {
68 UnsafeEnum::Valid(ref e) => e.to_primitive(),
69 UnsafeEnum::Invalid(n) => *n,
70 }
71 }
72}
73
74#[derive(Debug, Default, Clone)]
77pub struct Utf8String {
78 pub(crate) inner: Vec<Utf8Char>,
79}
80
81impl Utf8String {
82 pub fn new(s: &str) -> Self {
83 Utf8String {
84 inner: s.chars().map(|c| Utf8Char(c)).collect(),
85 }
86 }
87}
88
89#[derive(Debug, Default, Clone)]
91pub struct AsciiString {
92 pub(crate) inner: Vec<AsciiChar>,
93}
94
95impl AsciiString {
96 pub fn new(s: &str) -> Self {
97 AsciiString {
98 inner: s.chars().map(|c| AsciiChar(c)).collect(),
99 }
100 }
101}
102
103#[derive(Default, Debug, Clone)]
105pub(crate) struct Utf8Char(pub(crate) char);
106
107#[derive(Default, Debug, Clone)]
109pub(crate) struct AsciiChar(pub(crate) char);
110
111#[derive(Debug, Default, Clone)]
114pub struct Constraints<T: Bounded + Debug> {
115 pub min: Option<T>,
117 pub max: Option<T>,
119 pub weighted: Weighted,
121 pub max_size: Option<usize>,
123 pub base_object_size_accounted_for: bool,
124}
125
126impl<T: Bounded + Debug> Constraints<T> {
127 pub fn new() -> Constraints<T> {
128 Constraints {
129 min: None,
130 max: None,
131 weighted: Weighted::None,
132 max_size: None,
133 base_object_size_accounted_for: false,
134 }
135 }
136
137 pub fn min<'a>(&'a mut self, min: T) -> &'a mut Constraints<T> {
138 self.min = Some(min);
139 self
140 }
141
142 pub fn max<'a>(&'a mut self, max: T) -> &'a mut Constraints<T> {
143 self.max = Some(max);
144 self
145 }
146
147 pub fn weighted<'a>(&'a mut self, weighted: Weighted) -> &'a mut Constraints<T> {
148 self.weighted = weighted;
149 self
150 }
151
152 pub fn max_size<'a>(&'a mut self, max_size: usize) -> &'a mut Constraints<T> {
153 self.max_size = Some(max_size);
154 self
155 }
156
157 pub fn account_for_base_object_size<'a, U: crate::traits::SerializedSize>(
158 &'a mut self,
159 ) -> &'a mut Constraints<T> {
160 if !self.base_object_size_accounted_for {
161 if let Some(ref mut max_size) = self.max_size {
162 if U::max_default_object_size() > *max_size {
163 panic!("minimum base object size is larger than the desired maximum output size (required at least: 0x{:X}, max: 0x{:X}). Check to ensure your output buffer for this object is larger enough", U::max_default_object_size(), *max_size);
164 }
165
166 *max_size = max_size.saturating_sub(U::max_default_object_size());
167 }
168
169 self.base_object_size_accounted_for = true;
170 }
171
172 self
173 }
174
175 pub fn set_base_size_accounted_for<'a>(&'a mut self) -> &'a mut Constraints<T> {
176 self.base_object_size_accounted_for = true;
177 self
178 }
179}
180
181#[derive(Debug, PartialEq, Clone, Copy)]
183pub enum Weighted {
184 None,
185 Min,
186 Max,
187}
188
189impl Default for Weighted {
190 fn default() -> Self {
191 Weighted::None
192 }
193}