gs-hex/src/main/scala/gs/hex/v0/HexDecode.scala

85 lines
1.9 KiB
Scala

package gs.hex.v0
/** Type Class for decoding hexadecimal strings to some type.
*/
trait HexDecode[A]:
/** Given some hexadecimal string representing encoded data, parse that string
* to reconstruct that data.
*
* @param data
* The encoded hexadecimal string.
* @return
* The decoded data, or nothing if the input is invalid.
*/
def fromHexString(data: String): Option[A]
extension (data: String) def fromHex(): Option[A] = fromHexString(data)
object HexDecode:
/** Retrieve the [[HexDecode]] instance for the given type.
*
* @param H
* The type.
* @return
* The [[HexDecode]] instance for the given type.
*/
def apply[A](
using
H: HexDecode[A]
): HexDecode[A] = H
given HexDecode[Array[Byte]] = new HexDecode[Array[Byte]] {
/** @inheritDoc
*/
def fromHexString(data: String): Option[Array[Byte]] =
Hex.fromHexString(data)
}
given HexDecode[String] = new HexDecode[String] {
/** @inheritDoc
*/
def fromHexString(data: String): Option[String] =
Hex.fromHexString(data).map(bytes => new String(bytes))
}
given HexDecode[Boolean] = new HexDecode[Boolean] {
/** @inheritDoc
*/
def fromHexString(data: String): Option[Boolean] =
if data == "1" then Some(true)
else if data == "0" then Some(false)
else None
}
given HexDecode[Int] = new HexDecode[Int] {
/** @inheritDoc
*/
def fromHexString(data: String): Option[Int] =
Hex.fromHexString(data).flatMap { bytes =>
if bytes.length != 4 then None
else Some(java.nio.ByteBuffer.wrap(bytes).getInt())
}
}
given HexDecode[Long] = new HexDecode[Long] {
/** @inheritDoc
*/
def fromHexString(data: String): Option[Long] =
Hex.fromHexString(data).flatMap { bytes =>
if bytes.length != 8 then None
else Some(java.nio.ByteBuffer.wrap(bytes).getLong())
}
}
end HexDecode