|
@@ -2,9 +2,9 @@ use serde::de::Visitor;
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
pub struct CreateDeserializer<'de> {
|
|
|
- table_name: Option<&'static str>,
|
|
|
- column_names: Option<&'static [&'static str]>,
|
|
|
+ column_names: Vec<String>,
|
|
|
column_types: Vec<String>,
|
|
|
+ column_name_stack: Vec<String>,
|
|
|
_de: std::marker::PhantomData<&'de u8>,
|
|
|
}
|
|
|
|
|
@@ -14,7 +14,7 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut CreateDeserializer<'de> {
|
|
|
// we (ab)use the forward_to_deserialize_any! macro to stub out the types we don't care about
|
|
|
serde::forward_to_deserialize_any! {
|
|
|
bool i8 i16 i128 u8 u16 u32 u64 u128 f32 f64 char str
|
|
|
- bytes byte_buf option unit unit_struct newtype_struct seq tuple
|
|
|
+ option unit unit_struct tuple
|
|
|
tuple_struct map enum identifier ignored_any
|
|
|
}
|
|
|
|
|
@@ -24,29 +24,57 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut CreateDeserializer<'de> {
|
|
|
|
|
|
fn deserialize_i32<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
|
|
|
self.column_types.push("integer".to_owned());
|
|
|
+ self.column_names.push(self.column_name_stack.pop().unwrap());
|
|
|
v.visit_i32(0)
|
|
|
}
|
|
|
|
|
|
fn deserialize_i64<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
|
|
|
self.column_types.push("integer".to_owned());
|
|
|
+ self.column_names.push(self.column_name_stack.pop().unwrap());
|
|
|
v.visit_i64(0)
|
|
|
}
|
|
|
|
|
|
fn deserialize_string<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
|
|
|
self.column_types.push("varchar".to_owned());
|
|
|
+ self.column_names.push(self.column_name_stack.pop().unwrap());
|
|
|
v.visit_string("".to_owned())
|
|
|
}
|
|
|
|
|
|
+ fn deserialize_bytes<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
|
|
|
+ self.column_types.push("blob".to_owned());
|
|
|
+ self.column_names.push(self.column_name_stack.pop().unwrap());
|
|
|
+ v.visit_bytes(&[])
|
|
|
+ }
|
|
|
+
|
|
|
+ fn deserialize_byte_buf<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
|
|
|
+ self.column_types.push("blob".to_owned());
|
|
|
+ self.column_names.push(self.column_name_stack.pop().unwrap());
|
|
|
+ v.visit_bytes(&[])
|
|
|
+ }
|
|
|
+
|
|
|
+ fn deserialize_seq<V: Visitor<'de>>(
|
|
|
+ self, v: V) -> Result<V::Value, Self::Error> {
|
|
|
+
|
|
|
+ v.visit_seq(self)
|
|
|
+ }
|
|
|
+
|
|
|
fn deserialize_struct<V: Visitor<'de>>(
|
|
|
self,
|
|
|
name: &'static str,
|
|
|
fields: &'static [&'static str],
|
|
|
v: V,
|
|
|
) -> Result<V::Value, Self::Error> {
|
|
|
- self.table_name = Some(name);
|
|
|
- self.column_names = Some(fields);
|
|
|
+ self.column_name_stack.extend(fields.iter().map(|x| x.to_string()));
|
|
|
v.visit_seq(self)
|
|
|
}
|
|
|
+
|
|
|
+ fn deserialize_newtype_struct<V: Visitor<'de>>(
|
|
|
+ self,
|
|
|
+ name: &'static str,
|
|
|
+ v: V
|
|
|
+ ) -> Result<V::Value, Self::Error> {
|
|
|
+ unreachable!("microrm cannot store newtype structs")
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl<'de> serde::de::SeqAccess<'de> for CreateDeserializer<'de> {
|
|
@@ -62,9 +90,9 @@ impl<'de> serde::de::SeqAccess<'de> for CreateDeserializer<'de> {
|
|
|
|
|
|
pub fn sql_for<T: crate::model::Entity>() -> (String, String) {
|
|
|
let mut cd = CreateDeserializer {
|
|
|
- table_name: None,
|
|
|
- column_names: None,
|
|
|
+ column_names: Vec::new(),
|
|
|
column_types: Vec::new(),
|
|
|
+ column_name_stack: Vec::new(),
|
|
|
_de: std::marker::PhantomData {},
|
|
|
};
|
|
|
|
|
@@ -79,7 +107,6 @@ pub fn sql_for<T: crate::model::Entity>() -> (String, String) {
|
|
|
"CREATE TABLE {} ({})",
|
|
|
<T as crate::model::Entity>::table_name(),
|
|
|
cd.column_names
|
|
|
- .unwrap()
|
|
|
.iter()
|
|
|
.zip(cd.column_types.iter())
|
|
|
.map(|(n, t)| n.to_string() + " " + t)
|