toml: add reflection method (#12664)
parent
0da7e2f8ab
commit
1d6cc57d9c
|
@ -226,3 +226,36 @@ fn (a Any) value_(value Any, key []string) Any {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (a Any) reflect<T>() T {
|
||||||
|
mut reflected := T{}
|
||||||
|
$for field in T.fields {
|
||||||
|
$if field.typ is string {
|
||||||
|
reflected.$(field.name) = a.value(field.name).default_to('').string()
|
||||||
|
} $else $if field.typ is bool {
|
||||||
|
reflected.$(field.name) = a.value(field.name).default_to(false).bool()
|
||||||
|
} $else $if field.typ is int {
|
||||||
|
reflected.$(field.name) = a.value(field.name).default_to(0).int()
|
||||||
|
} $else $if field.typ is f32 {
|
||||||
|
reflected.$(field.name) = a.value(field.name).default_to(0.0).f32()
|
||||||
|
} $else $if field.typ is f64 {
|
||||||
|
reflected.$(field.name) = a.value(field.name).default_to(0.0).f64()
|
||||||
|
} $else $if field.typ is i64 {
|
||||||
|
reflected.$(field.name) = a.value(field.name).default_to(0).i64()
|
||||||
|
} $else $if field.typ is u64 {
|
||||||
|
reflected.$(field.name) = a.value(field.name).default_to(0).u64()
|
||||||
|
} $else $if field.typ is Any {
|
||||||
|
reflected.$(field.name) = a.value(field.name)
|
||||||
|
} $else $if field.typ is DateTime {
|
||||||
|
dt := DateTime{'0000-00-00T00:00:00.000'}
|
||||||
|
reflected.$(field.name) = a.value(field.name).default_to(dt).datetime()
|
||||||
|
} $else $if field.typ is Date {
|
||||||
|
da := Date{'0000-00-00'}
|
||||||
|
reflected.$(field.name) = a.value(field.name).default_to(da).date()
|
||||||
|
} $else $if field.typ is Time {
|
||||||
|
t := Time{'00:00:00.000'}
|
||||||
|
reflected.$(field.name) = a.value(field.name).default_to(t).time()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return reflected
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
import toml
|
||||||
|
|
||||||
|
const toml_text = '# This TOML can reflect to a struct
|
||||||
|
name = "Tom"
|
||||||
|
age = 45
|
||||||
|
height = 1.97
|
||||||
|
|
||||||
|
birthday = 1980-04-23
|
||||||
|
|
||||||
|
[bio]
|
||||||
|
text = "Tom has done many great things"
|
||||||
|
years_of_service = 5
|
||||||
|
|
||||||
|
[config]
|
||||||
|
data = [ 1, 2, 3 ]
|
||||||
|
levels = { "info" = 1, "warn" = 2, "critical" = 3 }
|
||||||
|
'
|
||||||
|
|
||||||
|
struct Bio {
|
||||||
|
text string
|
||||||
|
years_of_service int
|
||||||
|
}
|
||||||
|
|
||||||
|
struct User {
|
||||||
|
name string
|
||||||
|
age int
|
||||||
|
height f64
|
||||||
|
birthday toml.Date
|
||||||
|
|
||||||
|
config toml.Any
|
||||||
|
mut:
|
||||||
|
bio Bio
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_reflect() {
|
||||||
|
toml_doc := toml.parse(toml_text) or { panic(err) }
|
||||||
|
|
||||||
|
mut user := toml_doc.reflect<User>()
|
||||||
|
user.bio = toml_doc.value('bio').reflect<Bio>()
|
||||||
|
|
||||||
|
assert user.name == 'Tom'
|
||||||
|
assert user.age == 45
|
||||||
|
assert user.height == 1.97
|
||||||
|
assert user.birthday.str() == '1980-04-23'
|
||||||
|
assert user.bio.text == 'Tom has done many great things'
|
||||||
|
assert user.bio.years_of_service == 5
|
||||||
|
|
||||||
|
assert user.config.value('data[0]').int() == 1
|
||||||
|
assert user.config.value('levels.warn').int() == 2
|
||||||
|
}
|
|
@ -173,6 +173,10 @@ pub fn (d Doc) to_any() Any {
|
||||||
return ast_to_any(d.ast.table)
|
return ast_to_any(d.ast.table)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (d Doc) reflect<T>() T {
|
||||||
|
return d.to_any().reflect<T>()
|
||||||
|
}
|
||||||
|
|
||||||
// value queries a value from the TOML document.
|
// value queries a value from the TOML document.
|
||||||
// `key` supports a small query syntax scheme:
|
// `key` supports a small query syntax scheme:
|
||||||
// Maps can be queried in "dotted" form e.g. `a.b.c`.
|
// Maps can be queried in "dotted" form e.g. `a.b.c`.
|
||||||
|
|
Loading…
Reference in New Issue