use num_traits::Bounded;
use std::fmt::Debug;
#[cfg(feature = "serde_support")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
pub enum UnsafeEnum<T, I> {
Valid(T),
Invalid(I),
}
impl<T, I> Default for UnsafeEnum<T, I>
where
T: Default,
{
fn default() -> Self {
UnsafeEnum::Valid(Default::default())
}
}
impl<E, T> crate::traits::ToPrimitive for UnsafeEnum<E, T>
where
E: crate::traits::ToPrimitive<Output=T>,
T: Copy,
{
type Output = T;
fn to_primitive(&self) -> T {
match self {
UnsafeEnum::Valid(ref e) => e.to_primitive(),
UnsafeEnum::Invalid(n) => *n,
}
}
}
#[derive(Debug, Default, Clone)]
pub struct Utf8String {
pub(crate) inner: Vec<Utf8Char>,
}
impl Utf8String {
pub fn new(s: &str) -> Self {
Utf8String {
inner: s.chars().map(|c| Utf8Char(c)).collect(),
}
}
}
#[derive(Debug, Default, Clone)]
pub struct AsciiString {
pub(crate) inner: Vec<AsciiChar>,
}
impl AsciiString {
pub fn new(s: &str) -> Self {
AsciiString {
inner: s.chars().map(|c| AsciiChar(c)).collect(),
}
}
}
#[derive(Default, Debug, Clone)]
pub(crate) struct Utf8Char(pub(crate) char);
#[derive(Default, Debug, Clone)]
pub(crate) struct AsciiChar(pub(crate) char);
#[derive(Debug, Default, Clone)]
pub struct Constraints<T: Bounded + Debug> {
pub min: Option<T>,
pub max: Option<T>,
pub weighted: Weighted,
pub max_size: Option<usize>,
pub base_object_size_accounted_for: bool,
}
impl<T: Bounded + Debug> Constraints<T> {
pub fn new() -> Constraints<T> {
Constraints {
min: None,
max: None,
weighted: Weighted::None,
max_size: None,
base_object_size_accounted_for: false,
}
}
pub fn min<'a>(&'a mut self, min: T) -> &'a mut Constraints<T> {
self.min = Some(min);
self
}
pub fn max<'a>(&'a mut self, max: T) -> &'a mut Constraints<T> {
self.max = Some(max);
self
}
pub fn weighted<'a>(&'a mut self, weighted: Weighted) -> &'a mut Constraints<T> {
self.weighted = weighted;
self
}
pub fn max_size<'a>(&'a mut self, max_size: usize) -> &'a mut Constraints<T> {
self.max_size = Some(max_size);
self
}
pub fn account_for_base_object_size<'a, U: crate::traits::SerializedSize>(&'a mut self) -> &'a mut Constraints<T> {
if !self.base_object_size_accounted_for {
if let Some(ref mut max_size) = self.max_size {
if U::min_nonzero_elements_size() > *max_size {
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::min_nonzero_elements_size(), *max_size);
}
*max_size -= U::min_nonzero_elements_size();
}
self.base_object_size_accounted_for = true;
}
self
}
pub fn set_base_size_accounted_for<'a>(&'a mut self) -> &'a mut Constraints<T> {
self.base_object_size_accounted_for = true;
self
}
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Weighted {
None,
Min,
Max,
}
impl Default for Weighted {
fn default() -> Self {
Weighted::None
}
}