1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
use core::ops::Mul;
use core::ops::Add;

pub use cdr_encoding_size_derive::*;

/// This type is used to count maximum size of a Key when serialized
/// according to CDR but without field alignment.
/// The purpose is to find out if the (key) type always fits into 16 bytes or not.
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd,)]
pub enum CdrEncodingMaxSize {
  Bytes(usize),
  Unbounded,
}

impl Add for CdrEncodingMaxSize {
    type Output = Self;

    fn add(self, other: Self) -> Self::Output {
      use CdrEncodingMaxSize::*;
      match (self,other) {
        (Bytes(s),Bytes(o)) => Bytes(s+o),
        (Unbounded,_) => Unbounded,
        (_,Unbounded) => Unbounded,
      }
    }
}


impl Mul<usize> for CdrEncodingMaxSize {
  type Output = Self;

  fn mul(self, rhs: usize) -> Self::Output {
    use CdrEncodingMaxSize::*;
    match self {
      Unbounded => Unbounded,
      Bytes(b) => Bytes(b*rhs),
    }
  }
}

// -------------------------------------------
// -------------------------------------------

pub trait CdrEncodingSize
{
  fn cdr_encoding_max_size() -> CdrEncodingMaxSize;
}  

// -------------------------------------------
// -------------------------------------------


impl CdrEncodingSize for () {
  fn cdr_encoding_max_size() -> CdrEncodingMaxSize
  { CdrEncodingMaxSize::Bytes(0) }
}

macro_rules! prim_cdr_encoding_size {
  ($t:ty) => {
    impl CdrEncodingSize for $t {
      #[inline]
      fn cdr_encoding_max_size() -> CdrEncodingMaxSize
      { CdrEncodingMaxSize::Bytes( std::mem::size_of::<$t>() ) }
    }
  };
}

prim_cdr_encoding_size!(u8);
prim_cdr_encoding_size!(u16);
prim_cdr_encoding_size!(u32);
prim_cdr_encoding_size!(u64);
prim_cdr_encoding_size!(u128);

prim_cdr_encoding_size!(i8);
prim_cdr_encoding_size!(i16);
prim_cdr_encoding_size!(i32);
prim_cdr_encoding_size!(i64);
prim_cdr_encoding_size!(i128);

prim_cdr_encoding_size!(char);
//prim_cdr_encoding_size!(usize); // size is platform-dependent, do not use in serializable data
//prim_cdr_encoding_size!(isize);

impl CdrEncodingSize for bool {
  fn cdr_encoding_max_size() -> CdrEncodingMaxSize
  { CdrEncodingMaxSize::Bytes(1) }
}


impl<T: CdrEncodingSize> CdrEncodingSize for Vec<T> {
  fn cdr_encoding_max_size() -> CdrEncodingMaxSize
  { CdrEncodingMaxSize::Unbounded }
}

impl CdrEncodingSize for String {
  fn cdr_encoding_max_size() -> CdrEncodingMaxSize
  { CdrEncodingMaxSize::Unbounded }
}

impl<T: CdrEncodingSize> CdrEncodingSize for Box<T> {
  fn cdr_encoding_max_size() -> CdrEncodingMaxSize
  { T::cdr_encoding_max_size() }
}

impl<T: CdrEncodingSize, const N: usize> CdrEncodingSize for [T; N] {
  fn cdr_encoding_max_size() -> CdrEncodingMaxSize
  { T::cdr_encoding_max_size() * N }
}