Skip to main content

scythe_codegen/
backend_trait.rs

1use scythe_core::analyzer::{AnalyzedQuery, CompositeInfo, EnumInfo};
2use scythe_core::errors::ScytheError;
3
4/// A column with its type resolved to the target language.
5#[derive(Debug, Clone)]
6pub struct ResolvedColumn {
7    pub name: String,
8    pub field_name: String,
9    pub lang_type: String,
10    pub full_type: String,
11    pub neutral_type: String,
12    pub nullable: bool,
13}
14
15/// A parameter with its type resolved to the target language.
16#[derive(Debug, Clone)]
17pub struct ResolvedParam {
18    pub name: String,
19    pub field_name: String,
20    pub lang_type: String,
21    pub full_type: String,
22    pub borrowed_type: String,
23    pub neutral_type: String,
24    pub nullable: bool,
25}
26
27/// Trait that all codegen backends must implement.
28pub trait CodegenBackend: Send + Sync {
29    /// The backend's name (e.g. "rust-sqlx", "rust-tokio-postgres").
30    fn name(&self) -> &str;
31
32    /// The backend's manifest (type mappings, naming conventions, etc).
33    fn manifest(&self) -> &scythe_backend::manifest::BackendManifest;
34
35    /// Generate a row struct for a query result.
36    fn generate_row_struct(
37        &self,
38        query_name: &str,
39        columns: &[ResolvedColumn],
40    ) -> Result<String, ScytheError>;
41
42    /// Generate a model struct for a table.
43    fn generate_model_struct(
44        &self,
45        table_name: &str,
46        columns: &[ResolvedColumn],
47    ) -> Result<String, ScytheError>;
48
49    /// Generate a query function.
50    fn generate_query_fn(
51        &self,
52        analyzed: &AnalyzedQuery,
53        struct_name: &str,
54        columns: &[ResolvedColumn],
55        params: &[ResolvedParam],
56    ) -> Result<String, ScytheError>;
57
58    /// Generate an enum definition.
59    fn generate_enum_def(&self, enum_info: &EnumInfo) -> Result<String, ScytheError>;
60
61    /// Generate a composite type definition.
62    fn generate_composite_def(&self, composite: &CompositeInfo) -> Result<String, ScytheError>;
63
64    /// Generate a file-level header (imports, docstring, etc).
65    /// Returns an empty string by default; backends may override.
66    fn file_header(&self) -> String {
67        String::new()
68    }
69
70    /// Generate a file-level footer (closing braces, etc).
71    /// Returns an empty string by default; backends may override.
72    fn file_footer(&self) -> String {
73        String::new()
74    }
75
76    /// Generate a class header that wraps query functions only.
77    /// When non-empty, the assembly will emit all type definitions (enums,
78    /// row structs, model structs) first, then this class header, then all
79    /// query functions, then the file footer.
80    /// Returns an empty string by default (no class wrapper).
81    fn query_class_header(&self) -> String {
82        String::new()
83    }
84
85    /// Apply per-backend configuration options from [[sql.gen]].
86    /// Backends override this to handle options like `row_type = "pydantic"`.
87    fn apply_options(
88        &mut self,
89        _options: &std::collections::HashMap<String, String>,
90    ) -> Result<(), ScytheError> {
91        Ok(())
92    }
93
94    /// Database engines this backend supports.
95    /// Defaults to PostgreSQL only. Multi-DB backends override this.
96    fn supported_engines(&self) -> &[&str] {
97        &["postgresql"]
98    }
99}