macros.rs 6.5 KB

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