toml: fix @[toml: ], support @[skip] (#21571)

This commit is contained in:
tcn 2024-05-26 08:35:59 +02:00 committed by GitHub
parent b4c560d4b8
commit c689f801ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 147 additions and 98 deletions

View File

@ -0,0 +1,15 @@
import toml
struct TestStruct {
foo int
bar bool @[skip]
baz string = 'def' @[toml: barbaz]
}
fn test_toml_attr_encode() {
assert toml.encode(TestStruct{}) == 'foo = 0\nbarbaz = "def"'
}
fn test_toml_attr_decode() {
assert toml.decode[TestStruct]('foo = 0\nbarbaz = "def"')! == TestStruct{}
}

View File

@ -33,7 +33,19 @@ pub fn decode[T](toml_txt string) !T {
fn decode_struct[T](doc Any, mut typ T) { fn decode_struct[T](doc Any, mut typ T) {
$for field in T.fields { $for field in T.fields {
value := doc.value(field.name) mut field_name := field.name
mut skip := false
for attr in field.attrs {
if attr == 'skip' {
skip = true
break
}
if attr.starts_with('toml:') {
field_name = attr.all_after(':').trim_space()
}
}
if !skip {
value := doc.value(field_name)
$if field.is_enum { $if field.is_enum {
typ.$(field.name) = value.int() typ.$(field.name) = value.int()
} $else $if field.typ is string { } $else $if field.typ is string {
@ -81,32 +93,38 @@ fn decode_struct[T](doc Any, mut typ T) {
// |k, v| k, v.int() // |k, v| k, v.int()
// Unfortunately lambdas have issues with multiple return at the time of writing // Unfortunately lambdas have issues with multiple return at the time of writing
map[string]int { map[string]int {
typ.$(field.name) = maps.to_map[string, Any, string, int](mmap, fn (k string, v Any) (string, int) { typ.$(field.name) = maps.to_map[string, Any, string, int](mmap,
fn (k string, v Any) (string, int) {
return k, v.int() return k, v.int()
}) })
} }
map[string]i64 { map[string]i64 {
typ.$(field.name) = maps.to_map[string, Any, string, i64](mmap, fn (k string, v Any) (string, i64) { typ.$(field.name) = maps.to_map[string, Any, string, i64](mmap,
fn (k string, v Any) (string, i64) {
return k, v.i64() return k, v.i64()
}) })
} }
map[string]u64 { map[string]u64 {
typ.$(field.name) = maps.to_map[string, Any, string, u64](mmap, fn (k string, v Any) (string, u64) { typ.$(field.name) = maps.to_map[string, Any, string, u64](mmap,
fn (k string, v Any) (string, u64) {
return k, v.u64() return k, v.u64()
}) })
} }
map[string]f32 { map[string]f32 {
typ.$(field.name) = maps.to_map[string, Any, string, f32](mmap, fn (k string, v Any) (string, f32) { typ.$(field.name) = maps.to_map[string, Any, string, f32](mmap,
fn (k string, v Any) (string, f32) {
return k, v.f32() return k, v.f32()
}) })
} }
map[string]f64 { map[string]f64 {
typ.$(field.name) = maps.to_map[string, Any, string, f64](mmap, fn (k string, v Any) (string, f64) { typ.$(field.name) = maps.to_map[string, Any, string, f64](mmap,
fn (k string, v Any) (string, f64) {
return k, v.f64() return k, v.f64()
}) })
} }
map[string]bool { map[string]bool {
typ.$(field.name) = maps.to_map[string, Any, string, bool](mmap, fn (k string, v Any) (string, bool) { typ.$(field.name) = maps.to_map[string, Any, string, bool](mmap,
fn (k string, v Any) (string, bool) {
return k, v.bool() return k, v.bool()
}) })
} }
@ -117,12 +135,14 @@ fn decode_struct[T](doc Any, mut typ T) {
}) })
} }
map[string]Date { map[string]Date {
typ.$(field.name) = maps.to_map[string, Any, string, Date](mmap, fn (k string, v Any) (string, Date) { typ.$(field.name) = maps.to_map[string, Any, string, Date](mmap,
fn (k string, v Any) (string, Date) {
return k, v.date() return k, v.date()
}) })
} }
map[string]Time { map[string]Time {
typ.$(field.name) = maps.to_map[string, Any, string, Time](mmap, fn (k string, v Any) (string, Time) { typ.$(field.name) = maps.to_map[string, Any, string, Time](mmap,
fn (k string, v Any) (string, Time) {
return k, v.time() return k, v.time()
}) })
} }
@ -135,6 +155,7 @@ fn decode_struct[T](doc Any, mut typ T) {
} }
} }
} }
}
// encode encodes the type `T` into a TOML string. // encode encodes the type `T` into a TOML string.
// If `T` has a custom `.to_toml()` method, it will be used instead of the default. // If `T` has a custom `.to_toml()` method, it will be used instead of the default.
@ -151,7 +172,20 @@ pub fn encode[T](typ T) string {
fn encode_struct[T](typ T) map[string]Any { fn encode_struct[T](typ T) map[string]Any {
mut mp := map[string]Any{} mut mp := map[string]Any{}
$for field in T.fields { $for field in T.fields {
mp[field.name] = to_any(typ.$(field.name)) mut skip := false
mut field_name := field.name
for attr in field.attrs {
if attr == 'skip' {
skip = true
break
}
if attr.starts_with('toml:') {
field_name = attr.all_after(':').trim_space()
}
}
if !skip {
mp[field_name] = to_any(typ.$(field.name))
}
} }
return mp return mp
} }