#ifndef SERIALIZE_INTS_HPP_
#define SERIALIZE_INTS_HPP_

#include <Serialize/Base.hpp>
#include <cstdint>

#define DERIVE_INT_SERIALIZER(T) template<> struct SerialCodec<T> : public IntSerialCodec<T> {}

template<typename T>
struct IntSerialCodec
{
    static constexpr void encode(std::vector<uint8_t> &outBytes, const T &obj)
    {
        T value = obj;
        for (size_t i = 0; i < sizeof(T); i++)
        {
            outBytes.push_back(value & 0xFF);
            value >>= 8;
        }
    }

    static constexpr size_t decode(const uint8_t *data, size_t size, T &obj)
    {
        if (size < sizeof(T))
        {
            return 0;
        }
        
        obj = 0;
        for (size_t i = 0; i < sizeof(T); i++)
        {
            obj <<= 8;
            obj |= data[sizeof(T) - i - 1];
        }

        return sizeof(T);
    }
};

DERIVE_INT_SERIALIZER(int8_t);
DERIVE_INT_SERIALIZER(uint8_t);
DERIVE_INT_SERIALIZER(int16_t);
DERIVE_INT_SERIALIZER(uint16_t);
DERIVE_INT_SERIALIZER(int32_t);
DERIVE_INT_SERIALIZER(uint32_t);
DERIVE_INT_SERIALIZER(int64_t);
DERIVE_INT_SERIALIZER(uint64_t);

#endif