v / vlib / yaml / path.v
139 lines · 133 sloc · 2.12 KB · d96fe54c0a96fd6d651e9cb3c61b137ccc5c7dbe
Raw
1module yaml
2
3import time
4import x.json2
5
6fn (a Any) value_(current Any, key []string) ?Any {
7 if key.len == 0 {
8 return none
9 }
10 k, index := parse_array_key(key[0])
11 value := match current {
12 []Any {
13 if k != '' {
14 return none
15 }
16 current[index] or { return none }
17 }
18 map[string]Any {
19 v := current[k] or { return none }
20 if index > -1 {
21 if v is []Any {
22 v[index] or { return none }
23 } else {
24 return none
25 }
26 } else {
27 v
28 }
29 }
30 else {
31 return none
32 }
33 }
34
35 if key.len <= 1 {
36 return value
37 }
38 return match value {
39 []Any, map[string]Any { a.value_(value, key[1..]) }
40 else { none }
41 }
42}
43
44fn parse_dotted_key(key string) ![]string {
45 mut out := []string{}
46 mut buf := ''
47 mut in_string := false
48 mut delimiter := u8(` `)
49 for ch in key {
50 if ch in [`"`, `'`] {
51 if !in_string {
52 delimiter = ch
53 in_string = true
54 continue
55 }
56 if ch == delimiter {
57 in_string = false
58 if buf != '' {
59 out << buf
60 }
61 buf = ''
62 delimiter = ` `
63 continue
64 }
65 }
66 buf += ch.ascii_str()
67 if !in_string && ch == `.` {
68 buf = buf[..buf.len - 1]
69 if buf != '' {
70 out << buf
71 }
72 buf = ''
73 }
74 }
75 if buf != '' {
76 out << buf
77 }
78 if in_string {
79 return error('yaml: missing closing string delimiter `${delimiter.ascii_str()}`')
80 }
81 return out
82}
83
84fn parse_array_key(key string) (string, int) {
85 mut index := -1
86 mut k := key
87 if k.contains('[') {
88 index = k.all_after('[').all_before(']').int()
89 if k.starts_with('[') {
90 k = ''
91 } else {
92 k = k.all_before('[')
93 }
94 }
95 return k, index
96}
97
98fn from_json2(value json2.Any) Any {
99 return match value {
100 []json2.Any {
101 mut arr := []Any{cap: value.len}
102 for item in value {
103 arr << from_json2(item)
104 }
105 Any(arr)
106 }
107 map[string]json2.Any {
108 mut out := map[string]Any{}
109 for key, item in value {
110 out[key] = from_json2(item)
111 }
112 Any(out)
113 }
114 bool {
115 Any(value)
116 }
117 f32, f64 {
118 Any(f64(value))
119 }
120 i8, i16, i32, int {
121 Any(int(value))
122 }
123 i64 {
124 Any(value)
125 }
126 u8, u16, u32, u64 {
127 Any(u64(value))
128 }
129 string {
130 Any(value)
131 }
132 time.Time {
133 Any(value.str())
134 }
135 json2.Null {
136 null
137 }
138 }
139}
140