Advertisement
Guest User

Untitled

a guest
Jul 18th, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.17 KB | None | 0 0
  1. #![allow(unused)]
  2.  
  3. use byteorder::ByteOrder;
  4. use std::{error, fmt, str};
  5.  
  6. pub const U32_SIGNATURE: char = 'u';
  7. pub const U32_SIGNATURE_STR: &'static str = "u";
  8. pub const STRING_SIGNATURE: char = 's';
  9. pub const STRING_SIGNATURE_STR: &'static str = "s";
  10.  
  11. #[derive(Debug)]
  12. pub enum VariantError {
  13. IncorrectType,
  14. InvalidUtf8,
  15. InsufficientData,
  16. UnsupportedType,
  17. }
  18.  
  19. impl error::Error for VariantError {
  20. fn source(&self) -> Option<&(dyn error::Error + 'static)> {
  21. None
  22. }
  23. }
  24.  
  25. impl fmt::Display for VariantError {
  26. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  27. match self {
  28. VariantError::IncorrectType => write!(f, "incorrect type"),
  29. VariantError::InvalidUtf8 => write!(f, "invalid UTF-8"),
  30. VariantError::InsufficientData => write!(f, "insufficient data"),
  31. VariantError::UnsupportedType => write!(f, "unsupported type"),
  32. }
  33. }
  34. }
  35.  
  36. pub trait VariantType<'a>: Sized {
  37. fn signature() -> char;
  38. fn signature_str() -> &'static str;
  39. fn encode(&'a self) -> &'a [u8];
  40. fn extract_slice(data: &'a [u8]) -> Result<&'a [u8], VariantError>;
  41.  
  42. fn extract(bytes: &'a [u8]) -> Result<Self, VariantError>
  43. where
  44. Self: 'a;
  45. }
  46.  
  47. impl<'a> VariantType<'a> for u32 {
  48. fn signature() -> char {
  49. 'u'
  50. }
  51.  
  52. fn signature_str() -> &'static str {
  53. "u"
  54. }
  55.  
  56. fn encode(&'a self) -> &'a [u8] {
  57. &self.to_ne_bytes()
  58. }
  59.  
  60. fn extract_slice(bytes: &'a [u8]) -> Result<&'a [u8], VariantError> {
  61. if bytes.len() < 4 {
  62. return Err(VariantError::InsufficientData);
  63. }
  64.  
  65. Ok(&bytes[0..4])
  66. }
  67.  
  68. fn extract(bytes: &'a [u8]) -> Result<Self, VariantError>
  69. where
  70. Self: 'a,
  71. {
  72. if bytes.len() < 4 {
  73. return Err(VariantError::InsufficientData);
  74. }
  75.  
  76. Ok(byteorder::NativeEndian::read_u32(bytes))
  77. }
  78. }
  79.  
  80. impl<'a> VariantType<'a> for &'a str {
  81. fn signature() -> char {
  82. 's'
  83. }
  84.  
  85. fn signature_str() -> &'static str {
  86. "s"
  87. }
  88.  
  89. fn encode(&'a self) -> &'a [u8] {
  90. let len = self.len();
  91. let mut bytes = Vec::with_capacity(5 + len);
  92.  
  93. bytes.extend(&(len as u32).to_ne_bytes());
  94. bytes.extend(self.as_bytes());
  95. bytes.push(b'\0');
  96.  
  97. &bytes
  98. }
  99.  
  100. fn extract_slice(bytes: &'a [u8]) -> Result<&'a [u8], VariantError> {
  101. if bytes.len() < 4 {
  102. return Err(VariantError::InsufficientData);
  103. }
  104.  
  105. let last_index = byteorder::NativeEndian::read_u32(bytes) as usize + 5;
  106. if bytes.len() < last_index {
  107. return Err(VariantError::InsufficientData);
  108. }
  109.  
  110. Ok(&bytes[0..last_index])
  111. }
  112.  
  113. fn extract(bytes: &'a [u8]) -> Result<Self, VariantError>
  114. where
  115. Self: 'a,
  116. {
  117. if bytes.len() < 4 {
  118. return Err(VariantError::InsufficientData);
  119. }
  120.  
  121. str::from_utf8(&bytes[4..]).map_err(|_| VariantError::InvalidUtf8)
  122. }
  123. }
  124. pub struct Variant<'a> {
  125. // FIXME: This should be an `&str`
  126. signature: String,
  127. value: &'a [u8],
  128. }
  129.  
  130. impl<'a> Variant<'a> {
  131. pub fn from_data(data: &'a [u8], signature: &str) -> Result<Self, VariantError>
  132. where
  133. Self: 'a,
  134. {
  135. let value = match signature {
  136. // FIXME: There has to be a shorter way to do this
  137. U32_SIGNATURE_STR => u32::extract_slice(data)?,
  138. STRING_SIGNATURE_STR => <(&str)>::extract_slice(data)?,
  139. _ => return Err(VariantError::UnsupportedType),
  140. };
  141.  
  142. Ok(Self {
  143. value,
  144. signature: String::from(signature),
  145. })
  146. }
  147.  
  148. pub fn from<T: 'a + VariantType>(value: T) -> Self
  149. where
  150. Self: 'a,
  151. {
  152. Self {
  153. value: value.encode(),
  154. signature: String::from(T::signature_str()),
  155. }
  156. }
  157.  
  158. pub fn get_signature(&self) -> &str {
  159. &self.signature
  160. }
  161.  
  162. pub fn get<T: 'a + VariantType>(&'a self) -> Result<T, VariantError> {
  163. VariantType::extract(self.value)
  164. }
  165.  
  166. // FIXME: Return a slice
  167. pub fn get_bytes(&self) -> &[u8] {
  168. self.value
  169. }
  170.  
  171. pub fn len(&self) -> usize {
  172. self.value.len()
  173. }
  174. }
  175.  
  176. fn main() {
  177. println!("{}", <(&str)>::extract());
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement