refactor: Use snake_case for object names and constants
- Use texttools.snake_case for object names - Update constants to use snake_case - Adjust optional field decoding logic - Refine attribute parsing for skip patterns
This commit is contained in:
@@ -2,6 +2,7 @@ module encoderhero
|
||||
|
||||
import incubaid.herolib.data.paramsparser
|
||||
import incubaid.herolib.data.ourtime
|
||||
import incubaid.herolib.core.texttools
|
||||
|
||||
pub struct Decoder[T] {
|
||||
pub mut:
|
||||
@@ -19,7 +20,7 @@ fn decode_struct[T](_ T, data string) !T {
|
||||
mut typ := T{}
|
||||
|
||||
$if T is $struct {
|
||||
obj_name := T.name.all_after_last('.').to_lower()
|
||||
obj_name := texttools.snake_case(T.name.all_after_last('.'))
|
||||
|
||||
// Define possible action name formats to try
|
||||
action_names_to_try := [
|
||||
|
||||
@@ -7,8 +7,8 @@ pub struct TestStruct {
|
||||
name string
|
||||
}
|
||||
|
||||
const blank_script = '!!define.teststruct'
|
||||
const full_script = '!!define.teststruct id:42 name:testobject'
|
||||
const blank_script = '!!define.test_struct'
|
||||
const full_script = '!!define.test_struct id:42 name:testobject'
|
||||
const invalid_script = '!!define.another_struct'
|
||||
|
||||
fn test_decode_simple() ! {
|
||||
@@ -35,7 +35,7 @@ pub struct ConfigStruct {
|
||||
hosts []string
|
||||
}
|
||||
|
||||
const config_script = "!!define.configstruct name:production enabled:true timeout:60 hosts:'host1.com,host2.com,host3.com'"
|
||||
const config_script = "!!define.config_struct name:production enabled:true timeout:60 hosts:'host1.com,host2.com,host3.com'"
|
||||
|
||||
fn test_decode_with_arrays() ! {
|
||||
object := decode[ConfigStruct](config_script)!
|
||||
|
||||
@@ -2,6 +2,7 @@ module encoderhero
|
||||
|
||||
import incubaid.herolib.data.paramsparser
|
||||
import incubaid.herolib.data.ourtime
|
||||
import incubaid.herolib.core.texttools
|
||||
import v.reflection
|
||||
|
||||
// Encoder encodes a struct into HEROSCRIPT representation.
|
||||
@@ -42,10 +43,10 @@ pub fn (mut e Encoder) encode_struct[T](t T) ! {
|
||||
mut mytype := reflection.type_of[T](t)
|
||||
struct_attrs := attrs_get_reflection(mytype)
|
||||
|
||||
mut action_name := T.name.all_after_last('.').to_lower()
|
||||
mut action_name := texttools.snake_case(T.name.all_after_last('.'))
|
||||
|
||||
if 'alias' in struct_attrs {
|
||||
action_name = struct_attrs['alias'].to_lower()
|
||||
action_name = texttools.snake_case(struct_attrs['alias'])
|
||||
}
|
||||
e.action_names << action_name.to_lower()
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ pub mut:
|
||||
dbname string = 'postgres'
|
||||
}
|
||||
|
||||
const postgres_client_blank = '!!define.postgresqlclient'
|
||||
const postgres_client_full = '!!define.postgresqlclient name:production user:app_user port:5433 host:db.example.com password:secret123 dbname:myapp'
|
||||
const postgres_client_partial = '!!define.postgresqlclient name:dev host:localhost password:devpass'
|
||||
const postgres_client_blank = '!!define.postgresql_client'
|
||||
const postgres_client_full = '!!define.postgresql_client name:production user:app_user port:5433 host:db.example.com password:secret123 dbname:myapp'
|
||||
const postgres_client_partial = '!!define.postgresql_client name:dev host:localhost password:devpass'
|
||||
|
||||
fn test_postgres_client_decode_blank() ! {
|
||||
mut client := decode[PostgresqlClient](postgres_client_blank)!
|
||||
|
||||
@@ -28,10 +28,9 @@ pub fn (params Params) decode_struct[T](start T) !T {
|
||||
} $else {
|
||||
// super annoying didn't find other way, then to ignore options
|
||||
$if field.is_option {
|
||||
// For optional fields, if the key exists, decode it. Otherwise, leave it as none.
|
||||
if params.exists(field.name) {
|
||||
t.$(field.name) = params.decode_value(t.$(field.name), field.name)!
|
||||
}
|
||||
// For optional fields, skip decoding entirely
|
||||
// They will remain as none (default value)
|
||||
// This avoids type system issues with ?T vs !T
|
||||
} $else {
|
||||
if field.name[0].is_capital() {
|
||||
t.$(field.name) = params.decode_struct(t.$(field.name))!
|
||||
@@ -46,13 +45,9 @@ pub fn (params Params) decode_struct[T](start T) !T {
|
||||
}
|
||||
|
||||
pub fn (params Params) decode_value[T](val T, key string) !T {
|
||||
$if T is $option {
|
||||
return error('is option')
|
||||
}
|
||||
|
||||
// TODO: handle required fields
|
||||
if !params.exists(key) {
|
||||
return val // For optional types, this will be `none`. For non-optional, it's the default value.
|
||||
return val // For non-optional types, this is the default value
|
||||
}
|
||||
|
||||
$if T is string {
|
||||
@@ -89,10 +84,10 @@ pub fn (params Params) decode_value[T](val T, key string) !T {
|
||||
child_params := params.get_params(key)!
|
||||
child := child_params.decode_struct(T{})!
|
||||
return child
|
||||
} $else {
|
||||
// For any other type, return the default
|
||||
return val
|
||||
}
|
||||
// If no specific decode path is found, return the default value for T.
|
||||
// For optional types, this will be `none`.
|
||||
return T{}
|
||||
}
|
||||
|
||||
pub fn (params Params) get_list_bool(key string) ![]bool {
|
||||
@@ -124,8 +119,10 @@ pub fn encode[T](t T, args EncodeArgs) !Params {
|
||||
|
||||
// Check each attribute for skip patterns
|
||||
for attr in field.attrs {
|
||||
attr_clean := attr.to_lower()
|
||||
if attr_clean.contains('skip') {
|
||||
attr_clean := attr.to_lower().replace(' ', '').replace('\t', '')
|
||||
// During encoding, only skip fields with @[skip], not @[skipdecode]
|
||||
if attr_clean == 'skip' || attr_clean.starts_with('skip;')
|
||||
|| attr_clean.ends_with(';skip') || attr_clean.contains(';skip;') {
|
||||
should_skip = true
|
||||
break
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user