create.rs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. use serde::de::Visitor;
  2. #[derive(Debug)]
  3. pub struct CreateDeserializer<'de> {
  4. column_names: Vec<String>,
  5. column_types: Vec<String>,
  6. column_name_stack: Vec<String>,
  7. _de: std::marker::PhantomData<&'de u8>,
  8. }
  9. impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut CreateDeserializer<'de> {
  10. type Error = super::ModelError;
  11. // we (ab)use the forward_to_deserialize_any! macro to stub out the types we don't care about
  12. serde::forward_to_deserialize_any! {
  13. bool i8 i16 i128 u8 u16 u32 u64 u128 f32 f64 char str
  14. option unit unit_struct tuple
  15. tuple_struct map enum identifier ignored_any
  16. }
  17. fn deserialize_any<V: Visitor<'de>>(self, _v: V) -> Result<V::Value, Self::Error> {
  18. todo!()
  19. }
  20. fn deserialize_i32<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
  21. self.column_types.push("integer".to_owned());
  22. self.column_names.push(self.column_name_stack.pop().unwrap());
  23. v.visit_i32(0)
  24. }
  25. fn deserialize_i64<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
  26. self.column_types.push("integer".to_owned());
  27. self.column_names.push(self.column_name_stack.pop().unwrap());
  28. v.visit_i64(0)
  29. }
  30. fn deserialize_string<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
  31. self.column_types.push("varchar".to_owned());
  32. self.column_names.push(self.column_name_stack.pop().unwrap());
  33. v.visit_string("".to_owned())
  34. }
  35. fn deserialize_bytes<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
  36. self.column_types.push("blob".to_owned());
  37. self.column_names.push(self.column_name_stack.pop().unwrap());
  38. v.visit_bytes(&[])
  39. }
  40. fn deserialize_byte_buf<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
  41. self.column_types.push("blob".to_owned());
  42. self.column_names.push(self.column_name_stack.pop().unwrap());
  43. v.visit_bytes(&[])
  44. }
  45. fn deserialize_seq<V: Visitor<'de>>(
  46. self, v: V) -> Result<V::Value, Self::Error> {
  47. v.visit_seq(self)
  48. }
  49. fn deserialize_struct<V: Visitor<'de>>(
  50. self,
  51. name: &'static str,
  52. fields: &'static [&'static str],
  53. v: V,
  54. ) -> Result<V::Value, Self::Error> {
  55. self.column_name_stack.extend(fields.iter().map(|x| x.to_string()));
  56. v.visit_seq(self)
  57. }
  58. fn deserialize_newtype_struct<V: Visitor<'de>>(
  59. self,
  60. name: &'static str,
  61. v: V
  62. ) -> Result<V::Value, Self::Error> {
  63. unreachable!("microrm cannot store newtype structs")
  64. }
  65. }
  66. impl<'de> serde::de::SeqAccess<'de> for CreateDeserializer<'de> {
  67. type Error = super::ModelError;
  68. fn next_element_seed<T: serde::de::DeserializeSeed<'de>>(
  69. &mut self,
  70. seed: T,
  71. ) -> Result<Option<T::Value>, Self::Error> {
  72. seed.deserialize(self).map(Some)
  73. }
  74. }
  75. pub fn sql_for<T: crate::model::Entity>() -> (String, String) {
  76. let mut cd = CreateDeserializer {
  77. column_names: Vec::new(),
  78. column_types: Vec::new(),
  79. column_name_stack: Vec::new(),
  80. _de: std::marker::PhantomData {},
  81. };
  82. T::deserialize(&mut cd).expect("SQL creation failed!");
  83. (
  84. format!(
  85. "DROP TABLE IF EXISTS {}",
  86. <T as crate::model::Entity>::table_name()
  87. ),
  88. format!(
  89. "CREATE TABLE {} ({})",
  90. <T as crate::model::Entity>::table_name(),
  91. cd.column_names
  92. .iter()
  93. .zip(cd.column_types.iter())
  94. .map(|(n, t)| n.to_string() + " " + t)
  95. .collect::<Vec<_>>()
  96. .join(",")
  97. ),
  98. )
  99. }
  100. #[cfg(test)]
  101. mod test {
  102. #[derive(serde::Serialize, serde::Deserialize, crate::Entity)]
  103. struct Empty {}
  104. #[derive(serde::Serialize, serde::Deserialize, crate::Entity)]
  105. struct Single {
  106. e: i32,
  107. }
  108. #[test]
  109. fn example_sql_for() {
  110. assert_eq!(
  111. super::sql_for::<Empty>(),
  112. (
  113. "DROP TABLE IF EXISTS empty".to_owned(),
  114. "CREATE TABLE empty ()".to_owned()
  115. )
  116. );
  117. assert_eq!(
  118. super::sql_for::<Single>(),
  119. (
  120. "DROP TABLE IF EXISTS single".to_owned(),
  121. "CREATE TABLE single (e integer)".to_owned()
  122. )
  123. );
  124. }
  125. }