Files
sea-orm-generator/src/generator/modules/annotate/comment.rs
2025-04-17 22:05:58 +04:00

122 lines
4.0 KiB
Rust

use color_eyre::Result;
use minijinja::Environment;
use serde::Serialize;
use crate::generator::modules::{
discovery::{db::DbType, table::Table},
sea_orm::config::DateTimeCrate,
};
use comfy_table::{Cell, ContentArrangement, Table as CTable};
use super::{
AnnotateCommentConfig, COMMENTBODY, COMMENTHEAD, COMMENTTAIL, HEADER, SETTINGSDELIMITER,
};
#[derive(Debug, Serialize)]
struct CommentContext<'a> {
pub table_name: &'a str,
pub config: &'a AnnotateCommentConfig,
pub column_info_table: String,
pub comment_config: Option<String>,
pub config_delimiter: &'a str,
}
pub fn generate_comment(
table: &Table,
config: &AnnotateCommentConfig,
environment: &Environment<'static>,
db_type: &DbType,
date_time_crate: &DateTimeCrate,
comment_config: Option<AnnotateCommentConfig>,
) -> Result<String> {
let mut column_info_table = CTable::new();
let mut header = Vec::new();
if config.column_name.unwrap() {
header.push("Name");
}
if config.column_db_type.unwrap() {
header.push("DbType");
}
if config.column_rust_type.unwrap() {
header.push("RsType");
}
if config.column_attributes.unwrap() {
header.push("Attrs");
}
column_info_table
.load_preset("|| -+=++ + ++")
.set_content_arrangement(ContentArrangement::Dynamic)
.set_header(header);
if let Some(width) = config.max_wdith {
column_info_table.set_width(width);
}
for column in &table.columns {
let mut row = Vec::new();
if config.column_name.unwrap() {
row.push(Cell::new(column.name.clone()))
}
if config.column_db_type.unwrap() {
let column_type = column.get_db_type(db_type);
row.push(Cell::new(column_type));
}
if config.column_rust_type.unwrap() {
let column_type = column.get_rust_type(date_time_crate);
row.push(Cell::new(column_type));
}
if config.column_attributes.unwrap() {
let exclude = config.column_exclude_attributes.clone().unwrap();
let filter: Box<dyn Fn(&String) -> bool> = Box::new(move |f| {
let exclude = exclude.clone();
!exclude.contains(f)
});
let attrs_string = column.attrs_to_string(Some(filter));
row.push(Cell::new(attrs_string));
}
column_info_table.add_row(row);
}
let context = CommentContext {
table_name: &table.name,
config,
column_info_table: column_info_table.to_string(),
comment_config: comment_config
.and_then(|f| toml::to_string_pretty(&f).ok())
.map(|s| {
s.lines()
.map(|line| format!(" {}", line))
.collect::<Vec<_>>()
.join("\n")
}),
config_delimiter: SETTINGSDELIMITER,
};
let template = environment.get_template("annotate.comment")?;
let rendered_data = template.render(&context)?;
Ok(pad_comment(&rendered_data))
}
pub fn pad_comment(s: &str) -> String {
let parts = s.split('\n').collect::<Vec<_>>();
let mut padded = String::new();
for (index, part) in parts.iter().enumerate() {
let first = index == 0;
let comment = match first {
true => format!("{} {}\n{}", COMMENTHEAD, HEADER, COMMENTBODY),
false => COMMENTBODY.to_string(),
};
let padded_part = format!("{} {}\n", comment, part);
padded.push_str(&padded_part);
}
padded.push_str(COMMENTTAIL);
padded
}
pub fn find_settings_block(file_content: &str) -> Option<String> {
let delimiter_length = SETTINGSDELIMITER.len();
let start_pos = file_content.find(SETTINGSDELIMITER)?;
let end_pos = file_content[start_pos + delimiter_length..].find(SETTINGSDELIMITER)?;
let content = &file_content[start_pos + delimiter_length..start_pos + end_pos];
let content = content.replace(&format!("\n{COMMENTBODY}"), "\n");
Some(content)
}