macros.rs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. //! Collection of macros to generate code to digest data from SQLite
  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. return Err(Error::MissingColumn(required, vec.len()));
  13. }
  14. Ok::<_, Error>((
  15. $(
  16. vec.pop().expect(&format!("Checked length already for {}", stringify!($var)))
  17. ),+
  18. ))?
  19. };
  20. };
  21. }
  22. /// Parses a SQLite 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. other => Err(Error::InvalidType(
  31. "String".to_owned(),
  32. other.data_type().to_string(),
  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. other => Err(Error::InvalidType(
  44. "String".to_owned(),
  45. other.data_type().to_string(),
  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. other => Err(Error::InvalidType(
  57. "String".to_owned(),
  58. other.data_type().to_string(),
  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. Error::InvalidConversion(stringify!($col).to_owned(), "Number".to_owned())
  70. })?)),
  71. $crate::stmt::Column::Integer(n) => Ok(Some(n.try_into().map_err(|_| {
  72. Error::InvalidConversion(stringify!($col).to_owned(), "Number".to_owned())
  73. })?)),
  74. $crate::stmt::Column::Null => Ok(None),
  75. other => Err(Error::InvalidType(
  76. "Number".to_owned(),
  77. other.data_type().to_string(),
  78. )),
  79. })?
  80. };
  81. }
  82. /// Parses a column as a number
  83. #[macro_export]
  84. macro_rules! column_as_number {
  85. ($col:expr) => {
  86. (match $col {
  87. $crate::stmt::Column::Text(text) => text.parse().map_err(|_| {
  88. Error::InvalidConversion(stringify!($col).to_owned(), "Number".to_owned())
  89. }),
  90. $crate::stmt::Column::Integer(n) => n.try_into().map_err(|_| {
  91. Error::InvalidConversion(stringify!($col).to_owned(), "Number".to_owned())
  92. }),
  93. other => Err(Error::InvalidType(
  94. "Number".to_owned(),
  95. other.data_type().to_string(),
  96. )),
  97. })?
  98. };
  99. }
  100. /// Parses a column as a NULL or Binary
  101. #[macro_export]
  102. macro_rules! column_as_nullable_binary {
  103. ($col:expr) => {
  104. (match $col {
  105. $crate::stmt::Column::Text(text) => Ok(Some(text.as_bytes().to_vec())),
  106. $crate::stmt::Column::Blob(bytes) => Ok(Some(bytes.to_owned())),
  107. $crate::stmt::Column::Null => Ok(None),
  108. other => Err(Error::InvalidType(
  109. "String".to_owned(),
  110. other.data_type().to_string(),
  111. )),
  112. })?
  113. };
  114. }
  115. /// Parses a SQLite column as a binary
  116. #[macro_export]
  117. macro_rules! column_as_binary {
  118. ($col:expr) => {
  119. (match $col {
  120. $crate::stmt::Column::Text(text) => Ok(text.as_bytes().to_vec()),
  121. $crate::stmt::Column::Blob(bytes) => Ok(bytes.to_owned()),
  122. other => Err(Error::InvalidType(
  123. "String".to_owned(),
  124. other.data_type().to_string(),
  125. )),
  126. })?
  127. };
  128. }
  129. /// Parses a SQLite column as a string
  130. #[macro_export]
  131. macro_rules! column_as_string {
  132. ($col:expr, $callback_str:expr, $callback_bytes:expr) => {
  133. (match $col {
  134. $crate::stmt::Column::Text(text) => $callback_str(&text).map_err(Error::from),
  135. $crate::stmt::Column::Blob(bytes) => $callback_bytes(&bytes).map_err(Error::from),
  136. other => Err(Error::InvalidType(
  137. "String".to_owned(),
  138. other.data_type().to_string(),
  139. )),
  140. })?
  141. };
  142. ($col:expr, $callback:expr) => {
  143. (match $col {
  144. $crate::stmt::Column::Text(text) => $callback(&text).map_err(Error::from),
  145. $crate::stmt::Column::Blob(bytes) => {
  146. $callback(&String::from_utf8_lossy(&bytes)).map_err(Error::from)
  147. }
  148. other => Err(Error::InvalidType(
  149. "String".to_owned(),
  150. other.data_type().to_string(),
  151. )),
  152. })?
  153. };
  154. ($col:expr) => {
  155. (match $col {
  156. $crate::stmt::Column::Text(text) => Ok(text.to_owned()),
  157. $crate::stmt::Column::Blob(bytes) => Ok(String::from_utf8_lossy(&bytes).to_string()),
  158. other => Err(Error::InvalidType(
  159. "String".to_owned(),
  160. other.data_type().to_string(),
  161. )),
  162. })?
  163. };
  164. }