All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.alephium.api.TapirCodecs.scala Maven / Gradle / Ivy

The newest version!
// Copyright 2018 The Alephium Authors
// This file is part of the alephium project.
//
// The library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the library. If not, see .

package org.alephium.api

import scala.util.{Failure, Success, Try}

import sttp.tapir.{Codec, DecodeResult, Schema, Validator}
import sttp.tapir.CodecFormat.TextPlain

import org.alephium.api.model._
import org.alephium.json.Json._
import org.alephium.protocol.{Hash, PublicKey}
import org.alephium.protocol.config.GroupConfig
import org.alephium.protocol.model.{Address, BlockHash, GroupIndex, TransactionId}
import org.alephium.protocol.vm.{GasBox, GasPrice}
import org.alephium.util.{TimeStamp, U256}

trait TapirCodecs extends ApiModelCodec with TapirSchemasLike {

  implicit val timestampTapirCodec: Codec[String, TimeStamp, TextPlain] =
    Codec.long.validate(Validator.min(0L)).map(TimeStamp.unsafe(_))(_.millis)

  implicit val hashTapirCodec: Codec[String, Hash, TextPlain] =
    fromJson[Hash]

  implicit val blockHashTapirCodec: Codec[String, BlockHash, TextPlain] =
    fromJson[BlockHash]

  implicit val transactionIdCodec: Codec[String, TransactionId, TextPlain] =
    fromJson[TransactionId]

  implicit val assetAddressTapirCodec: Codec[String, Address.Asset, TextPlain] =
    fromJson[Address.Asset]

  implicit val contractAddressTapirCodec: Codec[String, Address.Contract, TextPlain] =
    fromJson[Address.Contract]

  implicit val addressTapirCodec: Codec[String, Address, TextPlain] =
    fromJson[Address]

  implicit val apiKeyTapirCodec: Codec[String, ApiKey, TextPlain] =
    fromJson[ApiKey]

  implicit val publicKeyTapirCodec: Codec[String, PublicKey, TextPlain] =
    fromJson[PublicKey]

  implicit val u256TapirCodec: Codec[String, U256, TextPlain] =
    fromJson[U256]

  implicit val gasBoxCodec: Codec[String, GasBox, TextPlain] =
    Codec.int.mapDecode(value =>
      GasBox.from(value) match {
        case Some(gas) => DecodeResult.Value(gas)
        case None => DecodeResult.Error(s"$value", new IllegalArgumentException(s"Invalid gas"))
      }
    )(_.value)

  implicit val gasPriceCodec: Codec[String, GasPrice, TextPlain] =
    u256TapirCodec.map[GasPrice](GasPrice(_))(_.value)

  implicit val minerActionTapirCodec: Codec[String, MinerAction, TextPlain] =
    fromJson[MinerAction]

  implicit val timespanTapirCodec: Codec[String, TimeSpan, TextPlain] =
    Codec.long.validate(Validator.min(1)).map(TimeSpan(_))(_.millis)

  implicit def groupIndexCodec(implicit
      groupConfig: GroupConfig
  ): Codec[String, GroupIndex, TextPlain] =
    Codec.int.mapDecode(int =>
      GroupIndex.from(int) match {
        case Some(groupIndex) => DecodeResult.Value(groupIndex)
        case None =>
          DecodeResult.Error(s"$int", new IllegalArgumentException("Invalid group index"))
      }
    )(_.value)

  def fromJson[A: ReadWriter](implicit schema: Schema[A]): Codec[String, A, TextPlain] =
    Codec.string
      .mapDecode[A] { raw =>
        Try(read[A](ujson.Str(raw))) match {
          case Success(a) => DecodeResult.Value(a)
          case Failure(error) =>
            DecodeResult.Error(raw, new IllegalArgumentException(error.getMessage))
        }
      } { a =>
        writeJs(a) match {
          case ujson.Str(str) => str
          case other          => write(other)
        }
      }
      .schema(schema)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy