v
Зеркало из https://github.com/vlang/v
1// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module json2
5
6import time
7
8// i8 uses `Any` as a 16-bit integer.
9pub fn (f Any) i8() i8 {
10match f {
11i8 {
12return f
13}
14i16, i32, int, i64, u8, u16, u32, u64, f32, f64, bool {
15return i8(f)
16}
17string {
18return f.i8()
19}
20else {
21return 0
22}
23}
24}
25
26// i16 uses `Any` as a 16-bit integer.
27pub fn (f Any) i16() i16 {
28match f {
29i16 {
30return f
31}
32i8, i32, int, i64, u8, u16, u32, u64, f32, f64, bool {
33return i16(f)
34}
35string {
36return f.i16()
37}
38else {
39return 0
40}
41}
42}
43
44// int uses `Any` as an integer.
45pub fn (f Any) int() int {
46match f {
47int {
48return f
49}
50i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, bool {
51return int(f)
52}
53string {
54return f.int()
55}
56else {
57return 0
58}
59}
60}
61
62// i32 uses `Any` as a 32-bit integer.
63pub fn (f Any) i32() i32 {
64match f {
65i32 {
66return f
67}
68i8, i16, int, i64, u8, u16, u32, u64, f32, f64, bool {
69return i32(f)
70}
71string {
72return f.i32()
73}
74else {
75return 0
76}
77}
78}
79
80// i64 uses `Any` as a 64-bit integer.
81pub fn (f Any) i64() i64 {
82match f {
83i64 {
84return f
85}
86i8, i16, i32, int, u8, u16, u32, u64, f32, f64, bool {
87return i64(f)
88}
89string {
90return f.i64()
91}
92else {
93return 0
94}
95}
96}
97
98// u64 uses `Any` as a 64-bit unsigned integer.
99pub fn (f Any) u64() u64 {
100match f {
101u64 {
102return f
103}
104u8, u16, u32, i8, i16, i32, int, i64, f32, f64, bool {
105return u64(f)
106}
107string {
108return f.u64()
109}
110else {
111return 0
112}
113}
114}
115
116// f32 uses `Any` as a 32-bit float.
117pub fn (f Any) f32() f32 {
118match f {
119f32 {
120return f
121}
122bool, i8, i16, i32, int, i64, u8, u16, u32, u64, f64 {
123return f32(f)
124}
125string {
126return f.f32()
127}
128else {
129return 0.0
130}
131}
132}
133
134// f64 uses `Any` as a 64-bit float.
135pub fn (f Any) f64() f64 {
136match f {
137f64 {
138return f
139}
140i8, i16, i32, int, i64, u8, u16, u32, u64, f32 {
141return f64(f)
142}
143string {
144return f.f64()
145}
146else {
147return 0.0
148}
149}
150}
151
152// bool uses `Any` as a bool.
153pub fn (f Any) bool() bool {
154match f {
155bool {
156return f
157}
158string {
159if f == 'false' {
160return false
161}
162if f == 'true' {
163return true
164}
165if f.len > 0 {
166return f != '0' && f != '0.0'
167} else {
168return false
169}
170}
171i8, i16, i32, int, i64 {
172return i64(f) != 0
173}
174u8, u16, u32, u64 {
175return u64(f) != 0
176}
177f32, f64 {
178return f64(f) != 0.0
179}
180else {
181return false
182}
183}
184}
185
186// arr uses `Any` as an array.
187pub fn (f Any) arr() []Any {
188if f is []Any {
189return f
190} else if f is map[string]Any {
191mut arr := []Any{}
192for _, v in f {
193arr << v
194}
195return arr
196}
197return [f]
198}
199
200// as_map uses `Any` as a map.
201pub fn (f Any) as_map() map[string]Any {
202if f is map[string]Any {
203return f
204} else if f is []Any {
205mut mp := map[string]Any{}
206for i, fi in f {
207mp['${i}'] = fi
208}
209return mp
210}
211return {
212'0': f
213}
214}
215
216// to_time uses `Any` as a time.Time.
217pub fn (f Any) to_time() !time.Time {
218match f {
219time.Time {
220return f
221}
222i64 {
223return time.unix(f)
224}
225string {
226is_iso8601 := f[4] == `-` && f[7] == `-`
227if is_iso8601 {
228return time.parse_iso8601(f)!
229}
230is_rfc3339 := f.len == 24 && f[23] == `Z` && f[10] == `T`
231if is_rfc3339 {
232return time.parse_rfc3339(f)!
233}
234mut is_unix_timestamp := true
235for c in f {
236if c == `-` || (c >= `0` && c <= `9`) {
237continue
238}
239is_unix_timestamp = false
240break
241}
242if is_unix_timestamp {
243return time.unix(f.i64())
244}
245// TODO: parse_iso8601
246// TODO: parse_rfc2822
247return time.parse(f)!
248}
249else {
250return error('not a time value: ${f} of type: ${f.type_name()}')
251}
252}
253}
254
255// map_from convert a struct to map of Any
256pub fn map_from[T](t T) map[string]Any {
257mut m := map[string]Any{}
258$if T is $struct {
259$for field in T.fields {
260value := t.$(field.name)
261
262$if field.is_array {
263mut arr := []Any{}
264for variable in value {
265arr << Any(variable)
266}
267m[field.name] = arr
268arr.clear()
269} $else $if field.is_struct {
270m[field.name] = map_from(value)
271} $else $if field.is_map {
272// TODO
273} $else $if field.is_alias {
274// TODO
275} $else $if field.is_option {
276// TODO
277} $else {
278// TODO: improve memory usage when convert
279$if field.typ is string {
280m[field.name] = value.str()
281} $else $if field.typ is bool {
282m[field.name] = t.$(field.name).str().bool()
283} $else $if field.typ is i8 {
284m[field.name] = t.$(field.name).str().i8()
285} $else $if field.typ is i16 {
286m[field.name] = t.$(field.name).str().i16()
287} $else $if field.typ is i32 {
288m[field.name] = t.$(field.name).str().i32()
289} $else $if field.typ is int {
290m[field.name] = t.$(field.name).str().int()
291} $else $if field.typ is i64 {
292m[field.name] = t.$(field.name).str().i64()
293} $else $if field.typ is f32 {
294m[field.name] = t.$(field.name).str().f32()
295} $else $if field.typ is f64 {
296m[field.name] = t.$(field.name).str().f64()
297} $else $if field.typ is u8 {
298m[field.name] = t.$(field.name).str().u8()
299} $else $if field.typ is u16 {
300m[field.name] = t.$(field.name).str().u16()
301} $else $if field.typ is u32 {
302m[field.name] = t.$(field.name).str().u32()
303} $else $if field.typ is u64 {
304m[field.name] = t.$(field.name).str().u64()
305} $else {
306// return error("The type of `${field.name}` can't be decoded. Please open an issue at https://github.com/vlang/v/issues/new/choose")
307}
308}
309}
310}
311return m
312}
313