diff --git a/decode.v b/decode.v index e455e92..b832b4d 100644 --- a/decode.v +++ b/decode.v @@ -3,6 +3,7 @@ module msgpack import time import encoding.hex import encoding.binary +import math const msg_bad_desc = 'unrecognized descriptor byte' @@ -11,7 +12,7 @@ struct Decoder { mut: pos int buffer []u8 - bd u8 + bd u8 // actual buffer value } pub fn new_decoder() Decoder { @@ -19,395 +20,310 @@ pub fn new_decoder() Decoder { } pub fn decode[T](src []u8) !T { - return T{} + mut val := T{} + + mut d := new_decoder() + d.decode[T](src, mut val) or { return error('error decoding data: ${err}') } + + return val } -pub fn (mut d Decoder) decode_from_string(data string) ! { - d.decode(hex.decode(data) or { return error('error decoding hex string') })! +pub fn (mut d Decoder) decode_from_string[T](data string) ! { + d.decode[T](hex.decode(data) or { return error('error decoding hex string') })! } -// TODO: proper decoding into data structures -// for now just get decoding of all types working. -pub fn (mut d Decoder) decode(data []u8) ! { +pub fn (mut d Decoder) decode[T](data []u8, mut val T) ! { d.buffer = data - for d.pos < d.buffer.len { - d.next() - d.decode_()! + d.next()! + + $if T is $int { + d.decode_integer[T](mut val) or { return error('error decoding integer: ${err}') } + } $else $if T is $float { + d.decode_float[T](mut val) or { return error('error decoding float: ${err}') } + } $else $if T is string { + d.decode_string[T](mut val) or { return error('error decoding string: ${err}') } + } $else $if T is []u8 { + d.decode_binary[T](mut val) or { return error('error decoding binary: ${err}') } + } $else $if T is $array { + d.decode_array[T](mut val) or { return error('error decoding array: ${err}') } + } $else $if T is $map { + d.decode_map[T](mut val) or { return error('error decoding map: ${err}') } + } $else $if T is time.Time { + d.decode_time[T](mut val) or { return error('error decoding time: ${err}') } + } $else $if T is $struct { + d.decode_struct[T](mut val) or { return error('error decoding struct: ${err}') } + } $else $if T is bool { + d.decode_bool[T](mut val) or { return error('error decoding boolean: ${err}') } + } $else { + return error('unsupported type for decoding: ${T.name}') } } -fn (mut d Decoder) decode_() ! { +pub fn (mut d Decoder) decode_integer[T](mut val T) ! { + data := d.buffer match d.bd { - mp_nil { - // n.v = .nil_ - // d.bdRead = false - println('nil') - } - mp_false { - // n.v = valueTypeBool - // n.b = false - println('false') - } - mp_true { - // n.v = valueTypeBool - // n.b = true - println('true') - } - mp_f32 { - // n.v = valueTypeFloat - // n.f = float64(math.Float32frombits(binary.big_endian_u32(d.d.decRd.readn4()))) - println('f32') - } - mp_f64 { - // n.v = valueTypeFloat - // n.f = math.Float64frombits(binary.big_endian_u64(d.d.decRd.readn8())) - println('f64') - } mp_u8 { - // n.v = valueTypeUint - // n.u = u64(d.d.decRd.readn1()) - println('u8') + val = data[d.pos] + d.pos++ } mp_u16 { - // n.v = valueTypeUint - // n.u = u64(binary.big_endian_u16(d.d.decRd.readn2())) - println('u16') + val = u64(binary.big_endian_u16(data[d.pos..d.pos + 2])) + d.pos += 2 } mp_u32 { - // n.v = valueTypeUint - // n.u = u64(binary.big_endian_u32(d.d.decRd.readn4())) - println('u32') + val = u64(int(binary.big_endian_u32(data[d.pos..d.pos + 4]))) + d.pos += 4 } mp_u64 { - // n.v = valueTypeUint - // n.u = u64(binary.big_endian_u64(d.d.decRd.readn8())) - println('u64') + val = u64(binary.big_endian_u64(data[d.pos..d.pos + 8])) + d.pos += 8 } mp_i8 { - // n.v = valueTypeInt - // n.i = i64(int8(d.d.decRd.readn1())) - println('i8') + val = i64(data[d.pos]) + d.pos++ } mp_i16 { - // n.v = valueTypeInt - // n.i = i64(int16(binary.big_endian_u16(d.d.decRd.readn2()))) - println('i16') + val = i64(i16(binary.big_endian_u16(data[d.pos..d.pos + 2]))) + d.pos += 2 } mp_i32 { - // n.v = valueTypeInt - // n.i = i64(int32(binary.big_endian_u32(d.d.decRd.readn4()))) - i := i64(int(binary.big_endian_u32(d.read_n(4)))) - // d.next() - println('int: ${i}') + val = i64(i32(binary.big_endian_u32(data[d.pos..d.pos + 4]))) + d.pos += 4 } mp_i64 { - // n.v = valueTypeInt - // n.i = i64(i64(binary.big_endian_u64(d.d.decRd.readn8()))) - println('i64') + val = i64(binary.big_endian_u64(data[d.pos..d.pos + 8])) + d.pos += 8 } else { - // println('else: $d.bd') - if d.bd in [mp_bin_8, mp_bin_16, mp_bin_32] { - println('bin') - } else if d.bd in [mp_str_8, mp_str_16, mp_str_32] - || (d.bd >= mp_fix_str_min && d.bd <= mp_fix_str_max) { - // println('string') - d.decode_string()! - } else if d.bd in [mp_array_16, mp_array_32] - || (d.bd >= mp_fix_array_min && d.bd <= mp_fix_array_max) { - println('array') - } else if d.bd in [mp_map_16, mp_map_32] - || (d.bd >= mp_fix_map_min && d.bd <= mp_fix_map_max) { - d.decode_map()! - } else if (d.bd >= mp_fix_ext_1 && d.bd <= mp_fix_ext_16) - || (d.bd >= mp_ext_8 && d.bd <= mp_ext_32) { - d.decode_ext()! - } + return error('invalid integer descriptor byte') } } - // default: - // switch { - // bd >= mpPosFixNumMin && bd <= mpPosFixNumMax: - // // positive fixnum (always signed) - // n.v = valueTypeInt - // n.i = i64(int8(bd)) - // bd >= mpNegFixNumMin && bd <= mpNegFixNumMax: - // // negative fixnum - // n.v = valueTypeInt - // n.i = i64(int8(bd)) - // bd == mp_str_8, bd == mp_str_16, bd == mp_str_32, bd >= mp_fix_str_min && bd <= mp_fix_str_max: - // d.d.fauxUnionReadRawBytes(d.h.WriteExt) - // // if d.h.WriteExt || d.h.RawToString { - // // n.v = .string_ - // // n.s = d.d.string_ZC(d.DecodeStringAsBytes()) - // // } else { - // // n.v = .bytes - // // n.l = d.DecodeBytes([]byte{}) - // // } - // bd == mp_bin_8, bd == mp_bin_16, bd == mp_bin_32: - // d.d.fauxUnionReadRawBytes(false) - // bd == mp_array_16, bd == mp_array_32, bd >= mp_fix_array_min && bd <= mp_fix_array_max: - // n.v = .array - // decodeFurther = true - // bd == mp_map_16, bd == mp_map_32, bd >= mp_fix_map_min && bd <= mp_fix_map_max: - // n.v = .map_ - // decodeFurther = true - // bd >= mp_fix_ext_1 && bd <= mp_fix_ext_16, bd >= mp_ext_8 && bd <= mp_ext_32: - // n.v = valueTypeExt - // clen := d.readExtLen() - // n.u = u64(d.d.decRd.readn1()) - // if n.u == u64(mpTimeExtTagU) { - // n.v = valueTypeTime - // n.t = d.decodeTime(clen) - // } else if d.d.bytes { - // n.l = d.d.decRd.rb.readx(uint(clen)) - // } else { - // n.l = decByteSlice(d.d.r(), clen, d.d.h.MaxInitLen, d.d.b[:]) - // } - // default: - // d.d.errorf("cannot infer value: %s: Ox%x/%d/%s", msg_bad_desc, bd, bd, mpdesc(bd)) - // } } -fn (mut d Decoder) decode_ext() ! { - // n.v = valueTypeExt - clen := d.read_ext_len()! - println('decode_ext - container len: ${clen}') - if d.bd == mp_time_ext_type { - // n.v = valueTypeTime - t := d.decode_time(clen) - println('time: ${t}') - } - // TODO: d.d.bytes? - // else if d.d.bytes { - // n.l = d.d.decRd.rb.readx(uint(clen)) - // } - else { - // n.l = decByteSlice(d.d.r(), clen, d.d.h.MaxInitLen, d.d.b[:]) +pub fn (mut d Decoder) decode_float[T](mut val T) ! { + data := d.buffer + match d.bd { + mp_f32 { + val = math.f32_from_bits(binary.big_endian_u32(data[1..4])) + d.pos += 4 + } + mp_f64 { + val = math.f64_from_bits(binary.big_endian_u64(data[1..8])) + d.pos += 8 + } + else { + return error('invalid float descriptor byte') + } } } -fn (mut d Decoder) decode_string() ! { - ct := match d.config.write_ext { - true { - match d.config.string_raw { - true { container_bin } - else { container_str } - } +pub fn (mut d Decoder) decode_string[T](mut val T) ! { + data := d.buffer + match d.bd { + mp_str_8, mp_str_16, mp_str_32, mp_fix_str_min...mp_fix_str_max { + str_len := d.read_str_len(data) or { return error('error reading string length') } + val = data[d.pos..d.pos + str_len].bytestr() + d.pos += str_len } else { - container_raw_legacy + return error('invalid string descriptor byte') } } - len := d.read_container_len(ct)! - x := d.read_n(len) - println('string: ${x.bytestr()} - len: ${len}') - d.decode_()! } -fn (mut d Decoder) decode_map() ! { - // containerLen := d.arrayStart(d.d.ReadArrayStart()) - // if containerLen == 0 { - // d.arrayEnd() - // return - // } - d.next() - container_len := d.read_map_start()! - println('map container_len: ${container_len}') - d.decode_()! +pub fn (mut d Decoder) decode_binary[T](mut val T) ! { + data := d.buffer + match d.bd { + mp_bin_8, mp_bin_16, mp_bin_32 { + bin_len := d.read_bin_len(data) or { return error('error reading binary length') } + val = data[d.pos..d.pos + bin_len] + d.pos += bin_len + } + else { + return error('invalid binary descriptor byte') + } + } } -fn (mut d Decoder) container_type() ValueType { - // if !d.bdRead { - // d.readNextBd() - // } - d.next() - bd := d.bd - if bd == mp_nil { - // d.bdRead = false - return .nil_ - } else if bd == mp_bin_8 || bd == mp_bin_16 || bd == mp_bin_32 { - return .bytes - } else if bd == mp_str_8 || bd == mp_str_16 || bd == mp_str_32 - || (bd >= mp_fix_str_min && bd <= mp_fix_str_max) { - if d.config.write_ext || d.config.string_raw { // UTF-8 string (new spec) - return .string_ - } - return .bytes // raw (old spec) - } else if bd == mp_array_16 || bd == mp_array_32 - || (bd >= mp_fix_array_min && bd <= mp_fix_array_max) { - return .array - } else if bd == mp_map_16 || bd == mp_map_32 || (bd >= mp_fix_map_min && bd <= mp_fix_map_max) { - return .map_ +pub fn (mut d Decoder) decode_array[T](mut val T) ! { + data := d.buffer + match d.bd { + mp_array_16, mp_array_32, mp_fix_array_min...mp_fix_array_max { + mut ana := []int{} + array_len := d.read_array_len(data) or { return error('error reading array length') } + for i in 0 .. array_len { + // TODO + } + } + else { + return error('invalid array descriptor byte') + } } - return .unset } -fn (mut d Decoder) read_container_len(ct ContainerType) !int { - bd := d.bd - if bd == ct.b8 { - return int(d.read_1()) - } else if bd == ct.b16 { - return int(binary.big_endian_u16(d.read_n(2))) - } else if bd == ct.b32 { - return int(binary.big_endian_u32(d.read_n(4))) - } else if (ct.b_fix_min & bd) == ct.b_fix_min { - return int(ct.b_fix_min ^ bd) - } else { - // return('cannot read container length: %s: hex: %x, decimal: %d', msg_bad_desc, bd, bd) - return error('cannot read container length: ${msgpack.msg_bad_desc}: hex: ${bd.hex()}, decimal: ${bd}') +// TODO +pub fn (mut d Decoder) decode_map[T](mut val T) ! { + data := d.buffer + match d.bd { + mp_map_16, mp_map_32, mp_fix_map_min...mp_fix_map_max { + map_len := d.read_map_len(data) or { return error('error reading map length') } + for i in 0 .. map_len { + mut key := '' + + key = decode[string](data[d.pos..]) or { return error('error decoding map key') } + + d.pos += key.len + 1 + val[key] = unsafe { nil } + } + } + else { + return error('invalid map descriptor byte') + } } - // d.bdRead = false - // return } -fn (mut d Decoder) read_map_start() !int { - // if d.advanceNil() { - if d.bd == mp_nil { - return container_len_nil +pub fn (mut d Decoder) decode_struct[T](mut val T) ! { + data := d.buffer + $for field in T.fields { + // Decode each field using its type + mut field_val := val.$(field.name) + d.decode(data[d.pos..], mut field_val) or { + return error('error decoding struct field: ${field.name}') + } + val[field.name] = field_val } - return d.read_container_len(container_map) } -fn (mut d Decoder) read_array_start() !int { - // if d.advanceNil() { - if d.bd == mp_nil { - return container_len_nil +pub fn (mut d Decoder) decode_bool[T](mut val T) ! { + val = d.bd == mp_true +} + +pub fn (mut d Decoder) decode_time[T](mut val T) ! { + data := d.buffer + $if T is time.Time || T is $int { + match d.bd { + mp_fix_ext_4 { + /* + timestamp 32 stores the number of seconds that have elapsed since 1970-01-01 00:00:00 UTC + in an 32-bit unsigned integer: + +--------+--------+--------+--------+--------+--------+ + | 0xd6 | -1 | seconds in 32-bit unsigned int | + +--------+--------+--------+--------+--------+--------+ + */ + sec := int(binary.big_endian_u32(data[d.pos..d.pos + 4])) + println(binary.big_endian_u32(data[d.pos..d.pos + 4])) + val = time.unix(i64(sec)) + d.pos += 4 + } + mp_fix_ext_8 { + /* + timestamp 64 stores the number of seconds and nanoseconds that have elapsed since 1970-01-01 00:00:00 UTC + in 32-bit unsigned integers: + +--------+--------+--------+--------+--------+------|-+--------+--------+--------+--------+ + | 0xd7 | -1 | nanosec. in 30-bit unsigned int | seconds in 34-bit unsigned int | + +--------+--------+--------+--------+--------+------^-+--------+--------+--------+--------+ + */ + sec := int(binary.big_endian_u64(data[d.pos..d.pos + 8])) + val = time.unix(i64(sec)) + d.pos += 8 + } + mp_ext_8 { + /* + timestamp 96 stores the number of seconds and nanoseconds that have elapsed since 1970-01-01 00:00:00 UTC + in 64-bit signed integer and 32-bit unsigned integer: + +--------+--------+--------+--------+--------+--------+--------+ + | 0xc7 | 12 | -1 |nanoseconds in 32-bit unsigned int | + +--------+--------+--------+--------+--------+--------+--------+ + +--------+--------+--------+--------+--------+--------+--------+--------+ + seconds in 64-bit signed int | + +--------+--------+--------+--------+--------+--------+--------+--------+ + */ + sec := int(binary.big_endian_u64(data[d.pos..d.pos + 12])) + val = time.unix(i64(sec)) + d.pos += 12 + } + else { + return error('invalid time descriptor byte') + } + } } - return d.read_container_len(container_array) } -fn (mut d Decoder) read_ext_len() !int { +fn (mut d Decoder) read_str_len(data []u8) !int { match d.bd { - mp_fix_ext_1 { - d.next() - return 1 + mp_str_8 { + return int(data[d.pos]) } - mp_fix_ext_2 { - d.next() - return 2 + mp_str_16 { + return int(binary.big_endian_u16(data[d.pos..d.pos + 2])) } - mp_fix_ext_4 { - d.next() - return 4 + mp_str_32 { + return int(binary.big_endian_u32(data[d.pos..d.pos + 4])) } - mp_fix_ext_8 { - d.next() - return 8 + mp_fix_str_min...mp_fix_str_max { + return data[d.pos - 1] - mp_fix_str_min } - mp_fix_ext_16 { - d.next() - return 16 + else { + return error('invalid string length descriptor byte') } - mp_ext_8 { - return int(d.read_1()) + } +} + +fn (mut d Decoder) read_bin_len(data []u8) !int { + match d.bd { + mp_bin_8 { + return int(data[d.pos]) } - mp_ext_16 { - return int(binary.big_endian_u16(d.read_n(2))) + mp_bin_16 { + return int(binary.big_endian_u16(data[d.pos..d.pos + 2])) } - mp_ext_32 { - return int(binary.big_endian_u32(d.read_n(4))) + mp_bin_32 { + return int(binary.big_endian_u32(data[d.pos..d.pos + 4])) } else { - return error('decoding ext bytes: found unexpected byte: ${d.bd.hex()}') + return error('invalid binary length descriptor byte') } } } -// func (d *msgpackDecDriver) DecodeTime() (t time.Time) { -// // decode time from string bytes or ext -// if d.advanceNil() { -// return -// } -// bd := d.bd -// var clen int -// if bd == mp_bin_8 || bd == mp_bin_16 || bd == mp_bin_32 { -// clen = d.read_container_len(msgpackContainerBin) // binary -// } else if bd == mp_str_8 || bd == mp_str_16 || bd == mp_str_32 || -// (bd >= mp_fix_str_min && bd <= mp_fix_str_max) { -// clen = d.read_container_len(msgpackContainerStr) // string/raw -// } else { -// // expect to see mp_fix_ext_4,-1 OR mp_fix_ext_8,-1 OR mp_ext_8,12,-1 -// d.bdRead = false -// b2 := d.d.decRd.readn1() -// if d.bd == mp_fix_ext_4 && b2 == mpTimeExtTagU { -// clen = 4 -// } else if d.bd == mp_fix_ext_8 && b2 == mpTimeExtTagU { -// clen = 8 -// } else if d.bd == mp_ext_8 && b2 == 12 && d.d.decRd.readn1() == mpTimeExtTagU { -// clen = 12 -// } else { -// d.d.errorf("invalid stream for decoding time as extension: got 0x%x, 0x%x", d.bd, b2) -// } -// } -// return d.decodeTime(clen) -// } - -// fn (mut d Decoder) decode_ext(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) { -// if xtag > 0xff { -// d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag) -// } -// if d.advanceNil() { -// return -// } -// xbs, realxtag1, zerocopy := d.decodeExtV(ext != nil, uint8(xtag)) -// realxtag := u64(realxtag1) -// if ext == nil { -// re := rv.(*RawExt) -// re.Tag = realxtag -// re.setData(xbs, zerocopy) -// } else if ext == SelfExt { -// d.d.sideDecode(rv, basetype, xbs) -// } else { -// ext.ReadExt(rv, xbs) -// } -// } +fn (mut d Decoder) read_array_len(data []u8) !int { + match d.bd { + mp_array_16 { + return int(binary.big_endian_u16(data[d.pos..d.pos + 2])) + } + mp_array_32 { + return int(binary.big_endian_u32(data[d.pos..d.pos + 4])) + } + mp_fix_array_min...mp_fix_array_max { + return data[d.pos - 1] - mp_fix_array_min + } + else { + return error('invalid array length descriptor byte') + } + } +} -fn (mut d Decoder) decode_time(clen int) time.Time { - // d.bdRead = false - match clen { - 4 { - return time.unix(i64(binary.big_endian_u32(d.read_n(4)))) +fn (mut d Decoder) read_map_len(data []u8) !int { + match d.bd { + mp_map_16 { + return int(binary.big_endian_u16(data[d.pos..d.pos + 2])) + } + mp_map_32 { + return int(binary.big_endian_u32(data[d.pos..d.pos + 4])) + } + mp_fix_map_min...mp_fix_map_max { + return data[d.pos - 1] - mp_fix_map_min } else { - panic('unsupported currently') + return error('invalid map length descriptor byte') } } - // match clen { - // 4 { - // // return time.unix(i64(binary.big_endian_u32(d.d.decRd.readn4())), 0).utc() - // return time.unix(i64(binary.big_endian_u32(d.read4())), 0).utc() - // } - // 8 { - // // tv := binary.big_endian_u64(d.d.decRd.readn8()) - // // return time.Unix(i64(tv&0x00000003ffffffff), i64(tv>>34)).utc() - // tv := binary.big_endian_u64(d.d.decRd.readn8()) - // return time.unix(i64(tv&0x00000003ffffffff), i64(tv>>34)).utc() - // } - // 12 { - // nsec := binary.big_endian_u32(d.readn4()) - // sec := binary.big_endian_u64(d.readn8()) - // return time.unix(i64(sec), i64(nsec)).utc() - // } - // else { - // // d.error("invalid length of bytes for decoding time - expecting 4 or 8 or 12, got $clen") - // } - // } } -pub fn (mut d Decoder) next() { +fn (mut d Decoder) next() ! { + if d.pos >= d.buffer.len { + return error('unexpected end of data') + } d.bd = d.buffer[d.pos] d.pos++ } - -fn (mut d Decoder) read_1() u8 { - d.next() - return d.buffer[d.pos] -} - -fn (mut d Decoder) read_n(len int) []u8 { - b := d.buffer[d.pos..d.pos + len] - d.pos += len - 1 - d.next() - return b -} diff --git a/decode_test.v b/decode_test.v index 27b4d90..da6747e 100644 --- a/decode_test.v +++ b/decode_test.v @@ -4,39 +4,53 @@ import msgpack import encoding.hex import time +struct Struct { + a string + b int +} + fn test_decoding() { - // // Test decoding integers - // assert msgpack.decode[i64](hex.decode('2a')!)! == 42 - // assert msgpack.decode[i64](hex.decode('d185')!)! == -123 + // Test decoding integers + assert msgpack.decode[int](hex.decode('d200000000')!)! == 0 + assert msgpack.decode[int](hex.decode('d20000002a')!)! == 42 + assert msgpack.decode[int](hex.decode('d2ffffff85')!)! == -123 + + // Test decoding strings + assert msgpack.decode[string](hex.decode('a568656c6c6f')!)! == 'hello' + assert msgpack.decode[string](hex.decode('a0')!)! == '' // Test empty string - // // Test decoding strings - // assert msgpack.decode[string](hex.decode('a5hello')!)! == 'hello' - // assert msgpack.decode[string](hex.decode('a0')!)! == '' + // Test decoding arrays + // assert msgpack.decode[[]int](hex.decode('93d200000001d200000002d200000003')!)! == [1, 2, 3] - // // Test decoding arrays - // assert msgpack.decode[[]int](hex.decode('93010203')!)! == [1, 2, 3] - // assert msgpack.decode[[]int](hex.decode('90')!)! == [] + // msgpack.decode[[]u8](msgpack.encode([u8(1),1,2]))! + // msgpack.decode[[]int](msgpack.encode([1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]))! + // msgpack.decode[[]u32](msgpack.encode([u32(1),1,2]))! + // assert msgpack.decode[[]u8](msgpack.encode([u8(1),1,1]))! == [u8(1), 2, 3] + // assert msgpack.decode[[]int](msgpack.encode([1,1,1]))! == [1, 2, 3] + // assert msgpack.decode[[]int](hex.decode('90')!)! == [] // Test empty array // // Test decoding maps - // assert msgpack.decode[map[string]string](hex.decode('82a4namea4Johna3age1e')!)! == { + // assert msgpack.decode[map[string]string](hex.decode('82a46e616d65a44a6f686ea3616765a23330')!)! == { // 'name': 'John' // 'age': '30' // } - // assert msgpack.decode[map[string]string](hex.decode('80')!)! == {} + // assert msgpack.decode[map[string]string](hex.decode('80')!)! == {} // Test empty map - // // Test decoding booleans - // assert msgpack.decode[bool](hex.decode('c3')!)! == true - // assert msgpack.decode[bool](hex.decode('c2')!)! == false + // // Test decoding structs + // assert msgpack.decode[Struct](hex.decode('82a161a44a6f686ea162d20000001e')!)! == Struct{'John', 30} - // // Test decoding floating-point numbers - // assert msgpack.decode[f64](hex.decode('cb@\t!f9f01b86a8')!)! == 3.14 + // Test decoding booleans + assert msgpack.decode[bool](hex.decode('c3')!)! == true + assert msgpack.decode[bool](hex.decode('c2')!)! == false + + // Test decoding floating-point numbers + assert msgpack.decode[f64](hex.decode('cb40091eb851eb851f')!)! == 3.14 + assert msgpack.decode[f32](hex.decode('ca4048f5c3')!)! == 3.14 // // Test decoding time // // Assuming time is 2023-11-27 12:34:56 - // assert msgpack.decode[time.Time](hex.decode('c704005fdce0d0')!)! == time.unix(1679922896) + // assert msgpack.decode[time.Time](hex.decode('d6ff642196d0')!)! == time.unix(1679922896) // // Test decoding byte slices // assert msgpack.decode[[]u8](hex.decode('c403010203')!)! == [u8(1), 2, 3] - - assert true } diff --git a/encode_test.v b/encode_test.v index 102e65e..3e702b6 100644 --- a/encode_test.v +++ b/encode_test.v @@ -49,5 +49,5 @@ fn test_encoding() { assert msgpack.encode(time.unix(1679922896)) == hex.decode('d6ff642196d0')! // REVIEW // Test encoding byte slices - assert msgpack.encode([u8(1), 2, 3]) == hex.decode('c403010203')! + assert msgpack.encode([u8(1), 2, 3]) == hex.decode('c403010203')! // REVIEW }