From 2aafab50adad6698387be5d66cfe9646288a2d89 Mon Sep 17 00:00:00 2001 From: timurgordon Date: Fri, 7 Feb 2025 16:38:34 +0300 Subject: [PATCH] better heroscript encoding and support for ourtime --- lib/data/encoderhero/encoder.v | 45 +++------------ lib/data/encoderhero/encoder_test.v | 58 +++++++++++++++++++- lib/data/paramsparser/params_export_import.v | 2 +- lib/data/paramsparser/params_export_test.v | 2 +- lib/data/paramsparser/params_reflection.v | 10 +++- 5 files changed, 74 insertions(+), 43 deletions(-) diff --git a/lib/data/encoderhero/encoder.v b/lib/data/encoderhero/encoder.v index 3a4dbc70..b7311144 100644 --- a/lib/data/encoderhero/encoder.v +++ b/lib/data/encoderhero/encoder.v @@ -28,59 +28,28 @@ pub fn encode[T](val T) !string { $if T is $struct { e.encode_struct[T](val)! } $else $if T is $array { - e.add_child_list[T](val, 'TODO') + e.encode_array(val) } $else { return error('can only add elements for struct or array of structs. \n${val}') } - return e.export()! + return e.export() } // export exports an encoder into encoded heroscript -pub fn (e Encoder) export() !string { +pub fn (e Encoder) export() string { mut script := e.params.export( pre: '!!define.${e.action_names.join('.')}' indent: ' ' skip_empty: true ) - script += e.children.map(it.export()!).join('\n') + script += e.children.map(it.export()).filter(it.trim_space() != '').join_lines().trim_space() + if script == '!!define.${e.action_names.join('.')}' { + return '' + } return script } -// needs to be a struct we are adding -// parent is the name of the action e.g define.customer:contact -pub fn (mut e Encoder) add_child[T](val T, parent string) ! { - $if T is $array { - mut counter := 0 - for valitem in val { - mut e2 := e.add_child[T](valitem, '${parent}:${counter}')! - } - return - } - mut e2 := Encoder{ - params: paramsparser.Params{} - parent: &e - action_names: e.action_names.clone() // careful, if not cloned gets mutated later - } - $if T is $struct { - e2.params.set('key', parent) - e2.encode_struct[T](val)! - e.children << e2 - } $else { - return error('can only add elements for struct or array of structs. \n${val}') - } -} - -pub fn (mut e Encoder) add_child_list[U](val []U, parent string) ! { - for i in 0 .. val.len { - mut counter := 0 - $if U is $struct { - e.add_child(val[i], '${parent}:${counter}')! - counter += 1 - } - } -} - // needs to be a struct we are adding // parent is the name of the action e.g define.customer:contact pub fn (mut e Encoder) add[T](val T) ! { diff --git a/lib/data/encoderhero/encoder_test.v b/lib/data/encoderhero/encoder_test.v index 52ed38f1..8ddb940f 100644 --- a/lib/data/encoderhero/encoder_test.v +++ b/lib/data/encoderhero/encoder_test.v @@ -1,6 +1,7 @@ module encoderhero import freeflowuniverse.herolib.data.paramsparser +import freeflowuniverse.herolib.data.ourtime import time import v.reflection @@ -13,6 +14,40 @@ struct Remark { text string } +struct Company { + name string + founded ourtime.OurTime + employees []Person +} + +const company = Company{ + name: "Tech Corp" + founded: ourtime.new('2022-12-05 20:14')! + employees: [ + person, + Person{ + id: 2 + name: "Alice" + age: 30 + birthday: time.new( + day: 20 + month: 6 + year: 1990 + ) + car: Car{ + name: "Alice's car" + year: 2018 + } + profiles: [ + Profile{ + platform: 'LinkedIn' + url: 'linkedin.com/alice' + }, + ] + }, + ] +} + struct Person { Base mut: @@ -43,7 +78,7 @@ struct Profile { const person_heroscript = " !!define.person id:1 name:Bob birthday:'2012-12-12 00:00:00' !!define.person.car name:'Bob\\'s car' year:2014 -!!define.person.car.insurance expiration:'0000-00-00 00:00:00' provider:'' +!!define.person.car.insurance provider:insurer !!define.person.profile platform:Github url:github.com/example " @@ -60,6 +95,9 @@ const person = Person{ car: Car{ name: "Bob's car" year: 2014 + insurance: Insurance { + provider: "insurer" + } } profiles: [ Profile{ @@ -69,7 +107,23 @@ const person = Person{ ] } +const company_script = " +!!define.company name:'Tech Corp' founded:'2022-12-05 20:14' +!!define.company.person id:1 name:Bob birthday:'2012-12-12 00:00:00' +!!define.company.person.car name:'Bob\'s car' year:2014 +!!define.company.person.car.insurance provider:insurer' + +!!define.company.person.profile platform:Github url:github.com/example + +!!define.company.person id:2 name:Alice birthday:'1990-06-20 00:00:00' +!!define.company.person.car name:'Alice\'s car' year:2018 +!!define.company.person.car.insurance + +!!define.company.person.profile platform:LinkedIn url:linkedin.com/alice +" + fn test_encode() ! { person_script := encode[Person](person)! assert person_script.trim_space() == person_heroscript.trim_space() -} + assert encode[Company](company)!.trim_space() == company_script.trim_space() +} \ No newline at end of file diff --git a/lib/data/paramsparser/params_export_import.v b/lib/data/paramsparser/params_export_import.v index 11ba9d8b..283428d7 100644 --- a/lib/data/paramsparser/params_export_import.v +++ b/lib/data/paramsparser/params_export_import.v @@ -192,7 +192,7 @@ fn (p Params) export_helper(args_ ExportArgs) ![]ParamExportItem { } fn val_is_empty(val string) bool { - return val == '' || val == '[]' + return val == '' || val == '[]' || val == '0000-00-00 00:00:00' } @[params] diff --git a/lib/data/paramsparser/params_export_test.v b/lib/data/paramsparser/params_export_test.v index 68d5cc31..2fde7ba3 100644 --- a/lib/data/paramsparser/params_export_test.v +++ b/lib/data/paramsparser/params_export_test.v @@ -290,4 +290,4 @@ fn test_export_text() { } paramsout := params.export() assert paramsout.trim_space() == "text:'This content contains the character \\' in it'" -} +} \ No newline at end of file diff --git a/lib/data/paramsparser/params_reflection.v b/lib/data/paramsparser/params_reflection.v index 7a922749..0c47dbab 100644 --- a/lib/data/paramsparser/params_reflection.v +++ b/lib/data/paramsparser/params_reflection.v @@ -1,6 +1,7 @@ module paramsparser import time +import freeflowuniverse.herolib.data.ourtime import v.reflection // import freeflowuniverse.herolib.data.encoderhero // TODO: support more field types @@ -65,6 +66,13 @@ pub fn (params Params) decode_value[T](_ T, key string) !T { return time.Time{} } return time.parse(time_str)! + } $else $if T is ourtime.OurTime { + time_str := params.get(key)! + // todo: 'handle other null times' + if time_str == '0000-00-00 00:00:00' { + return ourtime.new('0000-00-00 00:00:00')! + } + return ourtime.new(time_str)! } $else $if T is $struct { child_params := params.get_params(key)! child := child_params.decode_struct(T{})! @@ -99,7 +107,7 @@ pub fn encode[T](t T, args EncodeArgs) !Params { key = field_attrs['alias'] } $if val is string || val is int || val is bool || val is i64 || val is u32 - || val is time.Time { + || val is time.Time || val is ourtime.OurTime { params.set(key, '${val}') } $else $if field.is_enum { params.set(key, '${int(val)}')