forge_core/schema/
field.rs1use serde::{Deserialize, Serialize};
2
3use super::types::{RustType, SqlType};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct FieldDef {
8 pub name: String,
10
11 pub column_name: String,
13
14 pub rust_type: RustType,
16
17 pub sql_type: SqlType,
19
20 pub nullable: bool,
22
23 pub doc: Option<String>,
25}
26
27impl FieldDef {
28 pub fn new(name: &str, rust_type: RustType) -> Self {
30 let sql_type = rust_type.to_sql_type();
31 let nullable = rust_type.is_nullable();
32 let column_name = to_snake_case(name);
33
34 Self {
35 name: name.to_string(),
36 column_name,
37 rust_type,
38 sql_type,
39 nullable,
40 doc: None,
41 }
42 }
43
44 pub fn to_typescript(&self) -> String {
46 let ts_type = self.rust_type.to_typescript();
47 let optional = if self.nullable { "?" } else { "" };
48 format!(" {}{}: {};", to_camel_case(&self.name), optional, ts_type)
49 }
50}
51
52fn to_snake_case(s: &str) -> String {
54 let mut result = String::new();
55 for (i, c) in s.chars().enumerate() {
56 if c.is_uppercase() {
57 if i > 0 {
58 result.push('_');
59 }
60 result.push(c.to_lowercase().next().unwrap());
61 } else {
62 result.push(c);
63 }
64 }
65 result
66}
67
68fn to_camel_case(s: &str) -> String {
70 let mut result = String::new();
71 let mut capitalize_next = false;
72 for c in s.chars() {
73 if c == '_' {
74 capitalize_next = true;
75 } else if capitalize_next {
76 result.push(c.to_uppercase().next().unwrap());
77 capitalize_next = false;
78 } else {
79 result.push(c);
80 }
81 }
82 result
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn test_field_def_basic() {
91 let field = FieldDef::new("email", RustType::String);
92 assert_eq!(field.name, "email");
93 assert_eq!(field.column_name, "email");
94 assert!(!field.nullable);
95 }
96
97 #[test]
98 fn test_field_def_nullable() {
99 let field = FieldDef::new("avatar_url", RustType::Option(Box::new(RustType::String)));
100 assert!(field.nullable);
101 }
102
103 #[test]
104 fn test_to_snake_case() {
105 assert_eq!(to_snake_case("createdAt"), "created_at");
106 assert_eq!(to_snake_case("userId"), "user_id");
107 assert_eq!(to_snake_case("HTTPServer"), "h_t_t_p_server");
108 }
109
110 #[test]
111 fn test_to_camel_case() {
112 assert_eq!(to_camel_case("created_at"), "createdAt");
113 assert_eq!(to_camel_case("user_id"), "userId");
114 }
115}