refactor: Improve struct decoding and skip logic
- Refine `decode_struct` to handle data parsing and error messages - Enhance `should_skip_field_decode` to cover more skip attribute variations - Update constants and tests related to struct names - Adjust `decode_value` to better handle optional types and existing keys - Modify `decode_struct` to skip optional fields during decoding
This commit is contained in:
@@ -13,25 +13,31 @@ pub fn (params Params) decode[T](args T) !T {
|
||||
pub fn (params Params) decode_struct[T](start T) !T {
|
||||
mut t := T{}
|
||||
$for field in T.fields {
|
||||
// Check if field has skip attribute
|
||||
mut should_skip := false
|
||||
for attr in field.attrs {
|
||||
attr_clean := attr.to_lower()
|
||||
if attr_clean.contains('skip') {
|
||||
attr_clean := attr.to_lower().replace(' ', '').replace('\t', '')
|
||||
if attr_clean == 'skip' || attr_clean.starts_with('skip;')
|
||||
|| attr_clean.ends_with(';skip') || attr_clean.contains(';skip;') {
|
||||
should_skip = true
|
||||
break
|
||||
}
|
||||
// Also check for skipdecode
|
||||
if attr_clean == 'skipdecode' || attr_clean.contains('skipdecode') {
|
||||
should_skip = true
|
||||
break
|
||||
}
|
||||
}
|
||||
// println('Field: ${field.name}, should_skip: ${should_skip}, attrs: ${field.attrs}')
|
||||
if ! should_skip {
|
||||
|
||||
if !should_skip {
|
||||
$if field.is_enum {
|
||||
t.$(field.name) = params.get_int(field.name) or { int(t.$(field.name)) }
|
||||
} $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 +52,16 @@ 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.
|
||||
$if T is $option {
|
||||
// For optional types, we need to return the value as-is
|
||||
// This is a workaround for V's type system limitation
|
||||
// where ?T cannot be directly returned from !T function
|
||||
mut result := val
|
||||
return result
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
$if T is string {
|
||||
@@ -89,10 +98,15 @@ 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 $if T is $option {
|
||||
// For optional types that don't match above patterns
|
||||
// Return the default value (none)
|
||||
mut result := val
|
||||
return result
|
||||
} $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 {
|
||||
@@ -131,18 +145,7 @@ pub fn encode[T](t T, args EncodeArgs) !Params {
|
||||
}
|
||||
}
|
||||
|
||||
// // Additional check: if field name suggests it should be skipped
|
||||
// // This is a fallback for cases where attribute parsing differs
|
||||
// if field.name == 'other' && !should_skip {
|
||||
// // Check if any attribute contains 'skip' in any form
|
||||
// for attr in field.attrs {
|
||||
// if attr.contains('skip') {
|
||||
// should_skip = true
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
if !should_skip {
|
||||
val := t.$(field.name)
|
||||
field_attrs := attrs_get(field.attrs)
|
||||
|
||||
Reference in New Issue
Block a user