(* Copyright (c) Zefchain Labs, Inc. * SPDX-License-Identifier: MIT OR Apache-2.0 *) open Stdint open Misc let max_length = 1 lsl 31 - 1 let bool bo = if bo then {r=Bytes.make 1 '\001'; depth=0} else {r=Bytes.make 1 '\000'; depth=0} let uint8 (i : uint8) = let b = Bytes.create 1 in Uint8.to_bytes_little_endian i b 0; {r=b; depth=0} let uint16 (i : uint16) = let b = Bytes.create 2 in Uint16.to_bytes_little_endian i b 0; {r=b; depth=0} let uint32 (i : uint32) = let b = Bytes.create 4 in Uint32.to_bytes_little_endian i b 0; {r=b; depth=0} let uint64 (i : uint64) = let b = Bytes.create 8 in Uint64.to_bytes_little_endian i b 0; {r=b; depth=0} let uint128 (i : uint128) = let b = Bytes.create 16 in Uint128.to_bytes_little_endian i b 0; {r=b; depth=0} let int8 (i : int8) = let b = Bytes.create 1 in Int8.to_bytes_little_endian i b 0; {r=b; depth=0} let int16 (i : int16) = let b = Bytes.create 2 in Int16.to_bytes_little_endian i b 0; {r=b; depth=0} let int32 (i : int32) = let b = Bytes.create 4 in Int32.to_bytes_little_endian i b 0; {r=b; depth=0} let int64 (i : int64) = let b = Bytes.create 8 in Int64.to_bytes_little_endian i b 0; {r=b; depth=0} let int128 (i : int128) = let b = Bytes.create 16 in Int128.to_bytes_little_endian i b 0; {r=b; depth=0} let option f = function | None -> bool false | Some x -> let r = f x in {r with r=Bytes.concat Bytes.empty [ (bool true).r; r.r ]} let unit () = {r=Bytes.empty; depth=0} let concat l = let depth = list_depth l in {depth; r = Bytes.concat Bytes.empty @@ list_result l} let fixed f a = concat @@ Array.to_list @@ Array.map f a let variable length f l = concat @@ {r=length (List.length l); depth=0} :: (List.rev @@ List.rev_map f l) let string length s = { r = Bytes.concat Bytes.empty [ length (String.length s); Bytes.of_string s ]; depth=0 } let bytes length b = { r = Bytes.concat Bytes.empty [ length (Bytes.length b); b ]; depth = 0 } let map length fk fv m = variable length (fun (k, v) -> concat [ fk k; fv v ]) @@ Map.bindings m