macros.rs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. //! Collection of macros to generate code to digest data from a generic SQL databasex
  2. /// Unpacks a vector of Column, and consumes it, parsing into individual variables, checking the
  3. /// vector is big enough.
  4. #[macro_export]
  5. macro_rules! unpack_into {
  6. (let ($($var:ident),+) = $array:expr) => {
  7. #[allow(unused_parens)]
  8. let ($($var),+) = {
  9. let mut vec = $array.to_vec();
  10. vec.reverse();
  11. let required = 0 $(+ {let _ = stringify!($var); 1})+;
  12. if vec.len() < required {
  13. Err($crate::ConversionError::MissingColumn(required, vec.len()))?;
  14. }
  15. (
  16. $(
  17. vec.pop().expect(&format!("Checked length already for {}", stringify!($var)))
  18. ),+
  19. )
  20. };
  21. };
  22. }
  23. /// Parses a SQL column as a string or NULL
  24. #[macro_export]
  25. macro_rules! column_as_nullable_string {
  26. ($col:expr, $callback_str:expr, $callback_bytes:expr) => {
  27. (match $col {
  28. $crate::stmt::Column::Text(text) => Ok(Some(text).and_then($callback_str)),
  29. $crate::stmt::Column::Blob(bytes) => Ok(Some(bytes).and_then($callback_bytes)),
  30. $crate::stmt::Column::Null => Ok(None),
  31. _ => Err($crate::ConversionError::InvalidType(
  32. "String".to_owned(),
  33. stringify!($col).to_owned(),
  34. )),
  35. })?
  36. };
  37. ($col:expr, $callback_str:expr) => {
  38. (match $col {
  39. $crate::stmt::Column::Text(text) => Ok(Some(text).and_then($callback_str)),
  40. $crate::stmt::Column::Blob(bytes) => {
  41. Ok(Some(String::from_utf8_lossy(&bytes)).and_then($callback_str))
  42. }
  43. $crate::stmt::Column::Null => Ok(None),
  44. _ => Err($crate::ConversionError::InvalidType(
  45. "String".to_owned(),
  46. stringify!($col).to_owned(),
  47. )),
  48. })?
  49. };
  50. ($col:expr) => {
  51. (match $col {
  52. $crate::stmt::Column::Text(text) => Ok(Some(text.to_owned())),
  53. $crate::stmt::Column::Blob(bytes) => {
  54. Ok(Some(String::from_utf8_lossy(&bytes).to_string()))
  55. }
  56. $crate::stmt::Column::Null => Ok(None),
  57. _ => Err($crate::ConversionError::InvalidType(
  58. "String".to_owned(),
  59. stringify!($col).to_owned(),
  60. )),
  61. })?
  62. };
  63. }
  64. /// Parses a column as a number or NULL
  65. #[macro_export]
  66. macro_rules! column_as_nullable_number {
  67. ($col:expr) => {
  68. (match $col {
  69. $crate::stmt::Column::Text(text) => Ok(Some(text.parse().map_err(|_| {
  70. $crate::ConversionError::InvalidConversion(
  71. stringify!($col).to_owned(),
  72. "Number".to_owned(),
  73. )
  74. })?)),
  75. $crate::stmt::Column::Integer(n) => Ok(Some(n.try_into().map_err(|_| {
  76. $crate::ConversionError::InvalidConversion(
  77. stringify!($col).to_owned(),
  78. "Number".to_owned(),
  79. )
  80. })?)),
  81. $crate::stmt::Column::Null => Ok(None),
  82. _ => Err($crate::ConversionError::InvalidType(
  83. "Number".to_owned(),
  84. stringify!($col).to_owned(),
  85. )),
  86. })?
  87. };
  88. }
  89. /// Parses a column as a number
  90. #[macro_export]
  91. macro_rules! column_as_number {
  92. ($col:expr) => {
  93. (match $col {
  94. $crate::stmt::Column::Text(text) => text.parse().map_err(|_| {
  95. $crate::ConversionError::InvalidConversion(
  96. stringify!($col).to_owned(),
  97. "Number".to_owned(),
  98. )
  99. }),
  100. $crate::stmt::Column::Integer(n) => n.try_into().map_err(|_| {
  101. $crate::ConversionError::InvalidConversion(
  102. stringify!($col).to_owned(),
  103. "Number".to_owned(),
  104. )
  105. }),
  106. _ => Err($crate::ConversionError::InvalidType(
  107. "Number".to_owned(),
  108. stringify!($col).to_owned(),
  109. )),
  110. })?
  111. };
  112. }
  113. /// Parses a column as a NULL or Binary
  114. #[macro_export]
  115. macro_rules! column_as_nullable_binary {
  116. ($col:expr) => {
  117. (match $col {
  118. $crate::stmt::Column::Text(text) => Ok(Some(text.as_bytes().to_vec())),
  119. $crate::stmt::Column::Blob(bytes) => Ok(Some(bytes.to_owned())),
  120. $crate::stmt::Column::Null => Ok(None),
  121. _ => Err($crate::ConversionError::InvalidType(
  122. "String".to_owned(),
  123. stringify!($col).to_owned(),
  124. )),
  125. })?
  126. };
  127. }
  128. /// Parses a SQL column as a binary
  129. #[macro_export]
  130. macro_rules! column_as_binary {
  131. ($col:expr) => {
  132. (match $col {
  133. $crate::stmt::Column::Text(text) => Ok(text.as_bytes().to_vec()),
  134. $crate::stmt::Column::Blob(bytes) => Ok(bytes.to_owned()),
  135. _ => Err($crate::ConversionError::InvalidType(
  136. "String".to_owned(),
  137. stringify!($col).to_owned(),
  138. )),
  139. })?
  140. };
  141. }
  142. /// Parses a SQL column as a string
  143. #[macro_export]
  144. macro_rules! column_as_string {
  145. ($col:expr, $callback_str:expr, $callback_bytes:expr) => {
  146. (match $col {
  147. $crate::stmt::Column::Text(text) => {
  148. $callback_str(&text).map_err($crate::ConversionError::from)
  149. }
  150. $crate::stmt::Column::Blob(bytes) => {
  151. $callback_bytes(&bytes).map_err($crate::ConversionError::from)
  152. }
  153. _ => Err($crate::ConversionError::InvalidType(
  154. "String".to_owned(),
  155. stringify!($col).to_owned(),
  156. )),
  157. })?
  158. };
  159. ($col:expr, $callback:expr) => {
  160. (match $col {
  161. $crate::stmt::Column::Text(text) => {
  162. $callback(&text).map_err($crate::ConversionError::from)
  163. }
  164. $crate::stmt::Column::Blob(bytes) => {
  165. $callback(&String::from_utf8_lossy(&bytes)).map_err($crate::ConversionError::from)
  166. }
  167. _ => Err($crate::ConversionError::InvalidType(
  168. "String".to_owned(),
  169. stringify!($col).to_owned(),
  170. )),
  171. })?
  172. };
  173. ($col:expr) => {
  174. (match $col {
  175. $crate::stmt::Column::Text(text) => Ok(text.to_owned()),
  176. $crate::stmt::Column::Blob(bytes) => Ok(String::from_utf8_lossy(&bytes).to_string()),
  177. _ => Err($crate::ConversionError::InvalidType(
  178. "String".to_owned(),
  179. stringify!($col).to_owned(),
  180. )),
  181. })?
  182. };
  183. }