sqlcx_core/generator/rust_lang/
mod.rs1pub mod common;
2pub mod serde_structs;
3pub mod sqlx_driver;
4pub mod tokio_postgres;
5
6use crate::config::TargetConfig;
7use crate::error::{Result, SqlcxError};
8use crate::generator::{DriverGenerator, GeneratedFile, LanguagePlugin, SchemaGenerator};
9use crate::ir::SqlcxIR;
10
11use self::serde_structs::SerdeStructGenerator;
12use self::sqlx_driver::SqlxGenerator;
13
14pub struct RustPlugin {
15 pub schema_name: String,
16 pub driver_name: String,
17}
18
19impl RustPlugin {
20 pub fn new(schema: &str, driver: &str) -> Result<Self> {
21 resolve_schema(schema)?;
22 resolve_driver(driver)?;
23 Ok(Self {
24 schema_name: schema.to_string(),
25 driver_name: driver.to_string(),
26 })
27 }
28}
29
30fn resolve_schema(name: &str) -> Result<Box<dyn SchemaGenerator>> {
31 match name {
32 "serde" => Ok(Box::new(SerdeStructGenerator)),
33 _ => Err(SqlcxError::UnknownSchema(name.to_string())),
34 }
35}
36
37fn resolve_driver(name: &str) -> Result<Box<dyn DriverGenerator>> {
38 match name {
39 "sqlx" | "sqlx-postgres" => Ok(Box::new(SqlxGenerator::postgres())),
40 "sqlx-mysql" => Ok(Box::new(SqlxGenerator::mysql())),
41 "sqlx-sqlite" => Ok(Box::new(SqlxGenerator::sqlite())),
42 "tokio-postgres" => Ok(Box::new(tokio_postgres::TokioPostgresGenerator)),
43 _ => Err(SqlcxError::UnknownDriver(name.to_string())),
44 }
45}
46
47impl LanguagePlugin for RustPlugin {
48 fn generate(&self, ir: &SqlcxIR, config: &TargetConfig) -> Result<Vec<GeneratedFile>> {
49 let schema_gen = resolve_schema(&self.schema_name)?;
50 let driver_gen = resolve_driver(&self.driver_name)?;
51 let overrides = &config.overrides;
52
53 let mut files = Vec::new();
54
55 files.push(schema_gen.generate(ir, overrides)?);
57
58 files.extend(driver_gen.generate(ir)?);
60
61 Ok(files)
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use crate::config::TargetConfig;
69 use crate::generator::LanguagePlugin;
70 use crate::parser::DatabaseParser;
71 use crate::parser::postgres::PostgresParser;
72 use std::collections::HashMap;
73
74 fn parse_fixture_ir() -> SqlcxIR {
75 let schema_sql = include_str!("../../../../../tests/fixtures/schema.sql");
76 let queries_sql = include_str!("../../../../../tests/fixtures/queries/users.sql");
77 let parser = PostgresParser::new();
78 let (tables, enums) = parser.parse_schema(schema_sql).unwrap();
79 let queries = parser
80 .parse_queries(queries_sql, &tables, &enums, "queries/users.sql")
81 .unwrap();
82 SqlcxIR {
83 tables,
84 queries,
85 enums,
86 }
87 }
88
89 #[test]
90 fn generates_three_files() {
91 let ir = parse_fixture_ir();
92 let plugin = RustPlugin::new("serde", "sqlx").unwrap();
93 let config = TargetConfig {
94 language: "rust".to_string(),
95 out: "./src/db".to_string(),
96 schema: "serde".to_string(),
97 driver: "sqlx".to_string(),
98 overrides: HashMap::new(),
99 };
100 let files = plugin.generate(&ir, &config).unwrap();
101 assert_eq!(files.len(), 3);
102 assert!(files.iter().any(|f| f.path == "models.rs"));
103 assert!(files.iter().any(|f| f.path == "client.rs"));
104 assert!(files.iter().any(|f| f.path == "users_queries.rs"));
105 }
106}