buildCompactStruct :: Map.HashMap Int16 (LT.Text, ThriftVal) -> Builder
buildCompactStruct = flip (loop 0) mempty . Map.toList
  where
    loop _ [] acc = acc <> B.word8 (fromTType T_STOP)
    loop lastId ((fid, (_,val)) : fields) acc = loop fid fields $ acc <>
      (if fid > lastId && fid - lastId <= 15
       then B.word8 $ fromIntegral ((fid - lastId) `shiftL` 4) .|. typeOf val
       else B.word8 (typeOf val) <> buildVarint (i16ToZigZag fid)) <>
      (if typeOf val > 0x02 -- Not a T_BOOL
       then buildCompactValue val
       else mempty) -- T_BOOLs are encoded in the type
buildCompactStruct :: Map.HashMap Int16 (LT.Text, ThriftVal) -> Builder
buildCompactStruct = flip (loop 0) mempty . Map.toList
  where
    loop _ [] acc = acc <> B.word8 (fromTType T_STOP)
    loop lastId ((fid, (_,val)) : fields) acc = loop fid fields $ acc <>
      (if fid > lastId && fid - lastId <= 15
       then B.word8 $ fromIntegral ((fid - lastId) `shiftL` 4) .|. typeOf val
       else B.word8 (typeOf val) <> buildVarint (i16ToZigZag fid)) <>
      (if typeOf val > 0x02 -- Not a T_BOOL
       then buildCompactValue val
       else mempty) -- T_BOOLs are encoded in the type
buildCompactStruct = flip (loop 0) mempty . Map.toList
  where
    loop _ [] acc = acc <> B.word8 (fromTType T_STOP)
    loop lastId ((fid, (_,val)) : fields) acc = loop fid fields $ acc <>
      (if fid > lastId && fid - lastId <= 15
       then B.word8 $ fromIntegral ((fid - lastId) `shiftL` 4) .|. typeOf val
       else B.word8 (typeOf val) <> buildVarint (i16ToZigZag fid)) <>
      (if typeOf val > 0x02 -- Not a T_BOOL
       then buildCompactValue val
       else mempty) -- T_BOOLs are encoded in the type