io.circe.Decoder Scala Examples
The following examples show how to use io.circe.Decoder.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: Analyzer.scala From scarango with MIT License | 8 votes |
package com.outr.arango import io.circe.Decoder.Result import io.circe.{Decoder, DecodingFailure, Encoder, HCursor, Json} sealed abstract class Analyzer(val name: String) object Analyzer { case object Identity extends Analyzer("identity") case object TextGerman extends Analyzer("text_de") case object TextEnglish extends Analyzer("text_en") case object TextSpanish extends Analyzer("text_es") case object TextFinnish extends Analyzer("text_fi") case object TextFrench extends Analyzer("text_fr") case object TextItalian extends Analyzer("text_it") case object TextDutch extends Analyzer("text_nl") case object TextNorwegian extends Analyzer("text_no") case object TextPortuguese extends Analyzer("text_pt") case object TextRussian extends Analyzer("text_ru") case object TextSwedish extends Analyzer("text_sv") case object TextChinese extends Analyzer("text_zh") private val map = List(Identity, TextGerman, TextEnglish, TextSpanish, TextFinnish, TextFrench, TextItalian, TextDutch, TextNorwegian, TextPortuguese, TextRussian, TextSwedish, TextChinese).map(a => a.name -> a).toMap def apply(name: String): Analyzer = map.getOrElse(name, throw new RuntimeException(s"Unable to find analyzer by name: $name")) implicit val decoder: Decoder[Analyzer] = new Decoder[Analyzer] { override def apply(c: HCursor): Result[Analyzer] = c.value.asString match { case Some(s) => Right(Analyzer(s)) case None => Left(DecodingFailure(s"Expected String to decode Analyzer, but got: ${c.value}", Nil)) } } implicit val encoder: Encoder[Analyzer] = new Encoder[Analyzer] { override def apply(a: Analyzer): Json = Json.fromString(a.name) } }
Example 2
Source File: TopicConfigurationParser.scala From kafka-configurator with BSD 3-Clause "New" or "Revised" License | 6 votes |
package com.sky.kafka.configurator import java.io.{Reader => JReader} import cats.instances.either._ import cats.instances.list._ import cats.syntax.either._ import cats.syntax.traverse._ import io.circe import io.circe.generic.AutoDerivation import io.circe.yaml.parser._ import io.circe.{Decoder, DecodingFailure, Json} import scala.collection.immutable.ListMap object TopicConfigurationParser extends AutoDerivation { def apply(topicConfigReader: JReader): Either[circe.Error, List[Topic]] = for { ymlAsJson <- parse(topicConfigReader) topicConfigs <- if (ymlAsJson.isBoolean) List.empty[Topic].asRight else ymlAsJson.as[List[Topic]] } yield topicConfigs case class TopicConfig(partitions: Int, replication: Int, config: Map[String, String]) implicit val topicsDecoder: Decoder[List[Topic]] = Decoder.instance { cursor => for { configMap <- cursor.as[ListMap[String, TopicConfig]] topics = configMap.map { case (name, conf) => Topic(name, conf.partitions, conf.replication, conf.config) } } yield topics.toList } implicit val stringMapDecoder: Decoder[Map[String, String]] = Decoder.instance { cursor => def stringify(json: Json): Json = json.asNumber.fold(json)(num => Json.fromString(num.toLong.fold(num.toDouble.toString)(_.toString))) def failWithMsg(msg: String) = DecodingFailure(msg, List.empty) for { jsonObj <- cursor.value.asObject.toRight(failWithMsg(s"${cursor.value} is not an object")) valuesAsJsonStrings = jsonObj.mapValues(stringify) stringMap <- valuesAsJsonStrings.toList.traverse[Decoder.Result, (String, String)] { case (key, json) => json.asString.toRight(failWithMsg(s"$json is not a string")).map(key -> _) } } yield stringMap.toMap } }
Example 3
Source File: ScalajHttpClient.scala From telegram with Apache License 2.0 | 6 votes |
package com.bot4s.telegram.clients import java.net.Proxy import java.nio.file.Files import cats.instances.future._ import com.bot4s.telegram.api.RequestHandler import com.bot4s.telegram.methods.{Request, JsonRequest, MultipartRequest, Response} import com.bot4s.telegram.models.InputFile import com.bot4s.telegram.marshalling import io.circe.parser.parse import io.circe.{Decoder, Encoder} import scalaj.http.{Http, MultiPart} import slogging.StrictLogging import scala.concurrent.{ExecutionContext, Future, blocking} class ScalajHttpClient(token: String, proxy: Proxy = Proxy.NO_PROXY, telegramHost: String = "api.telegram.org") (implicit ec: ExecutionContext) extends RequestHandler[Future] with StrictLogging { val connectionTimeoutMs = 10000 val readTimeoutMs = 50000 private val apiBaseUrl = s"https://$telegramHost/bot$token/" def sendRequest[R, T <: Request[_]](request: T)(implicit encT: Encoder[T], decR: Decoder[R]): Future[R] = { val url = apiBaseUrl + request.methodName val scalajRequest = request match { case r: JsonRequest[_] => Http(url) .postData(marshalling.toJson(request)) .header("Content-Type", "application/json") case r: MultipartRequest[_] => // InputFile.FileIds are encoded as query params. val (fileIds, files) = r.getFiles.partition { case (key, _: InputFile.FileId) => true case _ => false } val parts = files.map { case (camelKey, inputFile) => val key = marshalling.snakenize(camelKey) inputFile match { case InputFile.FileId(id) => throw new RuntimeException("InputFile.FileId cannot must be encoded as a query param") case InputFile.Contents(filename, contents) => MultiPart(key, filename, "application/octet-stream", contents) case InputFile.Path(path) => MultiPart(key, path.getFileName.toString(), "application/octet-stream", Files.newInputStream(path), Files.size(path), _ => ()) case other => throw new RuntimeException(s"InputFile $other not supported") } } val fields = parse(marshalling.toJson(request)).fold(throw _, _.asObject.map { _.toMap.mapValues { json => json.asString.getOrElse(marshalling.printer.pretty(json)) } }) val fileIdsParams = fileIds.map { case (key, inputFile: InputFile.FileId) => marshalling.snakenize(key) -> inputFile.fileId } val params = fields.getOrElse(Map()) Http(url).params(params ++ fileIdsParams).postMulti(parts: _*) } import marshalling.responseDecoder Future { blocking { scalajRequest .timeout(connectionTimeoutMs, readTimeoutMs) .proxy(proxy) .asString } } map { x => if (x.isSuccess) marshalling.fromJson[Response[R]](x.body) else throw new RuntimeException(s"Error ${x.code} on request") } map (processApiResponse[R]) } }
Example 4
package jbok.network.http.server.authentication import cats.effect.IO import io.circe.generic.auto._ import io.circe.{Decoder, ObjectEncoder} import tsec.authentication.{AugmentedJWT, JWTAuthenticator, SecuredRequestHandler} import tsec.common.SecureRandomId import tsec.jws.mac.JWTMac import tsec.jwt.JWTClaims import tsec.mac.jca.{HMACSHA256, MacSigningKey} import scala.concurrent.duration._ object JWT { class Unbacked(key: MacSigningKey[HMACSHA256]) { private val userStore = DummyBackingStore.apply[Long, User](_.id) private val authenticator = JWTAuthenticator.unbacked.inBearerToken( expiryDuration = 10.minutes, //Absolute expiration time maxIdle = None, identityStore = userStore, signingKey = key ) val Auth = SecuredRequestHandler(authenticator) } class Stateful(key: MacSigningKey[HMACSHA256]) { private val jwtStore = DummyBackingStore.apply[SecureRandomId, AugmentedJWT[HMACSHA256, Long]](s => SecureRandomId.coerce(s.id)) private val userStore = DummyBackingStore.apply[Long, User](_.id) private val authenticator = JWTAuthenticator.backed.inBearerToken( expiryDuration = 10.minutes, //Absolute expiration time maxIdle = None, tokenStore = jwtStore, identityStore = userStore, signingKey = key ) val Auth = SecuredRequestHandler(authenticator) } class Stateless(key: MacSigningKey[HMACSHA256]) { private val authenticator = JWTAuthenticator.pstateless.inBearerToken[IO, User, HMACSHA256]( expiryDuration = 10.minutes, maxIdle = None, signingKey = key ) val Auth = SecuredRequestHandler(authenticator) } final case class CustomClaim(suchChars: String, much32Bits: Int, so64Bits: Long) val claim = "JBOK" def withCustomClaims[A: ObjectEncoder: Decoder]( key: String, value: A, duration: Option[FiniteDuration] = None ): IO[JWTClaims] = JWTClaims .withDuration[IO](expiration = duration).flatMap(_.withCustomFieldF[IO, A](key, value)) def sign(claims: JWTClaims, key: MacSigningKey[HMACSHA256]): IO[JWTMac[HMACSHA256]] = for { jwt <- JWTMac.build[IO, HMACSHA256](claims, key) //You can sign and build a jwt object directly } yield jwt def signToString(claims: JWTClaims, key: MacSigningKey[HMACSHA256]): IO[String] = sign(claims, key).map(_.toEncodedString) def parseFromString(jwt: String, key: MacSigningKey[HMACSHA256]): IO[JWTMac[HMACSHA256]] = JWTMac.verifyAndParse[IO, HMACSHA256](jwt, key) def verifyFromString(jwt: String, key: MacSigningKey[HMACSHA256]): IO[Boolean] = JWTMac.verifyFromStringBool[IO, HMACSHA256](jwt, key) }
Example 5
Source File: BlockTag.scala From iotchain with MIT License | 5 votes |
package jbok.core.api import io.circe.{Decoder, Encoder} import jbok.common.math.N sealed trait BlockTag object BlockTag { case object latest extends BlockTag final case class Number(value: N) extends BlockTag def apply(number: N): Number = Number(number) def apply(s: String): Number = Number(N(s)) def apply(i: Int): Number = Number(N(i)) def apply(l: Long): Number = Number(N(l)) implicit val encoder: Encoder[BlockTag] = Encoder.encodeString.contramap[BlockTag] { case BlockTag.latest => "latest" case BlockTag.Number(value) => value.toString() } implicit val decoder: Decoder[BlockTag] = Decoder.decodeString.map[BlockTag] { case "latest" => BlockTag.latest case number => BlockTag(number) } }
Example 6
Source File: APIWalTail.scala From scarango with MIT License | 5 votes |
package com.outr.arango.api import io.circe.Decoder.Result import io.youi.client.HttpClient import io.youi.http.{HeaderKey, HttpMethod} import io.youi.net._ import io.circe.{Decoder, DecodingFailure, HCursor} import profig.JsonUtil import scala.concurrent.{ExecutionContext, Future} object APIWalTail { private implicit def operationTypeDecoder: Decoder[OperationType] = new Decoder[OperationType] { override def apply(c: HCursor): Result[OperationType] = c.value.asNumber match { case Some(n) => Right(OperationType(n.toInt.get)) case None => Left(DecodingFailure(s"OperationType not a number: ${c.value}", Nil)) } } def get(client: HttpClient, global: Option[Boolean] = None, from: Option[Long] = None, to: Option[Long] = None, lastScanned: Long = 0L, chunkSize: Option[Long] = None, syncerId: Option[Long] = None, serverId: Option[Long] = None, clientId: Option[String] = None)(implicit ec: ExecutionContext): Future[WALOperations] = { client .method(HttpMethod.Get) .path(path"/_api/wal/tail", append = true) .param[Option[Long]]("from", from, None) .param[Option[Long]]("to", to, None) .param[Long]("lastScanned", lastScanned, 0L) .param[Option[Boolean]]("global", global, None) .param[Option[Long]]("chunkSize", chunkSize, None) .param[Option[Long]]("syncerId", syncerId, None) .param[Option[Long]]("serverId", serverId, None) .param[Option[String]]("clientId", clientId, None) .send() .map { response => val lines = response.content.map(_.asString).getOrElse("").split('\n').toList val operations = lines.map(_.trim).collect { case line if line.nonEmpty => JsonUtil.fromJsonString[WALOperation](line) } val headers = response.headers WALOperations( client = client, global = global, chunkSize = chunkSize, syncerId = syncerId, serverId = serverId, clientId = clientId, checkMore = headers.first(HeaderKey("X-Arango-Replication-Checkmore")).exists(_.toBoolean), fromPresent = headers.first(HeaderKey("X-Arango-Replication-Frompresent")).exists(_.toBoolean), lastIncluded = headers.first(HeaderKey("X-Arango-Replication-Lastincluded")).map(_.toLong).getOrElse(-1L), lastScanned = headers.first(HeaderKey("X-Arango-Replication-Lastscanned")).map(_.toLong).getOrElse(-1L), lastTick = headers.first(HeaderKey("X-Arango-Replication-Lasttick")).map(_.toLong).getOrElse(-1L), operations = operations ) } } }
Example 7
Source File: TransactionStatus.scala From scarango with MIT License | 5 votes |
package com.outr.arango.transaction import io.circe.Decoder.Result import io.circe.{Decoder, DecodingFailure, HCursor} sealed trait TransactionStatus object TransactionStatus { case object Running extends TransactionStatus case object Committed extends TransactionStatus case object Aborted extends TransactionStatus implicit val decoder: Decoder[TransactionStatus] = new Decoder[TransactionStatus] { override def apply(c: HCursor): Result[TransactionStatus] = c.value.asString match { case Some(s) => Right(TransactionStatus(s)) case None => Left(DecodingFailure(s"Failed to decode from ${c.value}", Nil)) } } def apply(value: String): TransactionStatus = value match { case "running" => Running case "committed" => Committed case "aborted" => Aborted } }
Example 8
Source File: Transaction.scala From scarango with MIT License | 5 votes |
package com.outr.arango.transaction import com.outr.arango.Graph import io.circe.Decoder.Result import io.circe.{Decoder, DecodingFailure, HCursor} import scala.concurrent.{ExecutionContext, Future} case class Transaction(id: String, status: TransactionStatus) { private[arango] var graph: Option[Graph] = None def withGraph(option: Option[Graph]): Transaction = { graph = option this } def checkStatus()(implicit ec: ExecutionContext): Future[Transaction] = { val g = graph.getOrElse(throw new RuntimeException("Graph not included!")) g.arangoDatabase.transactionStatus(id).map(_.withGraph(graph)) } def commit()(implicit ec: ExecutionContext): Future[Unit] = { val g = graph.getOrElse(throw new RuntimeException("Graph not included!")) g.arangoDatabase.transactionCommit(id).map { t => t.status match { case TransactionStatus.Running => throw new RuntimeException("Commit failed, transaction still running!") case TransactionStatus.Committed => () case TransactionStatus.Aborted => throw new RuntimeException("Commit failed, transaction aborted!") } } } def abort()(implicit ec: ExecutionContext): Future[Unit] = { val g = graph.getOrElse(throw new RuntimeException("Graph not included!")) g.arangoDatabase.transactionAbort(id).map { t => t.status match { case TransactionStatus.Running => throw new RuntimeException("Abort failed, transaction still running!") case TransactionStatus.Committed => throw new RuntimeException("Abort failed, transaction committed!") case TransactionStatus.Aborted => () } } } }
Example 9
Source File: Serialization.scala From scarango with MIT License | 5 votes |
package com.outr.arango import io.circe.Decoder.Result import io.circe.{Decoder, Encoder, HCursor, Json} import scala.language.experimental.macros case class Serialization[D](private val doc2Json: D => Json, private val json2Doc: Json => D) { final def toJson(document: D): Json = Id.update(doc2Json(document)) final def fromJson(json: Json): D = json2Doc(Id.update(json)) lazy val decoder: Decoder[D] = new Decoder[D] { override def apply(c: HCursor): Result[D] = Right(fromJson(c.value)) } } object Serialization { def auto[D]: Serialization[D] = macro Macros.serializationAuto[D] def create[D](encoder: Encoder[D], decoder: Decoder[D]): Serialization[D] = { val doc2Json = (d: D) => encoder(d) val json2Doc = (json: Json) => decoder.decodeJson(json) match { case Left(df) => throw df case Right(d) => d } Serialization[D](doc2Json, json2Doc) } }
Example 10
package com.outr.arango import io.circe.Decoder.Result import io.circe.{Decoder, Encoder, HCursor, Json} import com.outr.arango.JsonImplicits._ lazy val _id: String = s"$collection/$value" override def compare(that: Id[D]): Int = this._id.compare(that._id) override def toString: String = _id } object Id { private val ExtractorRegex = """(.+)/(.+)""".r implicit def encoder[D]: Encoder[Id[D]] = new Encoder[Id[D]] { override def apply(id: Id[D]): Json = Json.fromString(id._id) } implicit def decoder[D]: Decoder[Id[D]] = new Decoder[Id[D]] { override def apply(c: HCursor): Result[Id[D]] = c.value.asString.get match { case ExtractorRegex(collection, value) => Right(Id[D](value, collection)) } } def parse[D](id: String): Id[D] = id match { case ExtractorRegex(collection, value) => Id[D](value, collection) } def extract[D](json: Json): Id[D] = { val updated = update(json) decoder[D].decodeJson((updated \ "_id").get) match { case Left(df) => throw df case Right(id) => id } } def update(json: Json): Json = { val _key = (json \ "_key").flatMap(_.asString) val _id = (json \ "_id").flatMap(_.asString) val _identity = _id.map(parse[Any]) if (_id.nonEmpty && _key.isEmpty) { json.deepMerge(Json.obj("_key" -> Json.fromString(_identity.get.value))) } else { json } } }
Example 11
Source File: ResourceFileGoldenCodecLaws.scala From circe-golden with Apache License 2.0 | 5 votes |
package io.circe.testing.golden import cats.instances.list._, cats.instances.try_._ import cats.syntax.apply._, cats.syntax.traverse._ import io.circe.{ Decoder, Encoder, Printer } import java.io.{ File, PrintWriter } import org.scalacheck.{ Arbitrary, Gen } import scala.reflect.runtime.universe.TypeTag import scala.util.{ Failure, Try } import scala.util.matching.Regex abstract class ResourceFileGoldenCodecLaws[A]( name: String, resourceRootDir: File, resourcePackage: List[String], val size: Int, count: Int, override protected val printer: Printer ) extends GoldenCodecLaws[A] with ExampleGeneration[A] { private[this] val resourceRootPath: String = "/" + resourcePackage.mkString("/") + "/" private[this] val resourceDir: File = resourcePackage.foldLeft(resourceRootDir) { case (acc, p) => new File(acc, p) } private[this] val GoldenFilePattern: Regex = "^-(.{44})\\.json$".r private[this] lazy val loadGoldenFiles: Try[List[(A, String)]] = Resources.open(resourceRootPath).flatMap { dirSource => val files = dirSource.getLines.flatMap { case fileName if fileName.startsWith(name) => fileName.drop(name.length) match { case GoldenFilePattern(seed) => Some((seed, fileName)) case _ => None } case _ => None }.toList.traverse[Try, (A, String)] { case (seed, name) => val contents = Resources.open(resourceRootPath + name).map { source => val lines = source.getLines.mkString("\n") source.close() lines } (getValueFromBase64Seed(seed), contents).tupled } dirSource.close() // Fail if we don't have either zero golden files or the required number. files.flatMap { values => if (values.size == 0 || values.size == count) files else Failure(new IllegalStateException(s"Expected 0 or $count golden files, got ${values.size}")) } } private[this] def generateGoldenFiles: Try[List[(A, String)]] = generateRandomGoldenExamples(count).traverse { case (seed, value, encoded) => Try { resourceDir.mkdirs() val file = new File(resourceDir, s"$name-${seed.toBase64}.json") val writer = new PrintWriter(file) writer.print(encoded) writer.close() (value, encoded) } } protected lazy val goldenExamples: Try[List[(A, String)]] = loadGoldenFiles.flatMap(fs => if (fs.isEmpty) generateGoldenFiles else loadGoldenFiles) } object ResourceFileGoldenCodecLaws { def apply[A]( name: String, resourceRootDir: File, resourcePackage: List[String], size: Int, count: Int, printer: Printer )(implicit decodeA: Decoder[A], encodeA: Encoder[A], arbitraryA: Arbitrary[A]): GoldenCodecLaws[A] = new ResourceFileGoldenCodecLaws[A](name, resourceRootDir, resourcePackage, size, count, printer) { val decode: Decoder[A] = decodeA val encode: Encoder[A] = encodeA val gen: Gen[A] = arbitraryA.arbitrary } def apply[A]( size: Int = 100, count: Int = 1, printer: Printer = Printer.spaces2 )( implicit decodeA: Decoder[A], encodeA: Encoder[A], arbitraryA: Arbitrary[A], typeTagA: TypeTag[A] ): GoldenCodecLaws[A] = apply[A](Resources.inferName[A], Resources.inferRootDir, Resources.inferPackage[A], size, count, printer) }
Example 12
Source File: GoldenCodecTests.scala From circe-golden with Apache License 2.0 | 5 votes |
package io.circe.testing.golden import cats.instances.string._ import cats.kernel.Eq import cats.laws.IsEq import cats.laws.discipline.catsLawsIsEqToProp import io.circe.{ Decoder, Encoder, Json, Printer } import io.circe.testing.CodecTests import org.scalacheck.{ Arbitrary, Prop, Shrink } import scala.reflect.runtime.universe.TypeTag import scala.util.{ Failure, Success, Try } trait GoldenCodecTests[A] extends CodecTests[A] { def laws: GoldenCodecLaws[A] private[this] def tryListToProp[A: Eq](result: Try[List[IsEq[A]]]): Prop = result match { case Failure(error) => Prop.exception(error) case Success(equalities) => Prop.all(equalities.map(catsLawsIsEqToProp(_)): _*) } def goldenCodec( implicit arbitraryA: Arbitrary[A], shrinkA: Shrink[A], eqA: Eq[A], arbitraryJson: Arbitrary[Json], shrinkJson: Shrink[Json] ): RuleSet = new DefaultRuleSet( name = "goldenCodec", parent = Some(codec), "decoding golden files" -> tryListToProp(laws.goldenDecoding), "encoding golden files" -> tryListToProp(laws.goldenEncoding) ) def unserializableGoldenCodec( implicit arbitraryA: Arbitrary[A], shrinkA: Shrink[A], eqA: Eq[A], arbitraryJson: Arbitrary[Json], shrinkJson: Shrink[Json] ): RuleSet = new DefaultRuleSet( name = "goldenCodec", parent = Some(unserializableCodec), "decoding golden files" -> tryListToProp(laws.goldenDecoding), "encoding golden files" -> tryListToProp(laws.goldenEncoding) ) } object GoldenCodecTests { def apply[A: Decoder: Encoder: Arbitrary: TypeTag]: GoldenCodecTests[A] = apply[A](ResourceFileGoldenCodecLaws[A]()) def apply[A: Decoder: Encoder: Arbitrary: TypeTag](printer: Printer): GoldenCodecTests[A] = apply[A](ResourceFileGoldenCodecLaws[A](printer = printer)) def apply[A: Decoder: Encoder: Arbitrary: TypeTag](count: Int): GoldenCodecTests[A] = apply[A](ResourceFileGoldenCodecLaws[A](count = count)) def apply[A: Decoder: Encoder: Arbitrary: TypeTag](count: Int, printer: Printer): GoldenCodecTests[A] = apply[A](ResourceFileGoldenCodecLaws[A](count = count, printer = printer)) def apply[A: Decoder: Encoder: Arbitrary](laws0: GoldenCodecLaws[A]): GoldenCodecTests[A] = new GoldenCodecTests[A] { val laws: GoldenCodecLaws[A] = laws0 } }
Example 13
Source File: PaginationLinks.scala From kanadi with MIT License | 5 votes |
package org.zalando.kanadi package models import io.circe.{Decoder, Encoder} final case class PaginationLinks(prev: Option[PaginationLink], next: Option[PaginationLink]) object PaginationLinks { implicit val paginationLinksEncoder: Encoder[PaginationLinks] = Encoder.forProduct2( "prev", "next" )(x => PaginationLinks.unapply(x).get) implicit val paginationLinksDecoder: Decoder[PaginationLinks] = Decoder.forProduct2( "prev", "next" )(PaginationLinks.apply) }
Example 14
Source File: BasicServerError.scala From kanadi with MIT License | 5 votes |
package org.zalando.kanadi.models import io.circe.{Decoder, Encoder} final case class BasicServerError(error: String, errorDescription: String) object BasicServerError { implicit val basicServerErrorEncoder: Encoder[BasicServerError] = Encoder.forProduct2( "error", "error_description" )(x => BasicServerError.unapply(x).get) implicit val basicServerErrorDecoder: Decoder[BasicServerError] = Decoder.forProduct2( "error", "error_description" )(BasicServerError.apply) }
Example 15
Source File: package.scala From kanadi with MIT License | 5 votes |
package org.zalando import java.net.URI import cats.syntax.either._ import io.circe.Decoder.Result import io.circe.syntax._ import io.circe.{Decoder, DecodingFailure, Encoder, HCursor} import scala.util.control.NonFatal package object kanadi { private[kanadi] implicit val uriEncoder: Encoder[URI] = Encoder.instance[URI](_.toString.asJson) private[kanadi] implicit val uriDecoder: Decoder[URI] = new Decoder[URI] { override def apply(c: HCursor): Result[URI] = c.as[String].flatMap { value => try { Right(new URI(value)) } catch { case NonFatal(_) => Left(DecodingFailure("Invalid Uri", c.history)) } } } }
Example 16
Source File: SomeEvent.scala From kanadi with MIT License | 5 votes |
package org.zalando.kanadi import java.util.UUID import io.circe.{Decoder, Encoder} case class SomeEvent(firstName: String, lastName: String, uuid: UUID) object SomeEvent { implicit val someEventEncoder: Encoder[SomeEvent] = Encoder.forProduct3( "first_name", "last_name", "uuid" )(x => SomeEvent.unapply(x).get) implicit val someEventDecoder: Decoder[SomeEvent] = Decoder.forProduct3( "first_name", "last_name", "uuid" )(SomeEvent.apply) }
Example 17
Source File: SymmetricSerializationLaws.scala From circe-yaml with Apache License 2.0 | 5 votes |
package io.circe.yaml import cats.Eq import cats.instances.either._ import cats.laws._ import cats.laws.discipline._ import io.circe.{ Decoder, Encoder, Json, ParsingFailure } import org.scalacheck.{ Arbitrary, Prop, Shrink } import org.typelevel.discipline.Laws trait SymmetricSerializationLaws { def printerRoundTrip[A: Eq: Encoder: Decoder]( parse: String => Either[ParsingFailure, Json], print: Json => String, a: A ): IsEq[Either[io.circe.Error, A]] = parse(print(Encoder[A].apply(a))).right.flatMap(_.as[A]) <-> Right(a) } object SymmetricSerializationLaws { def apply(): SymmetricSerializationLaws = new SymmetricSerializationLaws {} } trait SymmetricSerializationTests extends Laws { def laws: SymmetricSerializationLaws def symmetricPrinter[A: Eq: Arbitrary: Shrink: Encoder: Decoder]( print: Json => String, parse: String => Either[ParsingFailure, Json] ): RuleSet = new DefaultRuleSet( name = "printer", parent = None, "roundTrip" -> Prop.forAll { (a: A) => laws.printerRoundTrip(parse, print, a) } ) } object SymmetricSerializationTests { def apply[A: Eq: Arbitrary: Decoder: Encoder]( print: Json => String, parse: String => Either[ParsingFailure, Json] ): SymmetricSerializationTests = new SymmetricSerializationTests { val laws: SymmetricSerializationLaws = SymmetricSerializationLaws() symmetricPrinter[A](print, parse) } }
Example 18
Source File: CirceJSONSerializer.scala From scala-json-rpc with MIT License | 5 votes |
package io.github.shogowada.scala.jsonrpc.serializers import io.circe.{Decoder, Encoder, Error, Json} import scala.language.experimental.macros import scala.reflect.macros.blackbox object CirceJSONCoder { def encode[T](value: T)(implicit encoder: Encoder[T]): Json = { encoder(value) } def decode[T](json: String)(implicit decoder: Decoder[T]): Either[Error, T] = { io.circe.parser.decode[T](json) } } class CirceJSONSerializer extends JSONSerializer { override def serialize[T](value: T): Option[String] = macro CirceJSONSerializerMacro.serialize[T] override def deserialize[T](json: String): Option[T] = macro CirceJSONSerializerMacro.deserialize[T] } object CirceJSONSerializer { def apply(): CirceJSONSerializer = { new CirceJSONSerializer } } object CirceJSONSerializerMacro { def serialize[T](c: blackbox.Context)(value: c.Expr[T]): c.Expr[Option[String]] = { import c.universe._ c.Expr[Option[String]]( q""" { import io.circe.generic.auto._ scala.util.Try(io.circe.Printer.noSpaces.pretty(io.github.shogowada.scala.jsonrpc.serializers.CirceJSONCoder.encode($value))).toOption } """ ) } def deserialize[T: c.WeakTypeTag](c: blackbox.Context)(json: c.Expr[String]): c.Expr[Option[T]] = { import c.universe._ val deserializeType = weakTypeOf[T] c.Expr[Option[T]]( q""" { import io.circe.generic.auto._ io.github.shogowada.scala.jsonrpc.serializers.CirceJSONCoder.decode[$deserializeType]($json).toOption } """ ) } }
Example 19
Source File: circe.scala From sup with Apache License 2.0 | 5 votes |
package sup.modules import io.circe.Decoder import io.circe.Encoder import sup.data.Report import sup.data.Tagged import sup.Health import sup.HealthResult object circe { implicit val healthCirceEncoder: Encoder[Health] = Encoder[String].contramap(_.toString) implicit val healthCirceDecoder: Decoder[Health] = Decoder[String].emap(s => Health.fromString(s).toRight(s"$s is not a valid ${Health.getClass.getName}")) implicit def taggedCirceEncoder[Tag: Encoder, H: Encoder]: Encoder[Tagged[Tag, H]] = Encoder.forProduct2("tag", "health")(tagged => (tagged.tag, tagged.health)) implicit def taggedCirceDecoder[Tag: Decoder, H: Decoder]: Decoder[Tagged[Tag, H]] = Decoder.forProduct2("tag", "health")(Tagged.apply) implicit def reportCirceEncoder[G[_], H[_], A: Encoder](implicit H: Encoder[G[H[A]]]): Encoder[Report[G, H, A]] = Encoder.forProduct2("health", "checks")(report => (report.health, report.checks)) implicit def reportCirceDecoder[G[_], H[_], A: Decoder](implicit H: Decoder[G[H[A]]]): Decoder[Report[G, H, A]] = Decoder.forProduct2("health", "checks")(Report.apply) implicit def healthResultCirceEncoder[H[_]](implicit E: Encoder[H[Health]]): Encoder[HealthResult[H]] = E.contramap(_.value) implicit def healthResultCirceDecoder[H[_]](implicit D: Decoder[H[Health]]): Decoder[HealthResult[H]] = D.map(HealthResult(_)) }
Example 20
Source File: ModelSet.scala From seals with Apache License 2.0 | 5 votes |
package dev.tauri.seals package checker import io.circe.{ Encoder, Decoder } import circe.Codecs final case class ModelSet(models: Map[String, Map[String, Model]]) final object ModelSet { implicit val encoderInstance: Encoder[ModelSet] = { // Note: we're explicitly only using `Reified` for decoding `Model`, // otherwise we want the default behavior of circe. implicit val mEnc: Encoder[Model] = Codecs.encoderFromReified[Model] Encoder[Map[String, Map[String, Model]]].contramap(_.models) } implicit val decoderInstance: Decoder[ModelSet] = { // Note: we're explicitly only using `Reified` for encoding `Model`, // otherwise we want the default behavior of circe. implicit val mDec: Decoder[Model] = Codecs.decoderFromReified[Model] Decoder[Map[String, Map[String, Model]]].map(ModelSet(_)) } }
Example 21
Source File: ExtractorSpec.scala From seals with Apache License 2.0 | 5 votes |
package dev.tauri.seals package checker import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import io.circe.Decoder import circe.Codecs._ class ExtractorSpec extends AnyFlatSpec with Matchers { val decoder = Decoder[Model] val pack = this.getClass.getPackage.getName val fooName = s"$pack.Foo" val ccName = s"$pack.CC" val wfooName = s"$pack.Wrap.WFoo" val wccName = s"$pack.Wrap.WCC" // force WFoo subclasses (SI-7046 workaround): def dummy1: Wrap.Bar = sys.error("dummy1") def dummy2: Wrap.Baz.type = sys.error("dummy2") val extractor = Extractor( this.getClass.getClassLoader, new java.io.File(this.getClass.getProtectionDomain.getCodeSource.getLocation.toURI) ) "Extractor#allClasses" should "find every class" in { extractor.allClasses(pack) should contain allOf ( "Foo", "Foo$", "CC", "CC$", "Wrap$" ) } "Extractor#extractAll" should "find all marked classes in a package" in { val models: Map[String, Model] = extractor.extractAll(pack) val expected = Map( fooName -> Foo.reifiedFoo.model, ccName -> CC.reifiedCC.model, wfooName -> Wrap.WFoo.reifiedWFoo.model, wccName -> Wrap.WCC.reifiedWCC.model ) models should === (expected) } "Extractor#allSchemas" should "collect all annotated classes" in { extractor.allSchemasOfPackage(pack).map(_.fullName).toSet should === (Set( fooName, ccName, wfooName, wccName )) } }
Example 22
Source File: CirceSerdes.scala From kafka-streams-circe with Apache License 2.0 | 5 votes |
package com.goyeau.kafka.streams.circe import java.nio.charset.StandardCharsets import java.util import io.circe.parser._ import io.circe.{Decoder, Encoder} import org.apache.kafka.common.errors.SerializationException import org.apache.kafka.common.serialization.{Deserializer, Serde, Serdes, Serializer} object CirceSerdes { implicit def serializer[T: Encoder]: Serializer[T] = new Serializer[T] { override def configure(configs: util.Map[String, _], isKey: Boolean): Unit = () override def serialize(topic: String, caseClass: T): Array[Byte] = Encoder[T].apply(caseClass).noSpaces.getBytes(StandardCharsets.UTF_8) override def close(): Unit = () } implicit def deserializer[T: Decoder]: Deserializer[T] = new Deserializer[T] { override def configure(configs: util.Map[String, _], isKey: Boolean): Unit = () override def deserialize(topic: String, data: Array[Byte]): T = Option(data).fold(null.asInstanceOf[T]) { data => decode[T](new String(data, StandardCharsets.UTF_8)) .fold(error => throw new SerializationException(error), identity) } override def close(): Unit = () } implicit def serde[CC: Encoder: Decoder]: Serde[CC] = Serdes.serdeFrom(serializer, deserializer) }
Example 23
Source File: StatelessJWTAuth.scala From tsec with MIT License | 5 votes |
package tsec.authentication.internal import java.time.Instant import cats.data.OptionT import cats.effect.Sync import cats.syntax.all._ import io.circe.syntax._ import io.circe.{Decoder, Encoder} import org.http4s._ import tsec.authentication._ import tsec.common._ import tsec.jws.mac._ import tsec.jwt.algorithms.JWTMacAlgo import tsec.jwt.JWTClaims import tsec.mac.MAC import tsec.mac.jca._ import scala.concurrent.duration._ private[tsec] abstract class StatelessJWTAuth[F[_], V: Decoder: Encoder.AsObject, A: JWTMacAlgo]( val expiry: FiniteDuration, val maxIdle: Option[FiniteDuration], signingKey: MacSigningKey[A] )(implicit F: Sync[F], cv: JWSMacCV[F, A]) extends JWTAuthenticator[F, V, V, A] { private[tsec] def verifyLastTouched(body: JWTMac[A], now: Instant): F[Option[Instant]] def parseRaw(raw: String, request: Request[F]): OptionT[F, SecuredRequest[F, V, AugmentedJWT[A, V]]] = OptionT( (for { now <- F.delay(Instant.now()) extracted <- cv.verifyAndParse(raw, signingKey, now) jwtid <- cataOption(extracted.id) body <- extracted.body.asF[F, V] expiry <- cataOption(extracted.body.expiration) lastTouched <- verifyLastTouched(extracted, now) augmented = AugmentedJWT( SecureRandomId.coerce(jwtid), extracted, body, expiry, lastTouched ) refreshed <- refresh(augmented) } yield SecuredRequest(request, body, refreshed).some) .handleError(_ => None) ) def create(body: V): F[AugmentedJWT[A, V]] = for { now <- F.delay(Instant.now()) jwtId <- SecureRandomId.Interactive.generateF[F] expiryTime = now.plusSeconds(expiry.toSeconds) lastTouched = touch(now) claims = JWTClaims( issuedAt = touch(now), jwtId = Some(jwtId), expiration = Some(expiryTime), customFields = body.asJsonObject.toList ) out <- JWTMac.build[F, A](claims, signingKey) } yield AugmentedJWT(jwtId, out, body, expiryTime, lastTouched) def update(authenticator: AugmentedJWT[A, V]): F[AugmentedJWT[A, V]] = F.pure(authenticator) def renew(authenticator: AugmentedJWT[A, V]): F[AugmentedJWT[A, V]] = for { now <- F.delay(Instant.now()) updatedExpiry = now.plusSeconds(expiry.toSeconds) authBody = authenticator.jwt.body lastTouched = touch(now) jwt <- JWTMac.build( authBody.withIATOption(lastTouched).withExpiry(updatedExpiry), signingKey ) } yield AugmentedJWT(authenticator.id, jwt, authenticator.identity, updatedExpiry, lastTouched) def discard(authenticator: AugmentedJWT[A, V]): F[AugmentedJWT[A, V]] = F.pure(authenticator.copy(jwt = JWTMac.buildToken[A](JWSMacHeader[A], JWTClaims(), MAC[A](Array.empty[Byte])))) def afterBlock(response: Response[F], authenticator: AugmentedJWT[A, V]): OptionT[F, Response[F]] = OptionT.pure[F](embed(response, authenticator)) }
Example 24
Source File: PartialStatelessJWTAuth.scala From tsec with MIT License | 5 votes |
package tsec.authentication.internal import java.time.Instant import cats.data.OptionT import cats.effect.Sync import cats.syntax.all._ import io.circe.parser.decode import io.circe.syntax._ import io.circe.{Decoder, Encoder} import org.http4s._ import tsec.authentication._ import tsec.common._ import tsec.jws.mac._ import tsec.jwt.algorithms.JWTMacAlgo import tsec.jwt.{JWTClaims, JWTPrinter} import tsec.mac.jca._ import scala.concurrent.duration._ def discard(authenticator: AugmentedJWT[A, I]): F[AugmentedJWT[A, I]] = for { now <- F.delay(Instant.now) jwt <- JWTMac .build[F, A]( authenticator.jwt.body .withExpiry(now) .withJwtID(SecureRandomId.Interactive.generate), signingKey ) } yield AugmentedJWT(authenticator.id, jwt, authenticator.identity, now, authenticator.lastTouched) }
Example 25
Source File: package.scala From tsec with MIT License | 5 votes |
package tsec import cats.{Eq, MonadError} import cats.instances.string._ import cats.syntax.either._ import io.circe.{Decoder, Encoder, HCursor, Json} import tsec.cipher.common.padding.NoPadding import tsec.cipher.symmetric._ import tsec.cipher.symmetric.jca._ import tsec.common._ import tsec.mac.MAC import tsec.mac.jca.MacVerificationError package object cookies { type AEADCookie[A] = AEADCookie.Cookie[A] implicit object AEADCookie { type Cookie[A] <: String @inline def fromEncrypted[A](a: CipherText[A], aad: AAD): AEADCookie[A] = apply[A](a.toConcatenated.toB64String + "-" + aad.toB64String) @inline def subst[G[_], A](fa: G[String]): G[AEADCookie[A]] = fa.asInstanceOf[G[AEADCookie[A]]] @inline def unsubst[G[_], A](fa: G[AEADCookie[A]]): G[String] = fa.asInstanceOf[G[String]] @inline def apply[A](raw: String): AEADCookie[A] = raw.asInstanceOf[AEADCookie[A]] def getEncryptedContent[F[_], A: AES]( signed: AEADCookie[A] )(implicit encryptor: AADEncryptor[F, A, SecretKey]): Either[CipherTextError, CipherText[A]] = { val split = signed.split("-") if (split.length != 2) Left(CipherTextError("String encoded improperly")) else { split(0).b64Bytes match { case Some(e) => CTOPS.ciphertextFromArray[A, GCM, NoPadding](e) case None => Left(CipherTextError("String encoded improperly")) } } } implicit def circeDecoder[A]: Decoder[AEADCookie[A]] = new Decoder[AEADCookie[A]] { def apply(c: HCursor) = c.as[String].map(AEADCookie.apply[A]) } implicit def circeEncoder[A]: Encoder[AEADCookie[A]] = new Encoder[AEADCookie[A]] { def apply(a: AEADCookie[A]): Json = Json.fromString(a) } } type SignedCookie[A] = SignedCookie.Cookie[A] implicit object SignedCookie { type Cookie[A] <: String @inline def from[A](signed: MAC[A], joined: String): SignedCookie[A] = apply[A](joined + "-" + signed.toB64String) @inline def apply[A](raw: String): SignedCookie[A] = raw.asInstanceOf[SignedCookie[A]] @inline def subst[G[_], A](fa: G[String]): G[SignedCookie[A]] = fa.asInstanceOf[G[SignedCookie[A]]] @inline def unsubst[G[_], A](fa: G[SignedCookie[A]]): G[String] = fa.asInstanceOf[G[String]] def fromDecodedString[F[_]](original: String)(implicit F: MonadError[F, Throwable]): F[String] = original.split("-") match { case Array(orig, nonce) => orig.b64Bytes match { case Some(o) => F.pure(o.toUtf8String) case None => F.raiseError(MacVerificationError("String encoded improperly")) } case _ => F.raiseError(MacVerificationError("String encoded improperly")) } } implicit final def cookieEQ[A]: Eq[SignedCookie[A]] = SignedCookie.subst(Eq[String]) implicit final def ecookieEQ[A]: Eq[AEADCookie[A]] = Eq.by[AEADCookie[A], String](identity[String]) }
Example 26
Source File: Error.scala From akka-http-oauth2-client with Apache License 2.0 | 5 votes |
package com.github.dakatsuka.akka.http.oauth2.client import akka.http.scaladsl.model.HttpResponse import akka.http.scaladsl.unmarshalling.Unmarshal import akka.stream.Materializer import com.github.dakatsuka.akka.http.oauth2.client.utils.JsonUnmarshaller import io.circe.Decoder import scala.concurrent.{ ExecutionContext, Future } object Error { sealed abstract class Code(val value: String) case object InvalidRequest extends Code("invalid_request") case object InvalidClient extends Code("invalid_client") case object InvalidToken extends Code("invalid_token") case object InvalidGrant extends Code("invalid_grant") case object InvalidScope extends Code("invalid_scope") case object UnsupportedGrantType extends Code("unsupported_grant_type") case object Unknown extends Code("unknown") object Code { def fromString(code: String): Code = code match { case "invalid_request" => InvalidRequest case "invalid_client" => InvalidClient case "invalid_token" => InvalidToken case "invalid_grant" => InvalidGrant case "invalid_scope" => InvalidScope case "unsupported_grant_type" => UnsupportedGrantType case _ => Unknown } } class UnauthorizedException(val code: Code, val description: String, val response: HttpResponse) extends RuntimeException(s"$code: $description") object UnauthorizedException extends JsonUnmarshaller { case class UnauthorizedResponse(error: String, errorDescription: String) implicit def decoder: Decoder[UnauthorizedResponse] = Decoder.instance { c => for { error <- c.downField("error").as[String].right description <- c.downField("error_description").as[String].right } yield UnauthorizedResponse(error, description) } def fromHttpResponse(response: HttpResponse)(implicit ec: ExecutionContext, mat: Materializer): Future[UnauthorizedException] = { Unmarshal(response).to[UnauthorizedResponse].map { r => new UnauthorizedException(Code.fromString(r.error), r.errorDescription, response) } } } }
Example 27
Source File: JsonUnmarshaller.scala From akka-http-oauth2-client with Apache License 2.0 | 5 votes |
package com.github.dakatsuka.akka.http.oauth2.client.utils import akka.http.scaladsl.model.ContentTypeRange import akka.http.scaladsl.model.MediaTypes.`application/json` import akka.http.scaladsl.unmarshalling.{ FromEntityUnmarshaller, Unmarshaller } import akka.util.ByteString import io.circe.{ jawn, Decoder, Json } trait JsonUnmarshaller { def unmarshallerContentTypes: Seq[ContentTypeRange] = List(`application/json`) implicit def jsonUnmarshaller: FromEntityUnmarshaller[Json] = Unmarshaller.byteStringUnmarshaller .forContentTypes(unmarshallerContentTypes: _*) .map { case ByteString.empty => throw Unmarshaller.NoContentException case data => jawn.parseByteBuffer(data.asByteBuffer).fold(throw _, identity) } implicit def unmarshaller[A: Decoder]: FromEntityUnmarshaller[A] = { def decode(json: Json) = implicitly[Decoder[A]].decodeJson(json).fold(throw _, identity) jsonUnmarshaller.map(decode) } }
Example 28
Source File: AccessToken.scala From akka-http-oauth2-client with Apache License 2.0 | 5 votes |
package com.github.dakatsuka.akka.http.oauth2.client import akka.http.scaladsl.model.HttpResponse import akka.http.scaladsl.unmarshalling.Unmarshal import akka.stream.Materializer import com.github.dakatsuka.akka.http.oauth2.client.utils.JsonUnmarshaller import io.circe.Decoder import scala.concurrent.Future case class AccessToken( accessToken: String, tokenType: String, expiresIn: Int, refreshToken: Option[String] ) object AccessToken extends JsonUnmarshaller { implicit def decoder: Decoder[AccessToken] = Decoder.instance { c => for { accessToken <- c.downField("access_token").as[String].right tokenType <- c.downField("token_type").as[String].right expiresIn <- c.downField("expires_in").as[Int].right refreshToken <- c.downField("refresh_token").as[Option[String]].right } yield AccessToken(accessToken, tokenType, expiresIn, refreshToken) } def apply(response: HttpResponse)(implicit mat: Materializer): Future[AccessToken] = { Unmarshal(response).to[AccessToken] } }
Example 29
Source File: TestSuiteTests.scala From circe-json-schema with Apache License 2.0 | 5 votes |
package io.circe.schema import cats.data.Validated import io.circe.{ Decoder, Json } import java.io.File import org.scalatest.flatspec.AnyFlatSpec case class SchemaTestCase(description: String, data: Json, valid: Boolean) case class SchemaTest(description: String, schema: Json, tests: List[SchemaTestCase]) object SchemaTestCase { implicit val decodeSchemaTestCase: Decoder[SchemaTestCase] = io.circe.generic.semiauto.deriveDecoder } object SchemaTest { implicit val decodeSchemaTest: Decoder[SchemaTest] = io.circe.generic.semiauto.deriveDecoder } class TestSuiteTests(path: String) extends AnyFlatSpec { val tests: List[SchemaTest] = io.circe.jawn .decodeFile[List[SchemaTest]](new File(path)) .getOrElse( throw new Exception(s"Unable to load test file: $path") ) tests.foreach { case SchemaTest(description, schema, tests) => tests.foreach { case SchemaTestCase(caseDescription, data, valid) => val expected = if (valid) "validate successfully" else "fail to validate" s"$description: $caseDescription" should expected in { val errors = Schema.load(schema).validate(data) if (valid) { assert(errors == Validated.valid(())) } else { assert(errors.isInvalid) } } it should s"$expected when schema is loaded from a string" in { val errors = Schema.loadFromString(schema.noSpaces).get.validate(data) if (valid) { assert(errors == Validated.valid(())) } else { assert(errors.isInvalid) } } } } } class AdditionalItemsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/additionalItems.json") class AdditionalPropertiesTestSuiteTests extends TestSuiteTests("tests/tests/draft7/additionalProperties.json") class AllOfTestSuiteTests extends TestSuiteTests("tests/tests/draft7/allOf.json") class AnyOfTestSuiteTests extends TestSuiteTests("tests/tests/draft7/anyOf.json") class BooleanSchemaTestSuiteTests extends TestSuiteTests("tests/tests/draft7/boolean_schema.json") class ConstTestSuiteTests extends TestSuiteTests("tests/tests/draft7/const.json") class ContainsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/contains.json") class DefaultTestSuiteTests extends TestSuiteTests("tests/tests/draft7/default.json") //class DefinitionsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/definitions.json") class EnumTestSuiteTests extends TestSuiteTests("tests/tests/draft7/enum.json") class ExclusiveMaximumTestSuiteTests extends TestSuiteTests("tests/tests/draft7/exclusiveMaximum.json") class ExclusiveMinimumTestSuiteTests extends TestSuiteTests("tests/tests/draft7/exclusiveMinimum.json") class FormatTestSuiteTests extends TestSuiteTests("tests/tests/draft7/format.json") class IfThenElseTestSuiteTests extends TestSuiteTests("tests/tests/draft7/if-then-else.json") class ItemsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/items.json") class MaximumTestSuiteTests extends TestSuiteTests("tests/tests/draft7/maximum.json") class MaxItemsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/maxItems.json") class MaxLengthTestSuiteTests extends TestSuiteTests("tests/tests/draft7/maxLength.json") class MaxPropertiesTestSuiteTests extends TestSuiteTests("tests/tests/draft7/maxProperties.json") class MinimumTestSuiteTests extends TestSuiteTests("tests/tests/draft7/minimum.json") class MinItemsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/minItems.json") class MinLengthTestSuiteTests extends TestSuiteTests("tests/tests/draft7/minLength.json") class MinPropertiesTestSuiteTests extends TestSuiteTests("tests/tests/draft7/minProperties.json") class MultipleOfTestSuiteTests extends TestSuiteTests("tests/tests/draft7/multipleOf.json") class NotTestSuiteTests extends TestSuiteTests("tests/tests/draft7/not.json") class OneOfTestSuiteTests extends TestSuiteTests("tests/tests/draft7/oneOf.json") class PatternTestSuiteTests extends TestSuiteTests("tests/tests/draft7/pattern.json") class PatternPropertiesTestSuiteTests extends TestSuiteTests("tests/tests/draft7/patternProperties.json") class PropertyNamesTestSuiteTests extends TestSuiteTests("tests/tests/draft7/propertyNames.json") // Not currently running remote tests. //class RefTestSuiteTests extends TestSuiteTests("tests/tests/draft7/ref.json") //class RefRemoteTestSuiteTests extends TestSuiteTests("tests/tests/draft7/refRemote.json") class RequiredTestSuiteTests extends TestSuiteTests("tests/tests/draft7/required.json") class TypeTestSuiteTests extends TestSuiteTests("tests/tests/draft7/type.json") class UniqueItemsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/uniqueItems.json")
Example 30
Source File: ParseOpenApi.scala From skeuomorph with Apache License 2.0 | 5 votes |
package higherkindness.skeuomorph.openapi import java.io.File import higherkindness.droste._ import higherkindness.skeuomorph.Parser import schema.OpenApi import cats.effect.Sync import cats.syntax.flatMap._ import cats.syntax.functor._ import cats.syntax.either._ object ParseOpenApi { import JsonDecoders._ case class YamlSource(file: File) case class JsonSource(file: File) implicit def parseYamlOpenApi[F[_], T](implicit T: Embed[JsonSchemaF, T]): Parser[F, YamlSource, OpenApi[T]] = new Parser[F, YamlSource, OpenApi[T]] { import yaml.{Decoder => _, _} override def parse(input: YamlSource)(implicit S: Sync[F]): F[OpenApi[T]] = readContent(input.file).flatMap(x => S.fromEither( yaml .Decoder[OpenApi[T]] .apply(x) .left .map(_.valueOr(identity)) ) ) } implicit def parseJsonOpenApi[F[_], T](implicit T: Embed[JsonSchemaF, T]): Parser[F, JsonSource, OpenApi[T]] = new Parser[F, JsonSource, OpenApi[T]] { import io.circe.Decoder import io.circe.parser override def parse(input: JsonSource)(implicit S: Sync[F]): F[OpenApi[T]] = for { content <- readContent(input.file) json <- S.fromEither(parser.parse(content)) openApi <- S.fromEither(Decoder[OpenApi[T]].decodeJson(json)) } yield openApi } private def readContent[F[_]: Sync](file: File): F[String] = Sync[F].delay { scala.io.Source .fromFile(file) .getLines() .toList .mkString("\n") } }
Example 31
Source File: CodacyConfigurationFile.scala From codacy-analysis-cli with GNU Affero General Public License v3.0 | 5 votes |
package com.codacy.analysis.core.configuration import better.files.File import cats.syntax.show._ import com.codacy.analysis.core.files.Glob import com.codacy.plugins.api.languages.{Language, Languages} import io.circe.generic.auto._ import io.circe.yaml.parser import io.circe.{Decoder, Json, _} import play.api.libs.json.JsValue import scala.util.{Properties, Try} final case class LanguageConfiguration(extensions: Option[Set[String]]) final case class EngineConfiguration(excludePaths: Option[Set[Glob]], baseSubDir: Option[String], extraValues: Option[Map[String, JsValue]]) final case class CodacyConfigurationFile(engines: Option[Map[String, EngineConfiguration]], excludePaths: Option[Set[Glob]], languages: Option[Map[Language, LanguageConfiguration]]) { lazy val languageCustomExtensions: Map[Language, Set[String]] = languages.fold(Map.empty[Language, Set[String]])(_.map { case (lang, config) => (lang, config.extensions.getOrElse(Set.empty[String])) }) } class CodacyConfigurationFileLoader { val filenames: Set[String] = Set(".codacy.yaml", ".codacy.yml") def load(directory: File): Either[String, CodacyConfigurationFile] = { search(directory).flatMap(configDir => parse(configDir.contentAsString)) } def search(root: File): Either[String, File] = { filenames .map(root / _) .find(f => f.exists && f.isRegularFile) .fold[Either[String, File]]( Left(s"Could not find Codacy configuration file. Make sure you have a file named like one of ${filenames .mkString(", ")}."))(Right(_)) } def parse(yamlString: String): Either[String, CodacyConfigurationFile] = { for { json <- parser.parse(yamlString).left.map(_.show) cursor = HCursor.fromJson(json) configurationEither = Decoder[CodacyConfigurationFile].decodeAccumulating(cursor).toEither configuration <- configurationEither.left.map(_.toList.map(_.show).mkString(Properties.lineSeparator)) } yield configuration } } object CodacyConfigurationFile { implicit val globDecoder: Decoder[Glob] = (c: HCursor) => c.as[String].map(Glob) implicit val languageKeyDecoder: KeyDecoder[Language] = (languageStr: String) => Languages.fromName(languageStr) implicit val decodeEngineConfiguration: Decoder[EngineConfiguration] = new Decoder[EngineConfiguration] { val engineConfigurationKeys = Set("enabled", "exclude_paths", "base_sub_dir") def apply(c: HCursor): Decoder.Result[EngineConfiguration] = { val extraKeys = c.keys.fold(List.empty[String])(_.to[List]).filter(key => !engineConfigurationKeys.contains(key)) for { excludePaths <- c.downField("exclude_paths").as[Option[Set[Glob]]] baseSubDir <- c.downField("base_sub_dir").as[Option[String]] } yield { val extraToolConfigurations: Map[String, JsValue] = extraKeys.flatMap { extraKey => c.downField(extraKey) .as[Json] .fold[Option[JsValue]]( { _ => Option.empty }, { json => Try(play.api.libs.json.Json.parse(json.noSpaces)).toOption }) .map(value => (extraKey, value)) }(collection.breakOut) EngineConfiguration(excludePaths, baseSubDir, Option(extraToolConfigurations).filter(_.nonEmpty)) } } } implicit val decodeCodacyConfigurationFile: Decoder[CodacyConfigurationFile] = Decoder.forProduct3("engines", "exclude_paths", "languages")(CodacyConfigurationFile.apply) }
Example 32
Source File: TestUtils.scala From codacy-analysis-cli with GNU Affero General Public License v3.0 | 5 votes |
package com.codacy.analysis.core.utils import java.nio.file.attribute.PosixFilePermission import java.nio.file.{Path, Paths} import better.files.File import com.codacy.plugins.api.results import io.circe.Decoder import org.specs2.concurrent.ExecutionEnv import org.specs2.matcher.MatchResult import scala.sys.process.Process object TestUtils { implicit val categoryDecoder: Decoder[results.Pattern.Category.Value] = Decoder.decodeEnumeration(results.Pattern.Category) implicit val levelDecoder: Decoder[results.Result.Level.Value] = Decoder.decodeEnumeration(results.Result.Level) implicit val fileDecoder: Decoder[Path] = Decoder[String].map(Paths.get(_)) implicit val executionEnv: ExecutionEnv = ExecutionEnv.fromGlobalExecutionContext def withClonedRepo[T](gitUrl: String, commitUUid: String)(block: (File, File) => MatchResult[T]): MatchResult[T] = (for { directory <- File.temporaryDirectory() file <- File.temporaryFile() } yield { directory .addPermission(PosixFilePermission.OWNER_READ) .addPermission(PosixFilePermission.GROUP_READ) .addPermission(PosixFilePermission.OTHERS_READ) .addPermission(PosixFilePermission.OWNER_EXECUTE) .addPermission(PosixFilePermission.GROUP_EXECUTE) .addPermission(PosixFilePermission.OTHERS_EXECUTE) Process(Seq("git", "clone", gitUrl, directory.pathAsString)).! Process(Seq("git", "reset", "--hard", commitUUid), directory.toJava).! block(file, directory) }).get() def withTemporaryGitRepo[T](fn: File => MatchResult[T]): MatchResult[T] = { (for { temporaryDirectory <- File.temporaryDirectory() } yield { Process(Seq("git", "init"), temporaryDirectory.toJava).! Process(Seq("git", "commit", "--allow-empty", "-m", "initial commit"), temporaryDirectory.toJava).! fn(temporaryDirectory) }).get } }
Example 33
Source File: tags.scala From circe-magnolia with Apache License 2.0 | 5 votes |
package io.circe.magnolia import io.circe.{Decoder, Encoder} import shapeless.tag.@@ object tags { trait Magnolia trait Circe final class TaggedDecoder[T, A](val inner: Decoder[A]) extends AnyVal { def toTagged: Decoder[A] @@ T = { shapeless.tag[T](inner) } } final class TaggedEncoder[T, A](val inner: Encoder[A]) extends AnyVal { def toTagged: Encoder[A] @@ T = { shapeless.tag[T](inner) } } final class PartialTagged[T] { def apply[A](decoder: Decoder[A]): TaggedDecoder[T, A] = new TaggedDecoder(decoder) def apply[A](encoder: Encoder[A]): TaggedEncoder[T, A] = new TaggedEncoder(encoder) } def mkTag[T]: PartialTagged[T] = new PartialTagged[T] }
Example 34
Source File: CodecEquivalenceTests.scala From circe-magnolia with Apache License 2.0 | 5 votes |
package io.circe.magnolia import cats.instances.either._ import cats.kernel.Eq import cats.laws._ import cats.laws.discipline._ import io.circe.magnolia.tags.{TaggedDecoder, TaggedEncoder} import io.circe.{Decoder, Encoder, Json} import org.scalacheck.{Arbitrary, Prop, Shrink} import org.typelevel.discipline.Laws import shapeless.tag.@@ trait CodecEquivalenceLaws[A] { def circeDecoder: Decoder[A] @@ tags.Circe def magnoliaDecoder: Decoder[A] @@ tags.Magnolia def circeEncoder: Encoder[A] @@ tags.Circe def magnoliaEncoder: Encoder[A] @@ tags.Magnolia def encoderEq(a: A): IsEq[Json] = circeEncoder(a) <-> magnoliaEncoder(a) def decoderEq(a: A): IsEq[Decoder.Result[A]] = { val encoded = magnoliaEncoder(a) encoded.as(circeDecoder) <-> encoded.as(magnoliaDecoder) } } object CodecEquivalenceLaws { def apply[A]( implicit circeDecode: Decoder[A] @@ tags.Circe, magnoliaDecode: Decoder[A] @@ tags.Magnolia, circeEncode: Encoder[A] @@ tags.Circe, magnoliaEncode: Encoder[A] @@ tags.Magnolia) = new CodecEquivalenceLaws[A] { override val circeDecoder = circeDecode override val magnoliaDecoder = magnoliaDecode override val circeEncoder = circeEncode override val magnoliaEncoder = magnoliaEncode } } trait CodecEquivalenceTests[A] extends Laws { def laws: CodecEquivalenceLaws[A] def codecEquivalence( implicit arbitraryA: Arbitrary[A], shrinkA: Shrink[A], eqA: Eq[A]): RuleSet = new DefaultRuleSet( name = "codec equality", parent = None, "encoder equivalence" -> Prop.forAll { (a: A) => laws.encoderEq(a) }, "decoder equivalence" -> Prop.forAll { (a: A) => laws.decoderEq(a) } ) // Use codecEquivalence if possible. Use only when only // derived Encoder can be equivalent and should be documented def encoderEquivalence( implicit arbitraryA: Arbitrary[A], shrinkA: Shrink[A] ): RuleSet = new DefaultRuleSet( name = "codec equality", parent = None, "encoder equivalence" -> Prop.forAll { (a: A) => laws.encoderEq(a) }, ) } object CodecEquivalenceTests { def apply[A]( implicit circeDecode: Decoder[A] @@ tags.Circe, magnoliaDecode: Decoder[A] @@ tags.Magnolia, circeEncode: Encoder[A] @@ tags.Circe, magnoliaEncode: Encoder[A] @@ tags.Magnolia): CodecEquivalenceTests[A] = new CodecEquivalenceTests[A] { val laws: CodecEquivalenceLaws[A] = CodecEquivalenceLaws[A]( circeDecode, magnoliaDecode, circeEncode, magnoliaEncode) } def useTagged[A]( implicit circeDecode: TaggedDecoder[tags.Circe, A], magnoliaDecode: TaggedDecoder[tags.Magnolia, A], circeEncode: TaggedEncoder[tags.Circe, A], magnoliaEncode: TaggedEncoder[tags.Magnolia, A]): CodecEquivalenceTests[A] = new CodecEquivalenceTests[A] { val laws: CodecEquivalenceLaws[A] = CodecEquivalenceLaws[A]( circeDecode.toTagged, magnoliaDecode.toTagged, circeEncode.toTagged, magnoliaEncode.toTagged) } }
Example 35
Source File: WrappedOptionalString.scala From circe-magnolia with Apache License 2.0 | 5 votes |
package io.circe.tests.examples import cats.kernel.Eq import io.circe.{ Decoder, Encoder } import org.scalacheck.Arbitrary case class OptionalString(value: String) { def toOption: Option[String] = value match { case "" => None case other => Some(other) } } object OptionalString { def fromOption(o: Option[String]): OptionalString = OptionalString(o.getOrElse("")) implicit val decodeOptionalString: Decoder[OptionalString] = Decoder[Option[String]].map(fromOption) implicit val encodeOptionalString: Encoder[OptionalString] = Encoder[Option[String]].contramap(_.toOption) implicit val eqOptionalString: Eq[OptionalString] = Eq.fromUniversalEquals implicit val arbitraryOptionalString: Arbitrary[OptionalString] = Arbitrary(Arbitrary.arbitrary[Option[String]].map(fromOption)) } case class WrappedOptionalField(f: OptionalString) object WrappedOptionalField { implicit val decodeWrappedOptionalField: Decoder[WrappedOptionalField] = Decoder.forProduct1("f")(WrappedOptionalField.apply) implicit val encodeWrappedOptionalField: Encoder[WrappedOptionalField] = Encoder.forProduct1("f")(_.f) implicit val eqWrappedOptionalField: Eq[WrappedOptionalField] = Eq.fromUniversalEquals implicit val arbitraryWrappedOptionalField: Arbitrary[WrappedOptionalField] = Arbitrary(Arbitrary.arbitrary[OptionalString].map(WrappedOptionalField(_))) }
Example 36
Source File: AutoDerivedSuite.scala From circe-magnolia with Apache License 2.0 | 5 votes |
package io.circe.magnolia import io.circe.magnolia.derivation.decoder.auto._ import io.circe.magnolia.derivation.encoder.auto._ import io.circe.testing.CodecTests import io.circe.tests.CirceSuite import io.circe.tests.examples._ import io.circe.{Decoder, Encoder, Json} import shapeless.tag import shapeless.tag.@@ import shapeless.test.illTyped class AutoDerivedSuite extends CirceSuite { import AutoDerivedSuiteInputs._ // TODO: All these imports are temporary workaround for https://github.com/propensive/magnolia/issues/89 import Encoder._ import Decoder._ private implicit val encodeStringTag: Encoder[String @@ Tag] = Encoder[String].narrow private implicit val decodeStringTag: Decoder[String @@ Tag] = Decoder[String].map(tag[Tag](_)) checkLaws("Codec[Tuple1[Int]]", CodecTests[Tuple1[Int]].unserializableCodec) checkLaws("Codec[(Int, Int, Foo)]", CodecTests[(Int, Int, Foo)].unserializableCodec) checkLaws("Codec[Qux[Int]]", CodecTests[Qux[Int]].unserializableCodec) checkLaws("Codec[Seq[Foo]]", CodecTests[Seq[Foo]].unserializableCodec) checkLaws("Codec[Baz]", CodecTests[Baz].unserializableCodec) checkLaws("Codec[Foo]", CodecTests[Foo].unserializableCodec) checkLaws("Codec[OuterCaseClassExample]", CodecTests[OuterCaseClassExample].unserializableCodec) checkLaws("Codec[RecursiveAdtExample]", CodecTests[RecursiveAdtExample].unserializableCodec) checkLaws("Codec[RecursiveWithOptionExample]", CodecTests[RecursiveWithOptionExample].unserializableCodec) checkLaws("Codec[RecursiveWithListExample]", CodecTests[RecursiveWithListExample].unserializableCodec) checkLaws("Codec[AnyValInside]", CodecTests[AnyValInside].unserializableCodec) "A generically derived codec" should "not interfere with base instances" in forAll { (is: List[Int]) => val json = Encoder[List[Int]].apply(is) assert(json === Json.fromValues(is.map(Json.fromInt)) && json.as[List[Int]] === Right(is)) } it should "not be derived for Object" in { illTyped("Decoder[Object]") illTyped("Encoder[Object]") } it should "not be derived for AnyRef" in { illTyped("Decoder[AnyRef]") illTyped("Encoder[AnyRef]") } "Generic decoders" should "not interfere with defined decoders" in forAll { (xs: List[String]) => val json = Json.obj("SubtypeWithExplicitInstance" -> Json.fromValues(xs.map(Json.fromString))) val ch = Decoder[Sealed].apply(json.hcursor) val res = ch === Right(SubtypeWithExplicitInstance(xs): Sealed) assert(res) } "Generic encoders" should "not interfere with defined encoders" in forAll { (xs: List[String]) => val json = Json.obj("SubtypeWithExplicitInstance" -> Json.fromValues(xs.map(Json.fromString))) assert(Encoder[Sealed].apply(SubtypeWithExplicitInstance(xs): Sealed) === json) } // TODO: tagged types don't work ATM, might be related to https://github.com/propensive/magnolia/issues/89 // checkLaws("Codec[WithTaggedMembers]", CodecTests[WithTaggedMembers].unserializableCodec) checkLaws("Codec[Seq[WithSeqOfTagged]]", CodecTests[Seq[WithSeqOfTagged]].unserializableCodec) }
Example 37
Source File: SemiautoDerivedSuite.scala From circe-magnolia with Apache License 2.0 | 5 votes |
package io.circe.magnolia import io.circe.magnolia.derivation.decoder.semiauto._ import io.circe.magnolia.derivation.encoder.semiauto._ import io.circe.testing.CodecTests import io.circe.tests.CirceSuite import io.circe.tests.examples._ import io.circe.{Decoder, Encoder, Json} import shapeless.test.illTyped class SemiautoDerivedSuite extends CirceSuite { import SemiautoDerivedSuiteInputs._ implicit def decodeBox[A: Decoder]: Decoder[Box[A]] = deriveMagnoliaDecoder implicit def encodeBox[A: Encoder]: Encoder[Box[A]] = deriveMagnoliaEncoder implicit def decodeQux[A: Decoder]: Decoder[Qux[A]] = deriveMagnoliaDecoder implicit def encodeQux[A: Encoder]: Encoder[Qux[A]] = deriveMagnoliaEncoder implicit val decodeWub: Decoder[Wub] = deriveMagnoliaDecoder implicit val encodeWub: Encoder[Wub] = deriveMagnoliaEncoder implicit val decodeFoo: Decoder[Foo] = deriveMagnoliaDecoder implicit val encodeFoo: Encoder[Foo] = deriveMagnoliaEncoder implicit val decodeAnyValInside: Decoder[AnyValInside] = deriveMagnoliaDecoder implicit val encodeAnyValInside: Encoder[AnyValInside] = deriveMagnoliaEncoder implicit val decodeRecursiveAdtExample: Decoder[RecursiveAdtExample] = deriveMagnoliaDecoder implicit val encodeRecursiveAdtExample: Encoder[RecursiveAdtExample] = deriveMagnoliaEncoder implicit val decodeRecursiveWithOptionExample: Decoder[RecursiveWithOptionExample] = deriveMagnoliaDecoder implicit val encodeRecursiveWithOptionExample: Encoder[RecursiveWithOptionExample] = deriveMagnoliaEncoder checkLaws("Codec[Tuple1[Int]]", CodecTests[Tuple1[Int]].unserializableCodec) checkLaws("Codec[(Int, Int, Foo)]", CodecTests[(Int, Int, Foo)].unserializableCodec) checkLaws("Codec[Box[Int]]", CodecTests[Box[Int]].unserializableCodec) checkLaws("Codec[Qux[Int]]", CodecTests[Qux[Int]].unserializableCodec) checkLaws("Codec[Seq[Foo]]", CodecTests[Seq[Foo]].unserializableCodec) checkLaws("Codec[Baz]", CodecTests[Baz].unserializableCodec) checkLaws("Codec[Foo]", CodecTests[Foo].unserializableCodec) checkLaws("Codec[RecursiveAdtExample]", CodecTests[RecursiveAdtExample].unserializableCodec) checkLaws("Codec[RecursiveWithOptionExample]", CodecTests[RecursiveWithOptionExample].unserializableCodec) checkLaws("Codec[AnyValInside]", CodecTests[AnyValInside].unserializableCodec) "A generically derived codec" should "not interfere with base instances" in forAll { (is: List[Int]) => val json = Encoder[List[Int]].apply(is) assert(json === Json.fromValues(is.map(Json.fromInt)) && json.as[List[Int]] === Right(is)) } it should "not come from nowhere" in { illTyped("Decoder[OvergenerationExampleInner]") illTyped("Encoder[OvergenerationExampleInner]") illTyped("Decoder[OvergenerationExampleOuter0]") illTyped("Encoder[OvergenerationExampleOuter0]") illTyped("Decoder[OvergenerationExampleOuter1]") illTyped("Encoder[OvergenerationExampleOuter1]") } it should "require instances for all parts" in { illTyped("deriveMagnoliaDecoder[OvergenerationExampleInner0]") illTyped("deriveMagnoliaDecoder[OvergenerationExampleInner1]") illTyped("deriveMagnoliaEncoder[OvergenerationExampleInner0]") illTyped("deriveMagnoliaEncoder[OvergenerationExampleInner1]") } }
Example 38
Source File: SemiautoDerivedEquivalenceSuite.scala From circe-magnolia with Apache License 2.0 | 5 votes |
package io.circe.magnolia import io.circe.{Decoder, Encoder} import io.circe.tests.CirceSuite import io.circe.tests.examples._ import shapeless.tag import shapeless.tag.@@ import tags._ class SemiautoDerivedEquivalenceSuite extends CirceSuite { import SemiautoDerivedSuiteInputs._ object magnolia { import io.circe.magnolia.derivation.decoder.semiauto._ import io.circe.magnolia.derivation.encoder.semiauto._ implicit val magnoliaEncoder3 = tag[Magnolia](deriveMagnoliaEncoder[Box[Int]]) implicit val magnoliaEncoder4 = tag[Magnolia](deriveMagnoliaEncoder[Qux[Int]]) implicit val magnoliaEncoder6 = tag[Magnolia](deriveMagnoliaEncoder[Baz]) implicit val magnoliaEncoder11 = tag[Magnolia](deriveMagnoliaEncoder[Wub]) implicit val magnoliaEncoder10 = tag[Magnolia](deriveMagnoliaEncoder[Bam]) implicit val magnoliaEncoder7 = tag[Magnolia](deriveMagnoliaEncoder[Foo]) private implicit val encodeRecursiveAdtExample: Encoder[RecursiveAdtExample] = deriveMagnoliaEncoder[RecursiveAdtExample] implicit val magnoliaEncoder8 = tag[Magnolia](encodeRecursiveAdtExample) private implicit val encodeREcursiveWithOptionExample: Encoder[RecursiveWithOptionExample] = deriveMagnoliaEncoder[RecursiveWithOptionExample] implicit val magnoliaEncoder9 = tag[Magnolia](encodeREcursiveWithOptionExample) implicit val magnoliaEncoder1 = tag[Magnolia](deriveMagnoliaEncoder[AnyValInside]) implicit val magnoliaEncoder5: Encoder[Seq[Foo]] @@ Magnolia = tag[Magnolia](Encoder.encodeSeq(magnoliaEncoder7)) implicit val magnoliaDecoder3 = tag[Magnolia](deriveMagnoliaDecoder[Box[Int]]) implicit val magnoliaDecoder4 = tag[Magnolia](deriveMagnoliaDecoder[Qux[Int]]) implicit val magnoliaDecoder11 = tag[Magnolia](deriveMagnoliaDecoder[Wub]) implicit val magnoliaDecoder10 = tag[Magnolia](deriveMagnoliaDecoder[Bam]) implicit val magnoliaDecoder6 = tag[Magnolia](deriveMagnoliaDecoder[Baz]) implicit val magnoliaDecoder7 = tag[Magnolia](deriveMagnoliaDecoder[Foo]) private implicit val decoderREcursiveAdtExample: Decoder[RecursiveAdtExample] = deriveMagnoliaDecoder[RecursiveAdtExample] implicit val magnoliaDecoder8 = tag[Magnolia](decoderREcursiveAdtExample) private implicit val decoderRecursiveWithOptionExample: Decoder[RecursiveWithOptionExample] = deriveMagnoliaDecoder[RecursiveWithOptionExample] implicit val magnoliaDecoder9 = tag[Magnolia](decoderRecursiveWithOptionExample) implicit val magnoliaDecoder1 = tag[Magnolia](deriveMagnoliaDecoder[AnyValInside]) implicit val magnoliaDecoder5 = tag[Magnolia](Decoder.decodeSeq(magnoliaDecoder7)) } object circe { import io.circe.generic.semiauto._ implicit val enc1 = deriveEncoder[Wub] implicit val dec1 = deriveDecoder[Wub] implicit val enc2 = deriveEncoder[BaseAdtExample] implicit val dec2 = deriveDecoder[BaseAdtExample] implicit val circeEncoder3 = tag[Circe](deriveEncoder[Box[Int]]) implicit val circeEncoder4 = tag[Circe](deriveEncoder[Qux[Int]]) implicit val circeEncoder6 = tag[Circe](deriveEncoder[Baz]) implicit val circeEncoder7 = tag[Circe](deriveEncoder[Foo]) private implicit val encoderREcursiveAdtExample: Encoder[RecursiveAdtExample] = deriveEncoder[RecursiveAdtExample] implicit val circeEncoder8 = tag[Circe](encoderREcursiveAdtExample) private implicit val encoderRecursiveWithOptionExample: Encoder[RecursiveWithOptionExample] = deriveEncoder[RecursiveWithOptionExample] implicit val circeEncoder9 = tag[Circe](encoderRecursiveWithOptionExample) implicit val circeEncoder1 = tag[Circe](deriveEncoder[AnyValInside]) implicit val circeEncoder5: Encoder[Seq[Foo]] @@ Circe = tag[Circe](Encoder.encodeSeq(circeEncoder7)) implicit val circeDecoder3 = tag[Circe](deriveDecoder[Box[Int]]) implicit val circeDecoder4 = tag[Circe](deriveDecoder[Qux[Int]]) implicit val circeDecoder6 = tag[Circe](deriveDecoder[Baz]) implicit val circeDecoder7 = tag[Circe](deriveDecoder[Foo]: Decoder[Foo]) private implicit val decodeRecursiveAdtExample: Decoder[RecursiveAdtExample] = deriveDecoder[RecursiveAdtExample] implicit val circeDecoder8 = tag[Circe](decodeRecursiveAdtExample) private implicit val decodeRecursiveWithOptionExample: Decoder[RecursiveWithOptionExample] = deriveDecoder[RecursiveWithOptionExample] implicit val circeDecoder9 = tag[Circe](decodeRecursiveWithOptionExample) implicit val circeDecoder1 = tag[Circe](deriveDecoder[AnyValInside]) implicit val circeDecoder5 = tag[Circe](Decoder.decodeSeq(circeDecoder7)) } import magnolia._ import circe._ checkLaws("Codec[Box[Int]]", CodecEquivalenceTests[Box[Int]].codecEquivalence) checkLaws("Codec[Qux[Int]]", CodecEquivalenceTests[Qux[Int]].codecEquivalence) checkLaws("Codec[Baz]", CodecEquivalenceTests[Baz].codecEquivalence) checkLaws("Codec[Foo]", CodecEquivalenceTests[Foo].codecEquivalence) checkLaws("Codec[RecursiveAdtExample]", CodecEquivalenceTests[RecursiveAdtExample].codecEquivalence) checkLaws("Codec[RecursiveWithOptionExample]", CodecEquivalenceTests[RecursiveWithOptionExample].codecEquivalence) checkLaws("Codec[AnyValInside]", CodecEquivalenceTests[AnyValInside].codecEquivalence) checkLaws("Codec[Seq[Foo]]", CodecEquivalenceTests[Seq[Foo]].codecEquivalence) }
Example 39
Source File: SemiautoDerivedSuiteInputs.scala From circe-magnolia with Apache License 2.0 | 5 votes |
package io.circe.magnolia import cats.kernel.Eq import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} import org.scalacheck.{Arbitrary, Gen} import org.scalacheck.Arbitrary.arbitrary object SemiautoDerivedSuiteInputs { sealed trait RecursiveAdtExample case class BaseAdtExample(a: String) extends RecursiveAdtExample case class NestedAdtExample(r: RecursiveAdtExample) extends RecursiveAdtExample object RecursiveAdtExample { implicit val eqRecursiveAdtExample: Eq[RecursiveAdtExample] = Eq.fromUniversalEquals private def atDepth(depth: Int): Gen[RecursiveAdtExample] = if (depth < 3) Gen.oneOf( Arbitrary.arbitrary[String].map(BaseAdtExample(_)), atDepth(depth + 1).map(NestedAdtExample(_)) ) else Arbitrary.arbitrary[String].map(BaseAdtExample(_)) implicit val arbitraryRecursiveAdtExample: Arbitrary[RecursiveAdtExample] = Arbitrary(atDepth(0)) } case class RecursiveWithOptionExample(o: Option[RecursiveWithOptionExample]) object RecursiveWithOptionExample { implicit val eqRecursiveWithOptionExample: Eq[RecursiveWithOptionExample] = Eq.fromUniversalEquals private def atDepth(depth: Int): Gen[RecursiveWithOptionExample] = if (depth < 3) Gen.option(atDepth(depth + 1)).map(RecursiveWithOptionExample(_)) else Gen.const(RecursiveWithOptionExample(None)) implicit val arbitraryRecursiveWithOptionExample : Arbitrary[RecursiveWithOptionExample] = Arbitrary(atDepth(0)) } case class AnyInt(value: Int) extends AnyVal object AnyInt { implicit val encodeAnyInt: Encoder[AnyInt] = deriveEncoder implicit val decodeAnyInt: Decoder[AnyInt] = deriveDecoder } case class AnyValInside(v: AnyInt) object AnyValInside { implicit val eqAnyValInside: Eq[AnyValInside] = Eq.fromUniversalEquals implicit val arbitraryAnyValInside: Arbitrary[AnyValInside] = Arbitrary(arbitrary[Int].map(i => AnyValInside(AnyInt(i)))) } case class OvergenerationExampleInner(i: Int) case class OvergenerationExampleOuter0(i: OvergenerationExampleInner) case class OvergenerationExampleOuter1(oi: Option[OvergenerationExampleInner]) }
Example 40
Source File: ExternalNotification.scala From CloudGenesis with Apache License 2.0 | 5 votes |
package com.lifeway.cloudops.cloudformation import io.circe.{Decoder, Encoder} case class ExternalNotification(eventType: EventType, accountId: String, stackName: String, stackFile: String, templateFile: String, fileVersion: String, bucket: String, tags: Option[Seq[Tag]]) object ExternalNotification { implicit val encoder: Encoder[ExternalNotification] = Encoder.forProduct8("eventType", "accountId", "stackName", "stackFile", "templateFile", "stackFileVersion", "bucket", "tags")(x => (x.eventType, x.accountId, x.stackName, x.stackFile, x.templateFile, x.fileVersion, x.bucket, x.tags)) implicit val decoder: Decoder[ExternalNotification] = Decoder.forProduct8("eventType", "accountId", "stackName", "stackFile", "templateFile", "stackFileVersion", "bucket", "tags")(ExternalNotification.apply) }
Example 41
Source File: Types.scala From CloudGenesis with Apache License 2.0 | 5 votes |
package com.lifeway.cloudops.cloudformation import io.circe.{Decoder, Encoder, Json} sealed trait EventType case object CreateUpdateEvent extends EventType case object DeletedEvent extends EventType object EventType { implicit val encoder: Encoder[EventType] = Encoder[EventType] { case CreateUpdateEvent => Json.fromString("CreateUpdateEvent") case DeletedEvent => Json.fromString("DeletedEvent") } implicit val decoder: Decoder[EventType] = Decoder[EventType] { c => for { eType <- c.as[String] } yield { eType match { case "CreateUpdateEvent" => CreateUpdateEvent case "DeletedEvent" => DeletedEvent } } } } case class S3File(bucket: String, key: String, versionId: String, eventType: EventType) object S3File { implicit val decoder: Decoder[S3File] = Decoder.forProduct4("bucketName", "key", "versionId", "eventType")(S3File.apply) implicit val encoder: Encoder[S3File] = Encoder.forProduct4("bucketName", "key", "versionId", "eventType")(f => (f.bucket, f.key, f.versionId, f.eventType)) }
Example 42
Source File: Http4sClientSpec.scala From canoe with MIT License | 5 votes |
package canoe.api.clients import canoe.api._ import canoe.methods.Method import canoe.models.InputFile import cats.effect.IO import io.circe.{Decoder, Encoder} import org.http4s.HttpApp import org.http4s.client.Client import org.http4s.dsl.io._ import io.circe.Json import io.chrisdavenport.log4cats.slf4j.Slf4jLogger import org.scalatest.freespec.AnyFreeSpec class Http4sClientSpec extends AnyFreeSpec { private case class TestMethod(name: String = "test", encoder: Encoder[String] = Encoder.encodeString, decoder: Decoder[String] = Decoder.decodeString, files: List[InputFile] = Nil) extends Method[String, String] { def attachments(request: String): List[(String, InputFile)] = files.map("" -> _) } private implicit val testMethod = TestMethod() private def response(s: String) = s"""{"ok" : true, "result" : "$s"}""" private implicit val logger = Slf4jLogger.getLogger[IO] "Client" - { "sends" - { "to correct Telegram endpoint" in { val client: Client[IO] = Client.fromHttpApp(HttpApp(r => Ok(response(r.uri.toString)))) val tgClient = new Http4sTelegramClient("token", client) assert(tgClient.execute("any").unsafeRunSync() == s"https://api.telegram.org/bottoken/${testMethod.name}") } val tgClient = new Http4sTelegramClient("", Client.fromHttpApp(HttpApp[IO] { r => Ok(response(r.headers.get(org.http4s.headers.`Content-Type`).map(_.value.replace("\"", "''")).getOrElse(""))) })) "json POST request if attachments contain file upload" in { assert(tgClient.execute("any").unsafeRunSync() == "application/json") } "multipart POST request if attachments contain file upload" in { val resp = tgClient.execute("any")(testMethod.copy(files = List(InputFile.Upload("", Array.emptyByteArray)))) assert(resp.unsafeRunSync().startsWith("multipart/form-data")) } } "encodes/decodes" - { "request entity with method encoder" in { val tgClient = new Http4sTelegramClient( "", Client.fromHttpApp(HttpApp[IO](_.bodyAsText.compile.string.flatMap(s => Ok(response(s.replace("\"", "'")))))) ) val res = tgClient.execute("")(testMethod.copy(encoder = Encoder.instance(_ => Json.fromString("encoded")))) assert(res.unsafeRunSync() == "'encoded'") } "result entity with method decoder" in { val tgClient = new Http4sTelegramClient("", Client.fromHttpApp(HttpApp[IO](_ => Ok(response(""))))) val res = tgClient.execute("")(testMethod.copy(decoder = Decoder.const("decoded"))) assert(res.unsafeRunSync() == "decoded") } } "handles" - { "decode failure as ResponseDecodingError" in { val tgClient = new Http4sTelegramClient("", Client.fromHttpApp(HttpApp[IO](_ => Ok("{}")))) assertThrows[ResponseDecodingError](tgClient.execute("any").unsafeRunSync()) } "unsuccessful result as FailedMethod" in { val response = """{"ok" : false, "result" : "any"}""" val tgClient = new Http4sTelegramClient("", Client.fromHttpApp(HttpApp[IO](_ => Ok(response)))) assertThrows[FailedMethod[String, String]](tgClient.execute("any").unsafeRunSync()) } } } }
Example 43
Source File: AddStickerToSet.scala From canoe with MIT License | 5 votes |
package canoe.methods.stickers import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.{InputFile, MaskPosition} import io.circe.generic.semiauto.deriveEncoder import io.circe.{Decoder, Encoder} import cats.instances.option._ import cats.syntax.all._ def animated(userId: Int, name: String, sticker: InputFile, emojis: String, maskPosition: Option[MaskPosition] ): AddStickerToSet = new AddStickerToSet(userId, name, None, Some(sticker), emojis, maskPosition) import io.circe.generic.auto._ implicit val method: Method[AddStickerToSet, Boolean] = new Method[AddStickerToSet, Boolean] { def name: String = "addStickerToSet" def encoder: Encoder[AddStickerToSet] = deriveEncoder[AddStickerToSet].snakeCase def decoder: Decoder[Boolean] = Decoder.decodeBoolean def attachments(request: AddStickerToSet): List[(String, InputFile)] = List(request.pngSticker.tupleLeft("png_sticker"), request.tgsSticker.tupleLeft("tgs_sticker")).flatten } }
Example 44
Source File: AnswerInlineQuery.scala From canoe with MIT License | 5 votes |
package canoe.methods.queries import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.{InlineQueryResult, InputFile} import io.circe.generic.semiauto.deriveEncoder import io.circe.{Decoder, Encoder} final case class AnswerInlineQuery(inlineQueryId: String, results: Seq[InlineQueryResult], cacheTime: Option[Int] = None, isPersonal: Option[Boolean] = None, nextOffset: Option[String] = None, switchPmText: Option[String] = None, switchPmParameter: Option[String] = None) object AnswerInlineQuery { import io.circe.generic.auto._ implicit val method: Method[AnswerInlineQuery, Boolean] = new Method[AnswerInlineQuery, Boolean] { def name: String = "answerInlineQuery" def encoder: Encoder[AnswerInlineQuery] = deriveEncoder[AnswerInlineQuery].snakeCase def decoder: Decoder[Boolean] = Decoder.decodeBoolean def attachments(request: AnswerInlineQuery): List[(String, InputFile)] = Nil } }
Example 45
Source File: SendMediaGroup.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.messages.TelegramMessage import canoe.models.{ChatId, InputFile, InputMedia} import io.circe.generic.semiauto.deriveEncoder import io.circe.{Decoder, Encoder} final case class SendMediaGroup(chatId: ChatId, media: List[InputMedia], disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None) object SendMediaGroup { import io.circe.generic.auto._ implicit val method: Method[SendMediaGroup, List[TelegramMessage]] = new Method[SendMediaGroup, List[TelegramMessage]] { def name: String = "sendMediaGroup" def encoder: Encoder[SendMediaGroup] = deriveEncoder[SendMediaGroup] .contramap[SendMediaGroup]( s => s.copy(media = s.media.filter(_.media match { case InputFile.Upload(_, _) => false case InputFile.Existing(_) => true })) ) .snakeCase def decoder: Decoder[List[TelegramMessage]] = Decoder.decodeList(TelegramMessage.telegramMessageDecoder) def attachments(request: SendMediaGroup): List[(String, InputFile)] = request.media.flatMap(_.files) } }
Example 46
Source File: SendDocument.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.ParseMode.ParseMode import canoe.models.messages.DocumentMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendDocument(chatId: ChatId, document: InputFile, thumb: Option[InputFile] = None, caption: Option[String] = None, parseMode: Option[ParseMode] = None, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendDocument { import io.circe.generic.auto._ implicit val method: Method[SendDocument, DocumentMessage] = new Method[SendDocument, DocumentMessage] { def name: String = "sendDocument" def encoder: Encoder[SendDocument] = deriveEncoder[SendDocument].snakeCase def decoder: Decoder[DocumentMessage] = deriveDecoder[DocumentMessage] def attachments(request: SendDocument): List[(String, InputFile)] = List("document" -> request.document) } }
Example 47
Source File: SendVideo.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.ParseMode.ParseMode import canoe.models.messages.VideoMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendVideo(chatId: ChatId, video: InputFile, duration: Option[Int] = None, width: Option[Int] = None, height: Option[Int] = None, thumb: Option[InputFile] = None, caption: Option[String] = None, parseMode: Option[ParseMode] = None, supportsStreaming: Option[Boolean] = None, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendVideo { import io.circe.generic.auto._ implicit val method: Method[SendVideo, VideoMessage] = new Method[SendVideo, VideoMessage] { def name: String = "sendVideo" def encoder: Encoder[SendVideo] = deriveEncoder[SendVideo].snakeCase def decoder: Decoder[VideoMessage] = deriveDecoder[VideoMessage] def attachments(request: SendVideo): List[(String, InputFile)] = List("video" -> request.video) } }
Example 48
Source File: EditMessageCaption.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.ParseMode.ParseMode import canoe.models.messages.TelegramMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.auto._ import io.circe.generic.semiauto.deriveEncoder import io.circe.{Decoder, Encoder} def inlined(inlineMessageId: String, caption: Option[String], parseMode: Option[ParseMode] = None, replyMarkup: Option[ReplyMarkup] = None): EditMessageCaption = new EditMessageCaption(None, None, Some(inlineMessageId), caption, parseMode, replyMarkup) implicit val method: Method[EditMessageCaption, Either[Boolean, TelegramMessage]] = new Method[EditMessageCaption, Either[Boolean, TelegramMessage]] { def name: String = "editMessageCaption" def encoder: Encoder[EditMessageCaption] = deriveEncoder[EditMessageCaption].snakeCase def decoder: Decoder[Either[Boolean, TelegramMessage]] = Decoder.decodeBoolean.either(TelegramMessage.telegramMessageDecoder) def attachments(request: EditMessageCaption): List[(String, InputFile)] = Nil } }
Example 49
Source File: SendAudio.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.ParseMode.ParseMode import canoe.models.messages.AudioMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendAudio(chatId: ChatId, audio: InputFile, duration: Option[Int] = None, caption: Option[String] = None, parseMode: Option[ParseMode] = None, performer: Option[String] = None, title: Option[String] = None, thumb: Option[InputFile] = None, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendAudio { import io.circe.generic.auto._ implicit val method: Method[SendAudio, AudioMessage] = new Method[SendAudio, AudioMessage] { def name: String = "sendAudio" def encoder: Encoder[SendAudio] = deriveEncoder[SendAudio].snakeCase def decoder: Decoder[AudioMessage] = deriveDecoder[AudioMessage] def attachments(request: SendAudio): List[(String, InputFile)] = List("audio" -> request.audio) } }
Example 50
Source File: EditMessageText.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.ParseMode.ParseMode import canoe.models.messages.TelegramMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto.deriveEncoder import io.circe.{Decoder, Encoder} def inlined(inlineMessageId: String, text: String, parseMode: Option[ParseMode] = None, disableWebPagePreview: Option[Boolean] = None, replyMarkup: Option[ReplyMarkup] = None): EditMessageText = new EditMessageText(None, None, Some(inlineMessageId), text, parseMode, disableWebPagePreview, replyMarkup) implicit val method: Method[EditMessageText, Either[Boolean, TelegramMessage]] = new Method[EditMessageText, Either[Boolean, TelegramMessage]] { import io.circe.generic.auto._ def name: String = "editMessageText" def encoder: Encoder[EditMessageText] = deriveEncoder[EditMessageText].snakeCase def decoder: Decoder[Either[Boolean, TelegramMessage]] = Decoder.decodeBoolean.either(TelegramMessage.telegramMessageDecoder) def attachments(request: EditMessageText): List[(String, InputFile)] = Nil } }
Example 51
Source File: SendAnimation.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.ParseMode.ParseMode import canoe.models.messages.AnimationMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendAnimation(chatId: ChatId, animation: InputFile, duration: Option[Int] = None, width: Option[Int] = None, height: Option[Int] = None, thumb: Option[InputFile] = None, caption: Option[String] = None, parseMode: Option[ParseMode] = None, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendAnimation { import io.circe.generic.auto._ implicit val method: Method[SendAnimation, AnimationMessage] = new Method[SendAnimation, AnimationMessage] { def name: String = "sendAnimation" def encoder: Encoder[SendAnimation] = deriveEncoder[SendAnimation].snakeCase def decoder: Decoder[AnimationMessage] = deriveDecoder[AnimationMessage] def attachments(request: SendAnimation): List[(String, InputFile)] = List("animation" -> request.animation) ++ request.thumb.map(t => "thumb" -> t).toList } }
Example 52
Source File: SendVideoNote.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.messages.VideoNoteMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendVideoNote(chatId: ChatId, videoNote: InputFile, duration: Option[Int] = None, length: Option[Int] = None, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendVideoNote { import io.circe.generic.auto._ implicit val method: Method[SendVideoNote, VideoNoteMessage] = new Method[SendVideoNote, VideoNoteMessage] { def name: String = "sendVideoNote" def encoder: Encoder[SendVideoNote] = deriveEncoder[SendVideoNote].snakeCase def decoder: Decoder[VideoNoteMessage] = deriveDecoder[VideoNoteMessage] def attachments(request: SendVideoNote): List[(String, InputFile)] = List("videoNote" -> request.videoNote) } }
Example 53
Source File: SendVoice.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.ParseMode.ParseMode import canoe.models.messages.VoiceMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendVoice(chatId: ChatId, voice: InputFile, caption: Option[String] = None, parseMode: Option[ParseMode] = None, duration: Option[Int] = None, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendVoice { import io.circe.generic.auto._ implicit val method: Method[SendVoice, VoiceMessage] = new Method[SendVoice, VoiceMessage] { def name: String = "sendVoice" def encoder: Encoder[SendVoice] = deriveEncoder[SendVoice].snakeCase def decoder: Decoder[VoiceMessage] = deriveDecoder[VoiceMessage] def attachments(request: SendVoice): List[(String, InputFile)] = List("voice" -> request.voice) } }
Example 54
Source File: EditMessageLiveLocation.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.messages.TelegramMessage import canoe.models.{ChatId, InlineKeyboardMarkup, InputFile} import io.circe.generic.semiauto.deriveEncoder import io.circe.{Decoder, Encoder} def inlined(inlineMessageId: Int, lat: Double, long: Double, replyMarkup: Option[InlineKeyboardMarkup] = None): EditMessageLiveLocation = new EditMessageLiveLocation(None, None, Some(inlineMessageId), lat, long, replyMarkup) implicit val method: Method[EditMessageLiveLocation, Either[Boolean, TelegramMessage]] = new Method[EditMessageLiveLocation, Either[Boolean, TelegramMessage]] { import io.circe.generic.auto._ def name: String = "editMessageLiveLocation" def encoder: Encoder[EditMessageLiveLocation] = deriveEncoder[EditMessageLiveLocation].snakeCase def decoder: Decoder[Either[Boolean, TelegramMessage]] = Decoder.decodeBoolean.either(TelegramMessage.telegramMessageDecoder) def attachments(request: EditMessageLiveLocation): List[(String, InputFile)] = Nil } }
Example 55
Source File: SendGame.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.messages.GameMessage import canoe.models.{InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendGame(chatId: Long, gameShortName: String, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendGame { import io.circe.generic.auto._ implicit val method: Method[SendGame, GameMessage] = new Method[SendGame, GameMessage] { def name: String = "sendGame" def encoder: Encoder[SendGame] = deriveEncoder[SendGame].snakeCase def decoder: Decoder[GameMessage] = deriveDecoder[GameMessage] def attachments(request: SendGame): List[(String, InputFile)] = Nil } }
Example 56
Source File: SendSticker.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.messages.StickerMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendSticker(chatId: ChatId, sticker: InputFile, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendSticker { import io.circe.generic.auto._ implicit val method: Method[SendSticker, StickerMessage] = new Method[SendSticker, StickerMessage] { def name: String = "sendSticker" def encoder: Encoder[SendSticker] = deriveEncoder[SendSticker].snakeCase def decoder: Decoder[StickerMessage] = deriveDecoder[StickerMessage] def attachments(request: SendSticker): List[(String, InputFile)] = List("sticker" -> request.sticker) } }
Example 57
Source File: SendDice.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.messages.DiceThrownMessage import canoe.models.{ChatId, DiceEmoji, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendDice(chatId: ChatId, emoji: DiceEmoji, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendDice { import io.circe.generic.auto._ implicit val method: Method[SendDice, DiceThrownMessage] = new Method[SendDice, DiceThrownMessage] { def name: String = "sendDice" def encoder: Encoder[SendDice] = deriveEncoder[SendDice].snakeCase def decoder: Decoder[DiceThrownMessage] = deriveDecoder[DiceThrownMessage] def attachments(request: SendDice): List[(String, InputFile)] = Nil } }
Example 58
Source File: SendContact.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.messages.ContactMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendContact(chatId: ChatId, phoneNumber: String, firstName: String, lastName: Option[String] = None, vcard: Option[String] = None, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendContact { import io.circe.generic.auto._ implicit val method: Method[SendContact, ContactMessage] = new Method[SendContact, ContactMessage] { def name: String = "sendContact" def encoder: Encoder[SendContact] = deriveEncoder[SendContact].snakeCase def decoder: Decoder[ContactMessage] = deriveDecoder[ContactMessage] def attachments(request: SendContact): List[(String, InputFile)] = Nil } }
Example 59
Source File: SendPhoto.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.ParseMode.ParseMode import canoe.models.messages.PhotoMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendPhoto(chatId: ChatId, photo: InputFile, caption: Option[String] = None, parseMode: Option[ParseMode] = None, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendPhoto { import io.circe.generic.auto._ implicit val method: Method[SendPhoto, PhotoMessage] = new Method[SendPhoto, PhotoMessage] { def name: String = "sendPhoto" def encoder: Encoder[SendPhoto] = deriveEncoder[SendPhoto].snakeCase def decoder: Decoder[PhotoMessage] = deriveDecoder[PhotoMessage] def attachments(request: SendPhoto): List[(String, InputFile)] = List("photo" -> request.photo) } }
Example 60
Source File: SendVenue.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.messages.VenueMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendVenue(chatId: ChatId, latitude: Double, longitude: Double, title: String, address: String, foursquareId: Option[String] = None, foursquareType: Option[String] = None, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendVenue { import io.circe.generic.auto._ implicit val method: Method[SendVenue, VenueMessage] = new Method[SendVenue, VenueMessage] { def name: String = "sendVenue" def encoder: Encoder[SendVenue] = deriveEncoder[SendVenue].snakeCase def decoder: Decoder[VenueMessage] = deriveDecoder[VenueMessage] def attachments(request: SendVenue): List[(String, InputFile)] = Nil } }
Example 61
Source File: SendLocation.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.messages.LocationMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendLocation(chatId: ChatId, latitude: Double, longitude: Double, livePeriod: Option[Int] = None, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendLocation { import io.circe.generic.auto._ implicit val method: Method[SendLocation, LocationMessage] = new Method[SendLocation, LocationMessage] { def name: String = "sendLocation" def encoder: Encoder[SendLocation] = deriveEncoder[SendLocation].snakeCase def decoder: Decoder[LocationMessage] = deriveDecoder[LocationMessage] def attachments(request: SendLocation): List[(String, InputFile)] = Nil } }
Example 62
Source File: EditMessageMedia.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.messages.TelegramMessage import canoe.models.{ChatId, InlineKeyboardMarkup, InputFile, InputMedia} import io.circe.generic.semiauto.deriveEncoder import io.circe.{Decoder, Encoder} def inlined(inlineMessageId: String, media: InputMedia, replyMarkup: Option[InlineKeyboardMarkup] = None): EditMessageMedia = new EditMessageMedia(None, None, Some(inlineMessageId), media, replyMarkup) implicit val method: Method[EditMessageMedia, Either[Boolean, TelegramMessage]] = new Method[EditMessageMedia, Either[Boolean, TelegramMessage]] { import io.circe.generic.auto._ def name: String = "editMessageMedia" def encoder: Encoder[EditMessageMedia] = deriveEncoder[EditMessageMedia].snakeCase def decoder: Decoder[Either[Boolean, TelegramMessage]] = Decoder.decodeBoolean.either(TelegramMessage.telegramMessageDecoder) def attachments(request: EditMessageMedia): List[(String, InputFile)] = request.media.files } }
Example 63
Source File: SendMessage.scala From canoe with MIT License | 5 votes |
package canoe.methods.messages import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.ParseMode.ParseMode import canoe.models.messages.TextMessage import canoe.models.{ChatId, InputFile, ReplyMarkup} import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder} final case class SendMessage(chatId: ChatId, text: String, parseMode: Option[ParseMode] = None, disableWebPagePreview: Option[Boolean] = None, disableNotification: Option[Boolean] = None, replyToMessageId: Option[Int] = None, replyMarkup: Option[ReplyMarkup] = None) object SendMessage { import io.circe.generic.auto._ implicit val method: Method[SendMessage, TextMessage] = new Method[SendMessage, TextMessage] { def name: String = "sendMessage" def encoder: Encoder[SendMessage] = deriveEncoder[SendMessage].snakeCase def decoder: Decoder[TextMessage] = deriveDecoder[TextMessage] def attachments(request: SendMessage): List[(String, InputFile)] = Nil } }
Example 64
Source File: SetGameScore.scala From canoe with MIT License | 5 votes |
package canoe.methods.games import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.messages.TelegramMessage import canoe.models.{ChatId, InputFile} import io.circe.generic.semiauto.deriveEncoder import io.circe.{Decoder, Encoder} def inlined(inlineMessageId: String, userId: Int, score: Long, force: Option[Boolean] = None, disableEditMessage: Option[Boolean] = None): SetGameScore = new SetGameScore(userId, score, force, disableEditMessage, inlineMessageId = Some(inlineMessageId)) implicit val method: Method[SetGameScore, Either[Boolean, TelegramMessage]] = new Method[SetGameScore, Either[Boolean, TelegramMessage]] { def name: String = "setGameScore" def encoder: Encoder[SetGameScore] = deriveEncoder[SetGameScore].snakeCase def decoder: Decoder[Either[Boolean, TelegramMessage]] = Decoder.decodeBoolean.either(TelegramMessage.telegramMessageDecoder) def attachments(request: SetGameScore): List[(String, InputFile)] = Nil } }
Example 65
Source File: PromoteChatMember.scala From canoe with MIT License | 5 votes |
package canoe.methods.chats import canoe.marshalling.codecs._ import canoe.methods.Method import canoe.models.{ChatId, InputFile} import io.circe.generic.semiauto.deriveEncoder import io.circe.{Decoder, Encoder} final case class PromoteChatMember(chatId: ChatId, userId: Int, canChangeInfo: Option[Boolean] = None, canPostMessages: Option[Boolean] = None, canEditMessages: Option[Boolean] = None, canDeleteMessages: Option[Boolean] = None, canInviteUsers: Option[Boolean] = None, canRestrictMembers: Option[Boolean] = None, canPinMessages: Option[Boolean] = None, canPromoteMembers: Option[Boolean] = None) object PromoteChatMember { implicit val method: Method[PromoteChatMember, Boolean] = new Method[PromoteChatMember, Boolean] { def name: String = "promoteChatMember" def encoder: Encoder[PromoteChatMember] = deriveEncoder[PromoteChatMember].snakeCase def decoder: Decoder[Boolean] = Decoder.decodeBoolean def attachments(request: PromoteChatMember): List[(String, InputFile)] = Nil } }
Example 66
Source File: Chat.scala From canoe with MIT License | 5 votes |
package canoe.models import canoe.models.ChatType.ChatType import io.circe.Decoder import io.circe.generic.auto._ import io.circe.generic.semiauto.deriveDecoder sealed trait Chat { def id: Long } object Chat { implicit val chatDecoder: Decoder[Chat] = Decoder.instance[Chat] { cursor => cursor .get[ChatType]("type") .map { case ChatType.Private => deriveDecoder[PrivateChat] case ChatType.Group => deriveDecoder[Group] case ChatType.Supergroup => deriveDecoder[Supergroup] case ChatType.Channel => deriveDecoder[Channel] } .flatMap(_.tryDecode(cursor)) } } final case class PrivateChat(id: Long, username: Option[String], firstName: Option[String], lastName: Option[String]) extends Chat final case class Group(id: Long, title: Option[String]) extends Chat final case class Supergroup(id: Long, title: Option[String], username: Option[String]) extends Chat final case class Channel(id: Long, title: Option[String], username: Option[String]) extends Chat
Example 67
Source File: ChatMember.scala From canoe with MIT License | 5 votes |
package canoe.models import canoe.models.MemberStatus.MemberStatus import io.circe.Decoder import io.circe.generic.auto._ import io.circe.generic.semiauto.deriveDecoder sealed trait ChatMember { def user: User } object ChatMember { implicit val chatMemberDecoder: Decoder[ChatMember] = Decoder.instance[ChatMember] { cursor => cursor .get[MemberStatus]("status") .map { case MemberStatus.Creator => deriveDecoder[ChatCreator] case MemberStatus.Administrator => deriveDecoder[ChatAdministrator] case MemberStatus.Member => deriveDecoder[OrdinaryMember] case MemberStatus.Restricted => deriveDecoder[RestrictedMember] case MemberStatus.Left => deriveDecoder[LeftMember] case MemberStatus.Kicked => deriveDecoder[KickedMember] } .flatMap(_.tryDecode(cursor)) } } final case class ChatCreator(user: User) extends ChatMember final case class OrdinaryMember(user: User) extends ChatMember final case class LeftMember(user: User) extends ChatMember final case class KickedMember(user: User, untilDate: Option[Int]) extends ChatMember final case class ChatAdministrator(user: User, customTitle: Option[String], canBeEdited: Option[Boolean], canChangeInfo: Option[Boolean], canPostMessages: Option[Boolean], canEditMessages: Option[Boolean], canDeleteMessages: Option[Boolean], canRestrictMembers: Option[Boolean], canPromoteMembers: Option[Boolean], canInviteUsers: Option[Boolean], canPinMessages: Option[Boolean]) extends ChatMember final case class RestrictedMember(user: User, untilDate: Option[Int], isMember: Option[Boolean], canChangeInfo: Option[Boolean], canInviteUsers: Option[Boolean], canPinMessages: Option[Boolean], canSendMessages: Option[Boolean], canSendMediaMessages: Option[Boolean], canSendOtherMessages: Option[Boolean], canAddWebPagePreviews: Option[Boolean]) extends ChatMember
Example 68
Source File: UserMessage.scala From canoe with MIT License | 5 votes |
package canoe.models.messages import canoe.models.{Chat, User} import cats.syntax.functor._ import io.circe.Decoder import io.circe.generic.auto._ import io.circe.generic.semiauto.deriveDecoder trait UserMessage extends TelegramMessage { def from: Option[User] def forwardFrom: Option[User] def forwardFromChat: Option[Chat] def forwardFromMessageId: Option[Int] def forwardSignature: Option[String] def forwardSenderName: Option[String] def forwardDate: Option[Int] def replyToMessage: Option[TelegramMessage] def editDate: Option[Int] def authorSignature: Option[String] } object UserMessage { implicit val userMessageDecoder: Decoder[UserMessage] = List[Decoder[UserMessage]]( deriveDecoder[AnimationMessage].widen, deriveDecoder[AudioMessage].widen, deriveDecoder[ContactMessage].widen, deriveDecoder[DocumentMessage].widen, deriveDecoder[GameMessage].widen, deriveDecoder[InvoiceMessage].widen, deriveDecoder[LocationMessage].widen, deriveDecoder[PhotoMessage].widen, deriveDecoder[PollMessage].widen, deriveDecoder[StickerMessage].widen, deriveDecoder[TextMessage].widen, deriveDecoder[VenueMessage].widen, deriveDecoder[VideoMessage].widen, deriveDecoder[VideoNoteMessage].widen, deriveDecoder[VoiceMessage].widen ).reduceLeft(_.or(_)) }
Example 69
Source File: TelegramMessage.scala From canoe with MIT License | 5 votes |
package canoe.models.messages import canoe.models.Chat import cats.syntax.functor._ import io.circe.Decoder trait TelegramMessage { def messageId: Int def chat: Chat def date: Int } object TelegramMessage { implicit val telegramMessageDecoder: Decoder[TelegramMessage] = List[Decoder[TelegramMessage]]( UserMessage.userMessageDecoder.widen, SystemMessage.systemMessageDecoder.widen ).reduceLeft(_.or(_)) }
Example 70
Source File: SystemMessage.scala From canoe with MIT License | 5 votes |
package canoe.models.messages import canoe.models.{Chat, DiceResult, PhotoSize, SuccessfulPayment, User} import cats.syntax.functor._ import io.circe.Decoder import io.circe.generic.auto._ import io.circe.generic.semiauto.deriveDecoder sealed trait SystemMessage extends TelegramMessage with Product object SystemMessage { implicit val systemMessageDecoder: Decoder[SystemMessage] = List[Decoder[SystemMessage]]( deriveDecoder[MessagePinned].widen, deriveDecoder[ChatMemberAdded].widen, deriveDecoder[ChannelCreated].widen, deriveDecoder[ChatMemberLeft].widen, deriveDecoder[ChatPhotoChanged].widen, deriveDecoder[ChatPhotoDeleted].widen, deriveDecoder[ChatTitleChanged].widen, deriveDecoder[MigratedFromGroup].widen, deriveDecoder[MigratedToSupergroup].widen, deriveDecoder[SuccessfulPaymentMessage].widen, deriveDecoder[GroupChatCreated].widen, deriveDecoder[SupergroupCreated].widen, deriveDecoder[WebsiteConnected].widen, deriveDecoder[DiceThrownMessage].widen ).reduceLeft(_.or(_)) } final case class MessagePinned(messageId: Int, chat: Chat, date: Int, pinnedMessage: TelegramMessage) extends SystemMessage final case class ChannelCreated(messageId: Int, chat: Chat, date: Int, channelChatCreated: Boolean) extends SystemMessage final case class ChatMemberAdded(messageId: Int, chat: Chat, date: Int, newChatMembers: Seq[User]) extends SystemMessage final case class ChatMemberLeft(messageId: Int, chat: Chat, date: Int, leftChatMember: User) extends SystemMessage final case class ChatPhotoChanged(messageId: Int, chat: Chat, date: Int, newChatPhoto: Seq[PhotoSize]) extends SystemMessage final case class ChatPhotoDeleted(messageId: Int, chat: Chat, date: Int, deleteChatPhoto: Boolean) extends SystemMessage final case class ChatTitleChanged(messageId: Int, chat: Chat, date: Int, newChatTitle: String) extends SystemMessage final case class MigratedFromGroup(messageId: Int, chat: Chat, date: Int, migrateFromChatId: Long) extends SystemMessage final case class MigratedToSupergroup(messageId: Int, chat: Chat, date: Int, migrateToChatId: Long) extends SystemMessage final case class GroupChatCreated(messageId: Int, chat: Chat, date: Int, groupChatCreated: Boolean) extends SystemMessage final case class SupergroupCreated(messageId: Int, chat: Chat, date: Int, supergroupChatCreated: Boolean) extends SystemMessage final case class SuccessfulPaymentMessage(messageId: Int, chat: Chat, date: Int, successfulPayment: SuccessfulPayment) extends SystemMessage final case class WebsiteConnected(messageId: Int, chat: Chat, date: Int, connectedWebsite: String) extends SystemMessage final case class DiceThrownMessage(messageId: Int, chat: Chat, date: Int, dice: DiceResult) extends SystemMessage
Example 71
Source File: Update.scala From canoe with MIT License | 5 votes |
package canoe.models import canoe.marshalling.codecs._ import canoe.models.messages.TelegramMessage import cats.syntax.functor._ import io.circe.Decoder import io.circe.generic.auto._ import io.circe.generic.semiauto.deriveDecoder sealed trait Update { def updateId: Long } object Update { final case class Unknown(updateId: Long) extends Update implicit val updateDecoder: Decoder[Update] = List[Decoder[Update]]( deriveDecoder[MessageReceived].widen, deriveDecoder[MessageEdited].widen, deriveDecoder[ChannelPost].widen, deriveDecoder[ChannelPostEdited].widen, deriveDecoder[PollUpdated].widen, deriveDecoder[InlineQueryReceived].widen, deriveDecoder[InlineResultSelected].widen, deriveDecoder[CallbackButtonSelected].widen, deriveDecoder[ShippingQueryReceived].widen, deriveDecoder[PreCheckoutQueryReceived].widen, deriveDecoder[PollAnswerReceived].widen, deriveDecoder[Unknown].widen ).reduceLeft(_.or(_)).camelCase } final case class PollUpdated(updateId: Long, poll: Poll) extends Update
Example 72
Source File: CodecsSpec.scala From canoe with MIT License | 5 votes |
package canoe.marshalling import canoe.marshalling.codecs._ import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder, Json} import org.scalatest.freespec.AnyFreeSpec class CodecsSpec extends AnyFreeSpec { case class Inner(longName: String) case class Outer(longInt: Int, inner: Inner) implicit val innerDecoder: Decoder[Inner] = deriveDecoder implicit val innerEncoder: Encoder[Inner] = deriveEncoder val decoder: Decoder[Outer] = deriveDecoder val encoder: Encoder[Outer] = deriveEncoder val instance: Outer = Outer(12, Inner("name")) "encoder works as expected" in { assert(allJsonKeys(encoder(instance)) == List("longInt", "inner", "longName")) } "snake case encoder encodes keys in snake_case manner" in { val encodedKeys = allJsonKeys(encoder.snakeCase(instance)) assert(encodedKeys.map(_.snakeCase) == encodedKeys) } "encoded snake_case is decoded in camelCase" in { val encodedDecoded = decoder.camelCase.decodeJson(encoder.snakeCase(instance)) assert(encodedDecoded.contains(instance)) } def allJsonKeys(json: Json): List[String] = json.asObject.toList.flatMap(_.toList).flatMap { case (k, json) => k :: allJsonKeys(json) } }
Example 73
Source File: AjaxClient.scala From canoe with MIT License | 5 votes |
package canoe.api.clients import canoe.api.{FailedMethod, ResponseDecodingError, TelegramClient} import canoe.methods.Method import canoe.models.Response import cats.effect.{Async, ContextShift} import cats.syntax.all._ import io.circe.Decoder import io.circe.parser.decode import org.scalajs.dom.console import org.scalajs.dom.ext.Ajax private[api] class AjaxClient[F[_]: Async: ContextShift](token: String) extends TelegramClient[F] { private val botApiUri: String = s"https://api.telegram.org/bot$token" def execute[Req, Res](request: Req)(implicit M: Method[Req, Res]): F[Res] = { implicit val responseDecoder: Decoder[Response[Res]] = Response.decoder[Res](M.decoder) sendJsonRequest(request, M).map(decode[Response[Res]]).flatMap { case Left(error) => handleUnknownEntity(M.name, request, error.getMessage) case Right(response) => handleTelegramResponse(M, request)(response) } } private def handleUnknownEntity[I, A](method: String, input: I, error: String): F[A] = { console.error( s"Received unknown Telegram entity during execution of '$method' method. \nInput data: $input. \n${error}" ) ResponseDecodingError(error.toString).raiseError[F, A] } private def handleTelegramResponse[A, I, C](m: Method[I, A], input: I)(response: Response[A]): F[A] = response match { case Response(true, Some(result), _, _, _) => result.pure[F] case failed => console.error(s"Received failed response from Telegram: $failed. Method name: ${m.name}, input data: $input") FailedMethod(m, input, failed).raiseError[F, A] } private def sendJsonRequest[Req, Res](request: Req, method: Method[Req, Res]): F[String] = { val url = s"$botApiUri/${method.name}" val json = method.encoder.apply(request).toString Async .fromFuture(F.delay(Ajax.post(url, json, headers = Map("Content-Type" -> "application/json")))) .map(_.responseText) } }
Example 74
Source File: package.scala From scalanda-v20 with MIT License | 5 votes |
package com.msilb.scalandav20.model import java.time.Instant import com.msilb.scalandav20.model.primitives.{DecimalNumber, InstrumentName} import io.circe.generic.JsonCodec import io.circe.generic.extras.semiauto.{deriveEnumerationDecoder, deriveEnumerationEncoder} import io.circe.syntax._ import io.circe.{Decoder, Encoder} import io.circe.java8.time._ package object pricing { type PriceValue = String sealed trait PricingStreamItem @JsonCodec case class PricingHeartbeat(`type`: String, time: Instant) extends PricingStreamItem sealed trait PriceStatus object PriceStatus { case object tradeable extends PriceStatus case object `non-tradeable` extends PriceStatus case object invalid extends PriceStatus implicit val decodePriceStatus: Decoder[PriceStatus] = deriveEnumerationDecoder implicit val encodePriceStatus: Encoder[PriceStatus] = deriveEnumerationEncoder } @JsonCodec case class PriceBucket(price: PriceValue, liquidity: Int) @JsonCodec case class QuoteHomeConversionFactors(positiveUnits: DecimalNumber, negativeUnits: DecimalNumber) @JsonCodec case class UnitsAvailableDetails(long: DecimalNumber, short: DecimalNumber) @JsonCodec case class UnitsAvailable(default: UnitsAvailableDetails, reduceFirst: UnitsAvailableDetails, reduceOnly: UnitsAvailableDetails, openOnly: UnitsAvailableDetails) @JsonCodec case class Price(`type`: String, instrument: InstrumentName, time: Instant, status: PriceStatus, bids: Seq[PriceBucket], asks: Seq[PriceBucket], closeoutBid: PriceValue, closeoutAsk: PriceValue, quoteHomeConversionFactors: Option[QuoteHomeConversionFactors], unitsAvailable: Option[UnitsAvailable]) extends PricingStreamItem object PricingStreamItem { implicit val decodePricingStreamItem: Decoder[PricingStreamItem] = Decoder.instance { c => c.downField("type").as[String].flatMap { case "HEARTBEAT" => c.as[PricingHeartbeat] case _ => c.as[Price] } } implicit val encodePricingStreamItem: Encoder[PricingStreamItem] = Encoder.instance { case t: PricingHeartbeat => t.asJson case t: Price => t.asJson } } }
Example 75
Source File: JsonToCsv.scala From temperature-machine with Apache License 2.0 | 5 votes |
package bad.robot.temperature import java.lang.Math.abs import java.time.Instant import java.time.ZoneId._ import java.time.format.DateTimeFormatter import java.time.format.FormatStyle._ import java.util.Locale import io.circe.Decoder import scalaz.\/ object JsonToCsv { type Row = (String, Instant, Double) val DefaultTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(SHORT).withLocale(Locale.getDefault).withZone(systemDefault()) def convert(json: => Error \/ String, formatter: DateTimeFormatter): Error \/ String = { for { string <- json series <- decodeAsDisjunction[List[Series]](string) } yield { toCsv(series, formatter) } } private def toCsv(series: List[Series], formatter: DateTimeFormatter) = { val quote = "\"" def toRows: List[Row] = for { reading <- series measurement <- reading.data } yield { (reading.label, measurement.time, measurement.temperature.celsius) } def toCsv(rows: List[Row]): List[String] = { val enquote: String => String = value => s"$quote$value$quote" val heading = List( enquote("Sensor"), enquote("Time"), enquote("Temperature"), enquote("Difference") ).mkString(",") if (rows.isEmpty) return Nil val tuples = rows.map(x => (x._1, x._2, x._3, "0")) val rowsWithPercentageDifference = tuples.drop(1).scan(tuples.head) { case (previous, current) => (current._1, current._2, current._3, f"${abs(current._3 - previous._3)}%.2f") } heading :: rowsWithPercentageDifference.map(row => List( enquote(row._1), enquote(formatter.format(row._2)), enquote(row._3.toString), enquote(row._4.toString) ).mkString(",")) } toCsv(toRows).mkString(sys.props("line.separator")) } } object Series { import io.circe.generic.semiauto._ implicit val dataCodec: Decoder[Series] = deriveDecoder[Series] } case class Series(label: String, data: List[Data]) object Data { import io.circe.generic.semiauto._ implicit val seriesCodec: Decoder[Data] = deriveDecoder[Data] } case class Data(x: Long, y: String) { def time: Instant = Instant.ofEpochMilli(x) def temperature: Temperature = Temperature(y.toDouble) }
Example 76
Source File: QueriesEndpoints.scala From endpoints4s with MIT License | 5 votes |
package cqrs.queries import java.util.UUID import endpoints4s.algebra.{BuiltInErrors, MuxEndpoints, MuxRequest, circe} import io.circe.{Decoder, Encoder, Json} import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} // TODO Enrich with failure information //#mux-responses sealed trait QueryResp case class MaybeResource(value: Option[Meter]) extends QueryResp case class ResourceList(value: List[Meter]) extends QueryResp //#mux-responses object QueryResp { implicit val queryDecoder: Decoder[QueryResp] = deriveDecoder implicit val queryEncoder: Encoder[QueryResp] = deriveEncoder }
Example 77
Source File: CommandsEndpoints.scala From endpoints4s with MIT License | 5 votes |
package cqrs.commands import java.time.Instant import java.util.UUID import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} import io.circe.{Decoder, Encoder} //#endpoints import endpoints4s.algebra.Endpoints import endpoints4s.algebra.circe.JsonEntitiesFromCodecs trait CommandsEndpoints extends Endpoints with JsonEntitiesFromCodecs { //#microservice-endpoint-description case class AddRecord(meterId: UUID, date: Instant, value: BigDecimal) extends UpdateCommand object Command { implicit val decoder: Decoder[Command] = deriveDecoder implicit val encoder: Encoder[Command] = deriveEncoder } case class StoredEvent(timestamp: Long, event: Event) object StoredEvent { implicit val decoder: Decoder[StoredEvent] = deriveDecoder implicit val encoder: Encoder[StoredEvent] = deriveEncoder } sealed trait Event case class MeterCreated(id: UUID, label: String) extends Event case class RecordAdded(id: UUID, date: Instant, value: BigDecimal) extends Event object Event { implicit val decoder: Decoder[Event] = deriveDecoder implicit val encoder: Encoder[Event] = deriveEncoder }
Example 78
Source File: ErrorCode.scala From lsp4s with Apache License 2.0 | 5 votes |
package scala.meta.jsonrpc import io.circe.Decoder import io.circe.Encoder sealed abstract class ErrorCode(val value: Int) case object ErrorCode { case object ParseError extends ErrorCode(-32700) case object InvalidRequest extends ErrorCode(-32600) case object MethodNotFound extends ErrorCode(-32601) case object InvalidParams extends ErrorCode(-32602) case object InternalError extends ErrorCode(-32603) case object RequestCancelled extends ErrorCode(-32800) // Server error: -32000 to -32099 case class Unknown(override val value: Int) extends ErrorCode(value) val builtin: Array[ErrorCode] = Array( ParseError, InvalidRequest, MethodNotFound, InvalidParams, InternalError, RequestCancelled ) implicit val encoder: Encoder[ErrorCode] = Encoder.encodeInt.contramap(_.value) implicit val decoder: Decoder[ErrorCode] = Decoder.decodeInt.map(i => builtin.find(_.value == i).getOrElse(Unknown(i))) }
Example 79
Source File: Endpoint.scala From lsp4s with Apache License 2.0 | 5 votes |
package scala.meta.jsonrpc import io.circe.Decoder import io.circe.Encoder import monix.eval.Task import monix.execution.Ack import scala.concurrent.Future class Endpoint[A: Decoder: Encoder, B: Decoder: Encoder](val method: String) { def encoderA: Encoder[A] = implicitly def decoderA: Decoder[A] = implicitly def encoderB: Encoder[B] = implicitly def decoderB: Decoder[B] = implicitly def request(request: A)( implicit client: JsonRpcClient ): Task[Either[Response.Error, B]] = client.request[A, B](method, request) def notify( notification: A )(implicit client: JsonRpcClient): Future[Ack] = client.notify[A](method, notification) } object Endpoint { def request[A: Decoder: Encoder, B: Decoder: Encoder]( method: String ): Endpoint[A, B] = new Endpoint(method) def notification[A: Decoder: Encoder](method: String): Endpoint[A, Unit] = new Endpoint(method) }
Example 80
Source File: RequestId.scala From lsp4s with Apache License 2.0 | 5 votes |
package scala.meta.jsonrpc import io.circe.Json import io.circe.Decoder import io.circe.Encoder sealed trait RequestId object RequestId { def apply(n: Int): RequestId.String = RequestId.String(Json.fromString(n.toString)) implicit val decoder: Decoder[RequestId] = Decoder.decodeJson.map { case s if s.isString => RequestId.String(s) case n if n.isNumber => RequestId.Number(n) case n if n.isNull => RequestId.Null } implicit val encoder: Encoder[RequestId] = Encoder.encodeJson.contramap { case RequestId.Number(v) => v case RequestId.String(v) => v case RequestId.Null => Json.Null } // implicit val encoder: Decoder = case class Number(value: Json) extends RequestId case class String(value: Json) extends RequestId case object Null extends RequestId }
Example 81
Source File: JsonRpcClient.scala From lsp4s with Apache License 2.0 | 5 votes |
package scala.meta.jsonrpc import scala.concurrent.Future import io.circe.Decoder import io.circe.Encoder import monix.eval.Task import monix.execution.Ack trait JsonRpcClient { final def notify[A]( endpoint: Endpoint[A, Unit], notification: A ): Future[Ack] = notify[A](endpoint.method, notification)(endpoint.encoderA) def notify[A: Encoder](method: String, notification: A): Future[Ack] def serverRespond(response: Response): Future[Ack] def clientRespond(response: Response): Unit final def request[A, B]( endpoint: Endpoint[A, B], req: A ): Task[Either[Response.Error, B]] = request[A, B](endpoint.method, req)(endpoint.encoderA, endpoint.decoderB) def request[A: Encoder, B: Decoder]( method: String, request: A ): Task[Either[Response.Error, B]] } object JsonRpcClient { val empty: JsonRpcClient = new JsonRpcClient { override def notify[A: Encoder]( method: String, notification: A ): Future[Ack] = Ack.Continue override def serverRespond(response: Response): Future[Ack] = Ack.Continue override def clientRespond(response: Response): Unit = () override def request[A: Encoder, B: Decoder]( method: String, request: A ): Task[Either[Response.Error, B]] = Task.never } }
Example 82
Source File: LanguageClient.scala From lsp4s with Apache License 2.0 | 5 votes |
package scala.meta.jsonrpc import cats.syntax.either._ import io.circe.Decoder import io.circe.Encoder import io.circe.syntax._ import java.io.OutputStream import java.nio.ByteBuffer import monix.eval.Callback import monix.eval.Task import monix.execution.Ack import monix.execution.Cancelable import monix.execution.atomic.Atomic import monix.execution.atomic.AtomicInt import monix.reactive.Observer import scala.collection.concurrent.TrieMap import scala.concurrent.Future import scala.concurrent.duration.Duration import MonixEnrichments._ import scribe.LoggerSupport class LanguageClient(out: Observer[ByteBuffer], logger: LoggerSupport) extends JsonRpcClient { def this(out: OutputStream, logger: LoggerSupport) = this(Observer.fromOutputStream(out, logger), logger) private val writer = new MessageWriter(out, logger) private val counter: AtomicInt = Atomic(1) private val activeServerRequests = TrieMap.empty[RequestId, Callback[Response]] def notify[A: Encoder](method: String, notification: A): Future[Ack] = writer.write(Notification(method, Some(notification.asJson))) def serverRespond(response: Response): Future[Ack] = response match { case Response.Empty => Ack.Continue case x: Response.Success => writer.write(x) case x: Response.Error => logger.error(s"Response error: $x") writer.write(x) } def clientRespond(response: Response): Unit = for { id <- response match { case Response.Empty => None case Response.Success(_, requestId) => Some(requestId) case Response.Error(_, requestId) => Some(requestId) } callback <- activeServerRequests.get(id).orElse { logger.error(s"Response to unknown request: $response") None } } { activeServerRequests.remove(id) callback.onSuccess(response) } def request[A: Encoder, B: Decoder]( method: String, request: A ): Task[Either[Response.Error, B]] = { val nextId = RequestId(counter.incrementAndGet()) val response = Task.create[Response] { (out, cb) => val scheduled = out.scheduleOnce(Duration(0, "s")) { val json = Request(method, Some(request.asJson), nextId) activeServerRequests.put(nextId, cb) writer.write(json) } Cancelable { () => scheduled.cancel() this.notify("$/cancelRequest", CancelParams(nextId.value)) } } response.map { case Response.Empty => Left( Response.invalidParams( s"Got empty response for request $request", nextId ) ) case err: Response.Error => Left(err) case Response.Success(result, _) => result.as[B].leftMap { err => Response.invalidParams(err.toString, nextId) } } } } object LanguageClient { def fromOutputStream(out: OutputStream, logger: LoggerSupport) = new LanguageClient(Observer.fromOutputStream(out, logger), logger) }
Example 83
Source File: Message.scala From lsp4s with Apache License 2.0 | 5 votes |
package scala.meta.jsonrpc import monix.eval.Task import io.circe.Json import io.circe.Decoder import io.circe.Encoder import io.circe.JsonObject import io.circe.derivation.annotations.JsonCodec import io.circe.syntax._ import cats.syntax.either._ sealed trait Message object Message { implicit val encoder: Encoder[Message] = new Encoder[Message] { override def apply(a: Message): Json = { val json = a match { case r: Request => r.asJson case r: Notification => r.asJson case r: Response => r.asJson } json.mapObject(_.add("jsonrpc", "2.0".asJson)) } } implicit val decoder: Decoder[Message] = Decoder.decodeJsonObject.emap { obj => val json = Json.fromJsonObject(obj) val result = if (obj.contains("id")) if (obj.contains("error")) json.as[Response.Error] else if (obj.contains("result")) json.as[Response.Success] else json.as[Request] else json.as[Notification] result.leftMap(_.toString) } } @JsonCodec case class Request( method: String, params: Option[Json], id: RequestId ) extends Message { def toError(code: ErrorCode, message: String): Response = Response.error(ErrorObject(code, message, None), id) } @JsonCodec case class Notification(method: String, params: Option[Json]) extends Message sealed trait Response extends Message { def isSuccess: Boolean = this.isInstanceOf[Response.Success] } object Response { implicit val encoderResponse: Encoder[Response] = new Encoder[Response] { override def apply(a: Response): Json = a match { case r: Response.Success => r.asJson case r: Response.Error => r.asJson case Response.Empty => JsonObject.empty.asJson } } @JsonCodec case class Success(result: Json, id: RequestId) extends Response @JsonCodec case class Error(error: ErrorObject, id: RequestId) extends Response case object Empty extends Response def empty: Response = Empty def ok(result: Json, id: RequestId): Response = success(result, id) def okAsync[T](value: T): Task[Either[Response.Error, T]] = Task(Right(value)) def success(result: Json, id: RequestId): Response = Success(result, id) def error(error: ErrorObject, id: RequestId): Response.Error = Error(error, id) def internalError(message: String): Response.Error = internalError(message, RequestId.Null) def internalError(message: String, id: RequestId): Response.Error = Error(ErrorObject(ErrorCode.InternalError, message, None), id) def invalidParams(message: String): Response.Error = invalidParams(message, RequestId.Null) def invalidParams(message: String, id: RequestId): Response.Error = Error(ErrorObject(ErrorCode.InvalidParams, message, None), id) def invalidRequest(message: String): Response.Error = Error( ErrorObject(ErrorCode.InvalidRequest, message, None), RequestId.Null ) def cancelled(id: Json): Response.Error = Error( ErrorObject(ErrorCode.RequestCancelled, "", None), id.as[RequestId].getOrElse(RequestId.Null) ) def parseError(message: String): Response.Error = Error(ErrorObject(ErrorCode.ParseError, message, None), RequestId.Null) def methodNotFound(message: String, id: RequestId): Response.Error = Error(ErrorObject(ErrorCode.MethodNotFound, message, None), id) }
Example 84
Source File: Json.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.bitbucketserver.http4s import cats.data.NonEmptyList import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} import io.circe.{Decoder, Encoder} import org.http4s.Uri import org.scalasteward.core.git.Sha1 import org.scalasteward.core.vcs.data.PullRequestState object Json { case class Page[A](values: List[A]) case class Repo(id: Int, name: String, forkable: Boolean, project: Project, links: Links) case class Project(key: String) type Links = Map[String, NonEmptyList[Link]] case class Link(href: Uri, name: Option[String]) case class PR(title: String, state: PullRequestState, links: Links) case class NewPR( title: String, description: String, state: PullRequestState, open: Boolean, closed: Boolean, fromRef: Ref, toRef: Ref, locked: Boolean, reviewers: List[Reviewer] ) case class Ref(id: String, repository: Repository) case class Repository(slug: String, project: Project) case class Condition(reviewers: List[DefaultReviewer]) case class DefaultReviewer(name: String) case class Reviewer(user: User) case class User(name: String) case class Branches(values: NonEmptyList[Branch]) case class Branch(id: String, latestCommit: Sha1) implicit def pageDecode[A: Decoder]: Decoder[Page[A]] = deriveDecoder implicit val repoDecode: Decoder[Repo] = deriveDecoder implicit val projectDecode: Decoder[Project] = deriveDecoder implicit val linkDecoder: Decoder[Link] = deriveDecoder implicit val uriDecoder: Decoder[Uri] = Decoder.decodeString.map(Uri.unsafeFromString) implicit val prDecoder: Decoder[PR] = deriveDecoder implicit val reviewerDecoder: Decoder[Reviewer] = deriveDecoder implicit val userDecoder: Decoder[User] = deriveDecoder implicit val defaultReviewerDecoder: Decoder[DefaultReviewer] = deriveDecoder implicit val conditionDecoder: Decoder[Condition] = deriveDecoder implicit val branchDecoder: Decoder[Branch] = deriveDecoder implicit val branchesDecoder: Decoder[Branches] = deriveDecoder implicit val encodeNewPR: Encoder[NewPR] = deriveEncoder implicit val encodeRef: Encoder[Ref] = deriveEncoder implicit val encodeRepository: Encoder[Repository] = deriveEncoder implicit val encodeProject: Encoder[Project] = deriveEncoder implicit val encodeReviewer: Encoder[Reviewer] = deriveEncoder implicit val encodeUser: Encoder[User] = deriveEncoder }
Example 85
Source File: Sha1.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.git import cats.Eq import cats.implicits._ import eu.timepit.refined.W import eu.timepit.refined.api.{Refined, RefinedTypeOps} import eu.timepit.refined.boolean.{And, Or} import eu.timepit.refined.char.Digit import eu.timepit.refined.collection.{Forall, Size} import eu.timepit.refined.generic.Equal import eu.timepit.refined.numeric.Interval import io.circe.refined._ import io.circe.{Decoder, Encoder} import org.scalasteward.core.git.Sha1.HexString final case class Sha1(value: HexString) object Sha1 { type HexDigit = Digit Or Interval.Closed[W.`'a'`.T, W.`'f'`.T] type HexString = String Refined (Forall[HexDigit] And Size[Equal[W.`40`.T]]) object HexString extends RefinedTypeOps[HexString, String] def from(s: String): Either[Throwable, Sha1] = HexString.from(s).bimap(new Throwable(_), Sha1.apply) implicit val sha1Eq: Eq[Sha1] = Eq.by(_.value.value) implicit val sha1Decoder: Decoder[Sha1] = Decoder[HexString].map(Sha1.apply) implicit val sha1Encoder: Encoder[Sha1] = Encoder[HexString].contramap(_.value) }
Example 86
Source File: UpdatePattern.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.repoconfig import cats.implicits._ import io.circe.generic.semiauto._ import io.circe.{Decoder, Encoder, HCursor} import org.scalasteward.core.data.{GroupId, Update} final case class UpdatePattern( groupId: GroupId, artifactId: Option[String], version: Option[UpdatePattern.Version] ) object UpdatePattern { final case class MatchResult( byArtifactId: List[UpdatePattern], filteredVersions: List[String] ) final case class Version(prefix: Option[String], suffix: Option[String]) { def matches(version: String): Boolean = suffix.forall(version.endsWith) && prefix.forall(version.startsWith) } def findMatch( patterns: List[UpdatePattern], update: Update.Single, include: Boolean ): MatchResult = { val byGroupId = patterns.filter(_.groupId === update.groupId) val byArtifactId = byGroupId.filter(_.artifactId.forall(_ === update.artifactId.name)) val filteredVersions = update.newerVersions.filter(newVersion => byArtifactId.exists(_.version.forall(_.matches(newVersion))) === include ) MatchResult(byArtifactId, filteredVersions) } implicit val updatePatternDecoder: Decoder[UpdatePattern] = deriveDecoder implicit val updatePatternEncoder: Encoder[UpdatePattern] = deriveEncoder implicit val updatePatternVersionDecoder: Decoder[Version] = Decoder[String] .map(s => Version(Some(s), None)) .or((hCursor: HCursor) => for { prefix <- hCursor.downField("prefix").as[Option[String]] suffix <- hCursor.downField("suffix").as[Option[String]] } yield Version(prefix, suffix) ) implicit val updatePatternVersionEncoder: Encoder[Version] = deriveEncoder }
Example 87
Source File: PullRequestUpdateStrategy.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.repoconfig import cats.Eq import io.circe.{Decoder, Encoder} sealed trait PullRequestUpdateStrategy { def name: String } object PullRequestUpdateStrategy { final case object Always extends PullRequestUpdateStrategy { val name = "always" } final case object OnConflicts extends PullRequestUpdateStrategy { val name = "on-conflicts" } final case object Never extends PullRequestUpdateStrategy { val name = "never" } val default: PullRequestUpdateStrategy = OnConflicts def fromString(value: String): PullRequestUpdateStrategy = value.trim.toLowerCase match { case "on-conflicts" => OnConflicts case "never" => Never case "always" => Always case _ => default } def fromBoolean(value: Boolean): PullRequestUpdateStrategy = if (value) OnConflicts else Never implicit val prUpdateStrategyDecoder: Decoder[PullRequestUpdateStrategy] = Decoder[Boolean].map(fromBoolean).or(Decoder[String].map(fromString)) implicit val prUpdateStrategyEncoder: Encoder[PullRequestUpdateStrategy] = Encoder[String].contramap(_.name) implicit val eqPRUpdateStrategy: Eq[PullRequestUpdateStrategy] = Eq.fromUniversalEquals }
Example 88
Source File: PullRequestFrequency.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.repoconfig import cats.Eq import cats.implicits._ import cron4s.lib.javatime._ import io.circe.{Decoder, Encoder} import org.scalasteward.core.repoconfig.PullRequestFrequency._ import org.scalasteward.core.util.Timestamp import scala.concurrent.duration._ sealed trait PullRequestFrequency { def render: String def onSchedule(now: Timestamp): Boolean = this match { case CronExpr(expr) => expr.datePart.allOf(now.toLocalDateTime) case _ => true } def waitingTime(lastCreated: Timestamp, now: Timestamp): Option[FiniteDuration] = { val nextPossible = this match { case Asap => None case Daily => Some(lastCreated + 1.day) case Weekly => Some(lastCreated + 7.days) case Monthly => Some(lastCreated + 30.days) case CronExpr(expr) => expr.next(lastCreated.toLocalDateTime).map(Timestamp.fromLocalDateTime) } nextPossible.map(now.until).filter(_.length > 0) } } object PullRequestFrequency { case object Asap extends PullRequestFrequency { val render = "@asap" } case object Daily extends PullRequestFrequency { val render = "@daily" } case object Weekly extends PullRequestFrequency { val render = "@weekly" } case object Monthly extends PullRequestFrequency { val render = "@monthly" } final case class CronExpr(expr: cron4s.CronExpr) extends PullRequestFrequency { val render: String = expr.toString } val default: PullRequestFrequency = Asap def fromString(s: String): Either[String, PullRequestFrequency] = s.trim.toLowerCase match { case Asap.render => Right(Asap) case Daily.render => Right(Daily) case Weekly.render => Right(Weekly) case Monthly.render => Right(Monthly) case other => // cron4s requires exactly 6 fields, but we also want to support the more // common format with 5 fields. Therefore we're prepending the "seconds" // field ourselves if parsing the original string fails. parseCron4s(other).orElse(parseCron4s("0 " + other)).leftMap(_.toString).map(CronExpr.apply) } private def parseCron4s(s: String): Either[Throwable, cron4s.CronExpr] = Either.catchNonFatal(cron4s.Cron.unsafeParse(s)) implicit val pullRequestFrequencyEq: Eq[PullRequestFrequency] = Eq.fromUniversalEquals implicit val pullRequestFrequencyDecoder: Decoder[PullRequestFrequency] = Decoder[String].emap(fromString) implicit val pullRequestFrequencyEncoder: Encoder[PullRequestFrequency] = Encoder[String].contramap(_.render) }
Example 89
Source File: UpdatesConfig.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.repoconfig import eu.timepit.refined.types.numeric.PosInt import io.circe.generic.extras.Configuration import io.circe.generic.extras.semiauto._ import io.circe.refined._ import io.circe.{Decoder, Encoder} import org.scalasteward.core.data.Update import org.scalasteward.core.update.FilterAlg.{ FilterResult, IgnoredByConfig, NotAllowedByConfig, VersionPinnedByConfig } import org.scalasteward.core.util.Nel final case class UpdatesConfig( pin: List[UpdatePattern] = List.empty, allow: List[UpdatePattern] = List.empty, ignore: List[UpdatePattern] = List.empty, limit: Option[PosInt] = None, includeScala: Option[Boolean] = None, fileExtensions: List[String] = List.empty ) { def keep(update: Update.Single): FilterResult = isAllowed(update).flatMap(isPinned).flatMap(isIgnored) def fileExtensionsOrDefault: Set[String] = if (fileExtensions.isEmpty) UpdatesConfig.defaultFileExtensions else fileExtensions.toSet private def isAllowed(update: Update.Single): FilterResult = { val m = UpdatePattern.findMatch(allow, update, include = true) if (m.filteredVersions.nonEmpty) Right(update.copy(newerVersions = Nel.fromListUnsafe(m.filteredVersions))) else if (allow.isEmpty) Right(update) else Left(NotAllowedByConfig(update)) } private def isPinned(update: Update.Single): FilterResult = { val m = UpdatePattern.findMatch(pin, update, include = true) if (m.filteredVersions.nonEmpty) Right(update.copy(newerVersions = Nel.fromListUnsafe(m.filteredVersions))) else if (m.byArtifactId.isEmpty) Right(update) else Left(VersionPinnedByConfig(update)) } private def isIgnored(update: Update.Single): FilterResult = { val m = UpdatePattern.findMatch(ignore, update, include = false) if (m.filteredVersions.nonEmpty) Right(update.copy(newerVersions = Nel.fromListUnsafe(m.filteredVersions))) else Left(IgnoredByConfig(update)) } } object UpdatesConfig { implicit val customConfig: Configuration = Configuration.default.withDefaults implicit val updatesConfigDecoder: Decoder[UpdatesConfig] = deriveConfiguredDecoder implicit val updatesConfigEncoder: Encoder[UpdatesConfig] = deriveConfiguredEncoder val defaultIncludeScala: Boolean = false val defaultFileExtensions: Set[String] = Set(".scala", ".sbt", ".sbt.shared", ".sc", ".yml", "pom.xml") // prevent IntelliJ from removing the import of io.circe.refined._ locally(refinedDecoder: Decoder[PosInt]) }
Example 90
Source File: Scope.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.data import cats.implicits._ import cats.{Applicative, Eval, Order, Traverse} import io.circe.generic.semiauto.deriveCodec import io.circe.{Codec, Decoder, Encoder} final case class Scope[A](value: A, resolvers: List[Resolver]) object Scope { type Dependency = Scope[org.scalasteward.core.data.Dependency] type Dependencies = Scope[List[org.scalasteward.core.data.Dependency]] implicit def scopeTraverse: Traverse[Scope] = new Traverse[Scope] { override def traverse[G[_]: Applicative, A, B](fa: Scope[A])(f: A => G[B]): G[Scope[B]] = f(fa.value).map(b => fa.copy(value = b)) override def foldLeft[A, B](fa: Scope[A], b: B)(f: (B, A) => B): B = f(b, fa.value) override def foldRight[A, B](fa: Scope[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = f(fa.value, lb) } implicit def scopeCodec[A: Decoder: Encoder]: Codec[Scope[A]] = deriveCodec implicit def scopeOrder[A: Order]: Order[Scope[A]] = Order.by((scope: Scope[A]) => (scope.value, scope.resolvers)) }
Example 91
Source File: JsonKeyValueStore.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.persistence import better.files.File import cats.Monad import cats.implicits._ import io.chrisdavenport.log4cats.Logger import io.circe.parser.decode import io.circe.syntax._ import io.circe.{Decoder, Encoder, KeyEncoder} import org.scalasteward.core.io.{FileAlg, WorkspaceAlg} final class JsonKeyValueStore[F[_], K, V]( name: String, schemaVersion: String, maybePrefix: Option[String] = None )(implicit fileAlg: FileAlg[F], keyEncoder: KeyEncoder[K], logger: Logger[F], valueDecoder: Decoder[V], valueEncoder: Encoder[V], workspaceAlg: WorkspaceAlg[F], F: Monad[F] ) extends KeyValueStore[F, K, V] { override def get(key: K): F[Option[V]] = jsonFile(key).flatMap { file => fileAlg.readFile(file).flatMap { case Some(content) => decode[Option[V]](content) match { case Right(maybeValue) => F.pure(maybeValue) case Left(error) => logger.error(error)(s"Failed to parse or decode JSON from $file").as(Option.empty[V]) } case None => F.pure(Option.empty[V]) } } override def put(key: K, value: V): F[Unit] = write(key, Some(value)) override def modifyF(key: K)(f: Option[V] => F[Option[V]]): F[Option[V]] = get(key).flatMap(maybeValue => f(maybeValue).flatTap(write(key, _))) private def jsonFile(key: K): F[File] = { val keyPath = maybePrefix.fold("")(_ + "/") + keyEncoder(key) workspaceAlg.rootDir.map(_ / "store" / name / s"v$schemaVersion" / keyPath / s"$name.json") } private def write(key: K, value: Option[V]): F[Unit] = jsonFile(key).flatMap(fileAlg.writeFile(_, value.asJson.toString)) }
Example 92
Source File: GroupMigrations.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.update import cats.implicits._ import io.circe.Decoder import io.circe.config.parser import io.circe.generic.extras.{semiauto, Configuration} import org.scalasteward.core.application.Config import org.scalasteward.core.data._ import org.scalasteward.core.io.FileAlg import org.scalasteward.core.util.{MonadThrowable, Nel} trait GroupMigrations { def findUpdateWithNewerGroupId(dependency: Dependency): Option[Update.Single] } object GroupMigrations { def create[F[_]: MonadThrowable](implicit fileAlg: FileAlg[F], config: Config ): F[GroupMigrations] = { val migrationSources = { val fromParameters: F[Option[String]] = config.groupMigrations.traverse(fileAlg.readFile(_)).flatMap { case None => none[String].pure[F] case Some(None) => new Throwable("Couldn't read the file with custom group migrations") .raiseError[F, Option[String]] case Some(Some(text)) => text.some.pure[F] } List( fileAlg.readResource("group-migrations.conf").map(List(_)), fromParameters.map(_.toList) ).flatSequence } val decodeFile: String => F[GroupIdChanges] = parser .decode[GroupIdChanges](_) .leftMap(e => new Throwable("Couldn't decode migrations file", e)) .liftTo[F] migrationSources .flatMap(_.traverse(decodeFile)) .map(_.flatMap(_.changes)) .map(migrations => dependency => migrateGroupId(dependency, migrations)) } def migrateGroupId( dependency: Dependency, migrations: List[GroupIdChange] ): Option[Update.Single] = migrations.view .filter(_.before === dependency.groupId) .find(_.artifactId === dependency.artifactId.name) .map { migration => Update.Single( CrossDependency(dependency), Nel.one(migration.initialVersion), Some(migration.after) ) } implicit val customConfig: Configuration = Configuration.default.withDefaults final case class GroupIdChanges(changes: List[GroupIdChange]) object GroupIdChanges { implicit val decoder: Decoder[GroupIdChanges] = semiauto.deriveConfiguredDecoder } final case class GroupIdChange( before: GroupId, after: GroupId, artifactId: String, initialVersion: String ) object GroupIdChange { implicit val decoder: Decoder[GroupIdChange] = semiauto.deriveConfiguredDecoder } }
Example 93
Source File: PullRequestOut.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.vcs.data import cats.implicits._ import io.circe.Decoder import io.circe.generic.semiauto._ import org.http4s.Uri import org.scalasteward.core.util.uri.uriDecoder import org.scalasteward.core.vcs.data.PullRequestState.Closed final case class PullRequestOut( html_url: Uri, state: PullRequestState, title: String ) { def isClosed: Boolean = state === Closed } object PullRequestOut { implicit val pullRequestOutDecoder: Decoder[PullRequestOut] = deriveDecoder // prevent IntelliJ from removing the import of uriDecoder locally(uriDecoder) }
Example 94
Source File: PullRequestState.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.vcs.data import cats.Eq import io.circe.{Decoder, Encoder} sealed trait PullRequestState object PullRequestState { case object Open extends PullRequestState case object Closed extends PullRequestState implicit val pullRequestStateEq: Eq[PullRequestState] = Eq.fromUniversalEquals implicit val pullRequestStateDecoder: Decoder[PullRequestState] = Decoder[String].emap { _.toLowerCase match { case "open" | "opened" => Right(Open) case "closed" | "merged" | "declined" => Right(Closed) case unknown => Left(s"Unexpected string '$unknown'") } } implicit val pullRequestStateEncoder: Encoder[PullRequestState] = Encoder[String].contramap { case Open => "open" case Closed => "closed" } }
Example 95
Source File: RepoOut.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.vcs.data import io.circe.Decoder import io.circe.generic.semiauto._ import org.http4s.Uri import org.scalasteward.core.git.Branch import org.scalasteward.core.util.ApplicativeThrowable import org.scalasteward.core.util.uri.uriDecoder final case class RepoOut( name: String, owner: UserOut, parent: Option[RepoOut], clone_url: Uri, default_branch: Branch ) { def parentOrRaise[F[_]](implicit F: ApplicativeThrowable[F]): F[RepoOut] = parent.fold(F.raiseError[RepoOut](new Throwable(s"repo $name has no parent")))(F.pure) def repo: Repo = Repo(owner.login, name) } object RepoOut { implicit val repoOutDecoder: Decoder[RepoOut] = deriveDecoder // prevent IntelliJ from removing the import of uriDecoder locally(uriDecoder) }
Example 96
Source File: RepositoryResponse.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.bitbucket.http4s import cats.implicits._ import io.circe.{ACursor, Decoder, DecodingFailure, Json} import org.http4s.Uri import org.scalasteward.core.git.Branch import org.scalasteward.core.util.uri._ import org.scalasteward.core.vcs.data.{Repo, UserOut} import scala.annotation.tailrec final private[http4s] case class RepositoryResponse( name: String, mainBranch: Branch, owner: UserOut, httpsCloneUrl: Uri, parent: Option[Repo] ) private[http4s] object RepositoryResponse { implicit private val repoDecoder: Decoder[Repo] = Decoder.instance { c => c.as[String].map(_.split('/')).flatMap { parts => parts match { case Array(owner, name) => Repo(owner, name).asRight case _ => DecodingFailure("Repo", c.history).asLeft } } } implicit val decoder: Decoder[RepositoryResponse] = Decoder.instance { c => for { name <- c.downField("name").as[String] owner <- c.downField("owner") .downField("username") .as[String] .orElse(c.downField("owner").downField("nickname").as[String]) cloneUrl <- c.downField("links") .downField("clone") .downAt { p => p.asObject .flatMap(o => o("name")) .flatMap(_.asString) .contains("https") } .downField("href") .as[Uri] defaultBranch <- c.downField("mainbranch").downField("name").as[Branch] maybeParent <- c.downField("parent").downField("full_name").as[Option[Repo]] } yield RepositoryResponse(name, defaultBranch, UserOut(owner), cloneUrl, maybeParent) } def downAt(p: Json => Boolean): ACursor = { @tailrec def find(c: ACursor): ACursor = if (c.succeeded) if (c.focus.exists(p)) c else find(c.right) else c find(cursor.downArray) } } }
Example 97
Source File: json.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.bitbucket.http4s import io.circe.Decoder import org.http4s.Uri import org.scalasteward.core.git.{Branch, Sha1} import org.scalasteward.core.util.uri.uriDecoder import org.scalasteward.core.vcs.data.{BranchOut, CommitOut, PullRequestOut, PullRequestState} private[http4s] object json { implicit val branchOutDecoder: Decoder[BranchOut] = Decoder.instance { c => for { branch <- c.downField("name").as[Branch] commitHash <- c.downField("target").downField("hash").as[Sha1] } yield BranchOut(branch, CommitOut(commitHash)) } implicit val pullRequestStateDecoder: Decoder[PullRequestState] = Decoder[String].emap { case "OPEN" => Right(PullRequestState.Open) case "MERGED" | "SUPERSEDED" | "DECLINED" => Right(PullRequestState.Closed) case unknown => Left(s"Unexpected string '$unknown'") } implicit val pullRequestOutDecoder: Decoder[PullRequestOut] = Decoder.instance { c => for { title <- c.downField("title").as[String] state <- c.downField("state").as[PullRequestState] html_url <- c.downField("links").downField("self").downField("href").as[Uri] } yield (PullRequestOut(html_url, state, title)) } }
Example 98
Source File: uri.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.util import cats.implicits._ import io.circe.{Decoder, KeyDecoder, KeyEncoder} import monocle.Optional import org.http4s.Uri import org.http4s.Uri.{Authority, UserInfo} object uri { implicit val uriDecoder: Decoder[Uri] = Decoder[String].emap(s => Uri.fromString(s).leftMap(_.getMessage)) implicit val uriKeyDecoder: KeyDecoder[Uri] = KeyDecoder.instance(Uri.fromString(_).toOption) implicit val uriKeyEncoder: KeyEncoder[Uri] = KeyEncoder.instance(_.renderString) val withAuthority: Optional[Uri, Authority] = Optional[Uri, Authority](_.authority)(authority => _.copy(authority = Some(authority))) val authorityWithUserInfo: Optional[Authority, UserInfo] = Optional[Authority, UserInfo](_.userInfo)(userInfo => _.copy(userInfo = Some(userInfo))) val withUserInfo: Optional[Uri, UserInfo] = authorityWithUserInfo.compose(withAuthority) }
Example 99
Source File: HttpJsonClient.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.util import cats.effect.Sync import cats.implicits._ import io.circe.{Decoder, Encoder} import org.http4s.Method.{GET, POST} import org.http4s.circe.{jsonEncoderOf, jsonOf} import org.http4s.client.Client import org.http4s._ import scala.util.control.NoStackTrace final class HttpJsonClient[F[_]: Sync](implicit client: Client[F] ) { type ModReq = Request[F] => F[Request[F]] def get[A: Decoder](uri: Uri, modify: ModReq): F[A] = request[A](GET, uri, modify) def post[A: Decoder](uri: Uri, modify: ModReq): F[A] = request[A](POST, uri, modify) def postWithBody[A: Decoder, B: Encoder](uri: Uri, body: B, modify: ModReq): F[A] = post[A](uri, modify.compose(_.withEntity(body)(jsonEncoderOf[F, B]))) private def request[A: Decoder](method: Method, uri: Uri, modify: ModReq): F[A] = client.expectOr[A](modify(Request[F](method, uri)))(resp => toUnexpectedResponse(uri, method, resp) )(jsonOf[F, A].transform(_.leftMap(failure => JsonParseError(uri, method, failure)))) private def toUnexpectedResponse( uri: Uri, method: Method, response: Response[F] ): F[Throwable] = { val body = response.body.through(fs2.text.utf8Decode).compile.string body.map(UnexpectedResponse(uri, method, response.headers, response.status, _)) } } final case class JsonParseError( uri: Uri, method: Method, underlying: DecodeFailure ) extends DecodeFailure { val message = s"uri: $uri\nmethod: $method\nmessage: ${underlying.message}" override def cause: Option[Throwable] = underlying.some override def toHttpResponse[F[_]](httpVersion: HttpVersion): Response[F] = underlying.toHttpResponse(httpVersion) } final case class UnexpectedResponse( uri: Uri, method: Method, headers: Headers, status: Status, body: String ) extends RuntimeException with NoStackTrace { override def getMessage: String = s"uri: $uri\nmethod: $method\nstatus: $status\nheaders: $headers\nbody: $body" }
Example 100
Source File: parser.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.buildtool.sbt import cats.implicits._ import io.circe.Decoder import io.circe.parser._ import org.scalasteward.core.buildtool.sbt.data.SbtVersion import org.scalasteward.core.data._ object parser { def parseBuildProperties(s: String): Option[SbtVersion] = """sbt.version\s*=\s*(.+)""".r.findFirstMatchIn(s).map(_.group(1)).map(SbtVersion.apply) def parseDependencies(lines: List[String]): List[Scope.Dependencies] = { val chunks = fs2.Stream.emits(lines).map(removeSbtNoise).split(_ === "--- snip ---") val decoder = Decoder[Dependency].either(Decoder[Resolver]) chunks.mapFilter { chunk => val (dependencies, resolvers) = chunk.toList.flatMap(decode(_)(decoder).toList).separate if (dependencies.isEmpty || resolvers.isEmpty) None else Some(Scope(dependencies, resolvers.sorted)) }.toList } private def removeSbtNoise(s: String): String = s.replace("[info]", "").trim }
Example 101
Source File: parser.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.buildtool.mill import cats.implicits._ import io.circe.{Decoder, DecodingFailure} import org.scalasteward.core.data.{ArtifactId, Dependency, GroupId, Resolver} object parser { sealed trait ParseError extends RuntimeException { def message: String final override def getMessage: String = message } case class CirceParseError(message: String, cause: io.circe.Error) extends ParseError { final override def getCause: Throwable = cause } def parseModules[F[_]]( input: String ): Either[ParseError, List[MillModule]] = for { json <- io.circe.parser .decode[Modules](input) .leftMap(CirceParseError("Failed to decode Modules", _): ParseError) } yield json.modules } case class Modules(modules: List[MillModule]) object Modules { implicit val decoder: Decoder[Modules] = Decoder.forProduct1("modules")(apply) } case class MillModule(name: String, repositories: List[Resolver], dependencies: List[Dependency]) object MillModule { val resolverDecoder: Decoder[Resolver] = Decoder.instance { c => c.downField("type").as[String].flatMap { case "maven" => for { url <- c.downField("url").as[String] creds <- c.downField("auth").as[Option[Resolver.Credentials]] } yield Resolver.MavenRepository(url, url, creds) case "ivy" => for { url <- c.downField("pattern").as[String] creds <- c.downField("auth").as[Option[Resolver.Credentials]] } yield Resolver.IvyRepository(url, url, creds) case typ => Left(DecodingFailure(s"Not a matching resolver type, $typ", c.history)) } } val dependencyDecoder: Decoder[Dependency] = Decoder.instance { c => for { groupId <- c.downField("groupId").as[GroupId] artifactId <- c.downField("artifactId").as[String].map(aid => ArtifactId(aid, None)) version <- c.downField("version").as[String] } yield Dependency(groupId, artifactId, version) } implicit val decoder: Decoder[MillModule] = Decoder.instance(c => for { name <- c.downField("name").as[String] resolvers <- c.downField("repositories").as(Decoder.decodeList(resolverDecoder)) dependencies <- c.downField("dependencies").as(Decoder.decodeList(dependencyDecoder)) } yield MillModule(name, resolvers, dependencies) ) }
Example 102
Source File: Migration.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.scalafix import io.circe.Decoder import io.circe.generic.semiauto._ import org.scalasteward.core.data.{GroupId, Version} import org.scalasteward.core.util.Nel final case class Migration( groupId: GroupId, artifactIds: Nel[String], newVersion: Version, rewriteRules: Nel[String], doc: Option[String] ) object Migration { implicit val migrationDecoder: Decoder[Migration] = deriveDecoder[Migration] }
Example 103
Source File: ScalafixMigrations.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.scalafix import io.circe.Decoder import io.circe.generic.extras.Configuration import io.circe.generic.extras.semiauto._ final case class ScalafixMigrations( disableDefaults: Boolean = false, migrations: List[Migration] = List.empty ) object ScalafixMigrations { implicit val configuration: Configuration = Configuration.default.withDefaults implicit val scalafixMigrationsDecoder: Decoder[ScalafixMigrations] = deriveConfiguredDecoder }
Example 104
Source File: VariableAliasing.scala From openlaw-core with Apache License 2.0 | 5 votes |
package org.adridadou.openlaw.parser.template import io.circe.{Decoder, Encoder} import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} import org.adridadou.openlaw.OpenlawValue import org.adridadou.openlaw.parser.template.variableTypes.VariableType import org.adridadou.openlaw.parser.template.expressions.Expression import org.adridadou.openlaw.result.{Result, Success} object VariableAliasing { implicit val variableAliasingEnc: Encoder[VariableAliasing] = deriveEncoder implicit val variableAliasingDec: Decoder[VariableAliasing] = deriveDecoder } final case class VariableAliasing(name: VariableName, expr: Expression) extends Expression with TemplatePart { def validate(executionResult: TemplateExecutionResult): Result[Unit] = if (name.isAnonymous) { Success.unit } else { expr.validate(executionResult) } override def expressionType( executionResult: TemplateExecutionResult ): Result[VariableType] = expr.expressionType(executionResult) override def evaluate( executionResult: TemplateExecutionResult ): Result[Option[OpenlawValue]] = expr.evaluate(executionResult) override def variables( executionResult: TemplateExecutionResult ): Result[List[VariableName]] = expr.variables(executionResult) override def missingInput( executionResult: TemplateExecutionResult ): Result[List[VariableName]] = expr.missingInput(executionResult) }
Example 105
Source File: SectionType.scala From openlaw-core with Apache License 2.0 | 5 votes |
package org.adridadou.openlaw.parser.template.variableTypes import cats.implicits._ import io.circe.{Decoder, Encoder} import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} import io.circe.parser.decode import org.adridadou.openlaw.{OpenlawNativeValue, OpenlawString, OpenlawValue} import org.adridadou.openlaw.parser.template.formatters.Formatter import org.adridadou.openlaw.parser.template._ import org.adridadou.openlaw.parser.template.expressions.Expression import org.adridadou.openlaw.result.{Failure, FailureException, Result, Success} final case class SectionInfo( name: Option[String], numbering: String, value: String ) extends OpenlawNativeValue case object SectionType extends VariableType(name = "Section") with NoShowInFormButRender { private implicit val enc: Encoder[SectionInfo] = deriveEncoder private implicit val dec: Decoder[SectionInfo] = deriveDecoder override def cast( value: String, executionResult: TemplateExecutionResult ): Result[SectionInfo] = decode[SectionInfo](value).leftMap(FailureException(_)) override def internalFormat(value: OpenlawValue): Result[String] = value match { case SectionInfo(_, _, value) => Success(value) case value => VariableType.convert[OpenlawString](value) } override def defaultFormatter: Formatter = new SectionFormatter override def getTypeClass: Class[SectionInfo] = classOf[SectionInfo] override def construct( constructorParams: Parameter, executionResult: TemplateExecutionResult ): Result[Option[SectionInfo]] = constructorParams match { case Parameters(seq) => val map = seq.toMap (for { numbering <- map.get("numbering") reference <- map.get("reference value") } yield for { numberingValue <- getOneValueConstant(numbering) referenceValue <- getOneValueConstant(reference) } yield SectionInfo(None, numberingValue, referenceValue)).sequence case _ => Failure("""Section requires parameters, not a unique value or a list""") } def thisType: VariableType = SectionType private def getOneValueConstant(value: Parameter): Result[String] = value match { case OneValueParameter(StringConstant(v)) => Success(v) case _ => Failure("""Section requires "numbering" argument.""") } } class SectionFormatter extends Formatter { override def format( expression: Expression, value: OpenlawValue, executionResult: TemplateExecutionResult ): Result[List[AgreementElement]] = VariableType.convert[SectionInfo](value) map { case SectionInfo(_, _, referenceValue) => List(FreeText(Text(referenceValue))) } override def missingValueFormat( expression: Expression ): List[AgreementElement] = List(FreeText(Text(s"[[$expression]]"))) override def stringFormat( expression: Expression, value: OpenlawValue, executionResult: TemplateExecutionResult ): Result[String] = VariableType.convert[SectionInfo](value) map { case SectionInfo(_, _, referenceValue) => referenceValue } override def missingValueString( expression: Expression ): String = ??? }
Example 106
Source File: LinkType.scala From openlaw-core with Apache License 2.0 | 5 votes |
package org.adridadou.openlaw.parser.template.variableTypes import cats.implicits._ import io.circe.{Decoder, Encoder} import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} import io.circe.parser.decode import org.adridadou.openlaw.{OpenlawNativeValue, OpenlawString, OpenlawValue} import org.adridadou.openlaw.parser.template.formatters.Formatter import org.adridadou.openlaw.parser.template._ import org.adridadou.openlaw.parser.template.expressions.Expression import org.adridadou.openlaw.result.{Failure, FailureException, Result, Success} object LinkInfo { implicit val linkInfoEnc: Encoder[LinkInfo] = deriveEncoder implicit val linkInfoDec: Decoder[LinkInfo] = deriveDecoder } final case class LinkInfo(label: String, url: String) extends OpenlawNativeValue case object LinkType extends VariableType(name = "Link") with NoShowInFormButRender { override def cast( value: String, executionResult: TemplateExecutionResult ): Result[LinkInfo] = decode[LinkInfo](value).leftMap(FailureException(_)) override def internalFormat(value: OpenlawValue): Result[String] = VariableType.convert[OpenlawString](value) override def defaultFormatter: Formatter = new LinkFormatter override def getTypeClass: Class[LinkInfo] = classOf[LinkInfo] override def construct( constructorParams: Parameter, executionResult: TemplateExecutionResult ): Result[Option[LinkInfo]] = constructorParams match { case Parameters(seq) => val map = seq.toMap for { label <- map.get("label").traverse(getOneValueConstant) url <- map.get("url").traverse(getOneValueConstant) } yield (label, url) mapN { LinkInfo(_, _) } case _ => Failure("""Link requires parameters, not a unique value or a list""") } def thisType: VariableType = LinkType private def getOneValueConstant(value: Parameter): Result[String] = value match { case OneValueParameter(StringConstant(v)) => Success(v) case _ => Failure("""Link requires "label" argument.""") } } class LinkFormatter extends Formatter { override def format( expression: Expression, value: OpenlawValue, executionResult: TemplateExecutionResult ): Result[List[AgreementElement]] = VariableType.convert[LinkInfo](value) map { case LinkInfo(labelValue, urlValue) => List(Link(labelValue, urlValue)) } override def missingValueFormat( expression: Expression ): List[AgreementElement] = List(FreeText(Text(s"[[$expression]]"))) override def stringFormat( expression: Expression, value: OpenlawValue, executionResult: TemplateExecutionResult ): Result[String] = VariableType.convert[LinkInfo](value) map { case LinkInfo(labelValue, urlValue) => s"$labelValue[$urlValue]" } }
Example 107
Source File: ResumeContractOracle.scala From openlaw-core with Apache License 2.0 | 5 votes |
package org.adridadou.openlaw.oracles import java.time.Instant import org.adridadou.openlaw.parser.template.variableTypes._ import org.adridadou.openlaw.vm._ import io.circe.{Decoder, Encoder} import io.circe.syntax._ import io.circe.generic.semiauto._ import org.adridadou.openlaw.result.Result import LocalDateTimeHelper._ final case class ResumeContractOracle(crypto: CryptoService) extends SignedActionOracle[ResumeExecutionEvent] { override def incoming( vm: OpenlawVm, event: ResumeExecutionEvent ): Result[OpenlawVm] = checkAction( vm, crypto, event, vm.contractDefinition.id(crypto).resumeContract(crypto) ) override def shouldExecute(event: OpenlawVmEvent): Boolean = event match { case _: ResumeExecutionEvent => true case _ => false } def processEvent( vm: OpenlawVm, event: ResumeExecutionEvent, name: String, identity: Identity ): Result[OpenlawVm] = { vm(UpdateExecutionStateCommand(ContractResumed, event)) } } object ResumeExecutionEvent { implicit val resumeExecutionEventEnc: Encoder[ResumeExecutionEvent] = deriveEncoder implicit val resumeExecutionEventDec: Decoder[ResumeExecutionEvent] = deriveDecoder } final case class ResumeExecutionEvent( signature: EthereumSignature, signatureDate: Instant ) extends SignedActionEvent { override def typeIdentifier: String = className[ResumeExecutionEvent] override def serialize: String = this.asJson.noSpaces }
Example 108
Source File: StopContractOracle.scala From openlaw-core with Apache License 2.0 | 5 votes |
package org.adridadou.openlaw.oracles import java.time.Instant import org.adridadou.openlaw.parser.template.variableTypes._ import org.adridadou.openlaw.vm._ import io.circe.{Decoder, Encoder} import io.circe.syntax._ import io.circe.generic.semiauto._ import org.adridadou.openlaw.result.Result import LocalDateTimeHelper._ final case class StopContractOracle(crypto: CryptoService) extends SignedActionOracle[StopExecutionEvent] { override def incoming( vm: OpenlawVm, event: StopExecutionEvent ): Result[OpenlawVm] = checkAction( vm, crypto, event, vm.contractDefinition.id(crypto).stopContract(crypto) ) override def shouldExecute(event: OpenlawVmEvent): Boolean = event match { case _: StopExecutionEvent => true case _ => false } def processEvent( vm: OpenlawVm, event: StopExecutionEvent, name: String, identity: Identity ): Result[OpenlawVm] = { vm(UpdateExecutionStateCommand(ContractStopped, event)) } } object StopExecutionEvent { implicit val stopExecutionEventEnc: Encoder[StopExecutionEvent] = deriveEncoder implicit val stopExecutionEventDec: Decoder[StopExecutionEvent] = deriveDecoder } final case class StopExecutionEvent( signature: EthereumSignature, signatureDate: Instant ) extends SignedActionEvent { override def typeIdentifier: String = className[StopExecutionEvent] override def serialize: String = this.asJson.noSpaces }
Example 109
Source File: TemplateLoadOracle.scala From openlaw-core with Apache License 2.0 | 5 votes |
package org.adridadou.openlaw.oracles import org.adridadou.openlaw.parser.template.variableTypes.EthereumAddress import org.adridadou.openlaw.values.TemplateId import org.adridadou.openlaw.vm.{LoadTemplateCommand, OpenlawVm, OpenlawVmEvent} import cats.implicits._ import TemplateId._ import io.circe.{Decoder, Encoder} import io.circe.syntax._ import io.circe.generic.semiauto._ import org.adridadou.openlaw.result.{Failure, Result} final case class TemplateLoadOracle(crypto: CryptoService) extends OpenlawOracle[LoadTemplate] { override def incoming( vm: OpenlawVm, event: LoadTemplate ): Result[OpenlawVm] = { val id = TemplateId(EthereumAddress.bytes2hex(crypto.sha256(event.content))) if (vm.contractDefinition.mainTemplate === id) { vm(LoadTemplateCommand(id, event)) } else { vm.contractDefinition.templates.values.find(templateId => templateId === id ) match { case Some(_) => vm(LoadTemplateCommand(id, event)) case None => Failure(s"invalid template for contract ${vm.contractId}") } } } override def shouldExecute(event: OpenlawVmEvent): Boolean = event match { case _: LoadTemplate => true case _ => false } } object LoadTemplate { implicit val loadTemplateEnc: Encoder[LoadTemplate] = deriveEncoder implicit val loadTemplateDec: Decoder[LoadTemplate] = deriveDecoder } final case class LoadTemplate(content: String) extends OpenlawVmEvent { override def typeIdentifier: String = className[LoadTemplate] override def serialize: String = this.asJson.noSpaces }
Example 110
Source File: TemplateId.scala From openlaw-core with Apache License 2.0 | 5 votes |
package org.adridadou.openlaw.values import cats.Eq import io.circe.{Decoder, Encoder, HCursor, Json, KeyDecoder, KeyEncoder} import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} import cats.implicits._ import org.adridadou.openlaw.parser.template.variableTypes.EthereumAddress final case class TemplateId(id: String = "") extends Comparable[TemplateId] { override def toString: String = id override def compareTo(o: TemplateId): Int = id.compareTo(o.id) } object TemplateId { def apply(data: Array[Byte]): TemplateId = TemplateId(EthereumAddress.bytes2hex(data)) implicit val templateIdEnc: Encoder[TemplateId] = deriveEncoder implicit val templateIdDec: Decoder[TemplateId] = deriveDecoder implicit val eq: Eq[TemplateId] = Eq.by(_.id) } final case class TemplateIdentifier(title: TemplateTitle, version: Int) final case class TemplateTitle(originalTitle: String, title: String) { override def toString: String = title override def equals(obj: Any): Boolean = obj match { case other: TemplateTitle => this === other case _ => false } override def hashCode(): Int = this.title.hashCode } object TemplateTitle { def apply(): TemplateTitle = TemplateTitle("") def apply(title: String): TemplateTitle = TemplateTitle(originalTitle = title, title = title.toLowerCase()) implicit val eq: Eq[TemplateTitle] = (x: TemplateTitle, y: TemplateTitle) => x.title === y.title implicit val templateTitleEnc: Encoder[TemplateTitle] = (a: TemplateTitle) => Json.fromString(a.originalTitle) implicit val templateTitleDec: Decoder[TemplateTitle] = (c: HCursor) => (for { title <- c.downField("title").as[String] } yield TemplateTitle(title)) match { case Right(title) => Right(title) case Left(_) => c.as[String].map(TemplateTitle(_)) } implicit val templateTitleKeyEnc: KeyEncoder[TemplateTitle] = (key: TemplateTitle) => key.title implicit val templateTitleKeyDec: KeyDecoder[TemplateTitle] = (key: String) => Some(TemplateTitle(key)) }
Example 111
Source File: ContractAccess.scala From openlaw-core with Apache License 2.0 | 5 votes |
package org.adridadou.openlaw.values import cats.Eq import io.circe.{Decoder, Encoder, HCursor, Json} sealed abstract class ContractAccess(val name: String) case object ContractSignable extends ContractAccess("signable") case object ContractNoAccess extends ContractAccess("noaccess") case object ContractReadonly extends ContractAccess("readonly") case object ContractEditable extends ContractAccess("editable") object ContractAccess { def apply(name: String): ContractAccess = name match { case ContractReadonly.name => ContractReadonly case ContractNoAccess.name => ContractNoAccess case ContractSignable.name => ContractSignable case ContractEditable.name => ContractEditable } def unapply(arg: ContractAccess): String = arg.name implicit val accessDecoder: Decoder[ContractAccess] = (c: HCursor) => { for { name <- c.as[String] } yield ContractAccess(name) } implicit val accessEncoder: Encoder[ContractAccess] = (a: ContractAccess) => Json.fromString(a.name) implicit val eqForContractAccess: Eq[ContractAccess] = Eq.fromUniversalEquals }
Example 112
Source File: ContractId.scala From openlaw-core with Apache License 2.0 | 5 votes |
package org.adridadou.openlaw.values import cats.Eq import io.circe.{Decoder, Encoder} import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} import org.adridadou.openlaw.oracles.CryptoService import org.adridadou.openlaw.parser.template.variableTypes.{ EthereumAddress, EthereumData } @SerialVersionUID(7843732947346776640L) final case class ContractId(id: String) { def stopContract(cryptoService: CryptoService): EthereumData = executionId("_stop_contract", cryptoService) def data: EthereumData = EthereumData(id) def resumeContract(cryptoService: CryptoService): EthereumData = executionId("_resume_contract", cryptoService) def executionId(command: String, crypto: CryptoService): EthereumData = EthereumData(id + EthereumData(crypto.sha256("_" + command)).toString) override def toString(): String = id } @SerialVersionUID(7843732947346776640L) object ContractId { def apply(data: Array[Byte]): ContractId = ContractId(EthereumAddress.bytes2hex(data)) implicit val contractIdEnc: Encoder[ContractId] = deriveEncoder implicit val contractIdDec: Decoder[ContractId] = deriveDecoder implicit val contractEq: Eq[ContractId] = Eq.fromUniversalEquals }
Example 113
Source File: GameManager.scala From telegram with Apache License 2.0 | 5 votes |
package com.bot4s.telegram.api import java.net.URLDecoder import java.nio.charset.StandardCharsets import java.util.Base64 import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.{Directive1, Route} import com.bot4s.telegram.marshalling import com.bot4s.telegram.methods.{GetGameHighScores, SetGameScore} import com.bot4s.telegram.models.{CallbackQuery, ChatId, User} import com.bot4s.telegram.future.BotExecutionContext import io.circe.generic.extras.semiauto._ import io.circe.generic.semiauto.deriveDecoder import io.circe.{Decoder, Encoder} import scala.concurrent.Future import scala.util.{Failure, Success} case class Payload( user : User, chatId : Option[ChatId] = None, messageId : Option[Int] = None, inlineMessageId : Option[String] = None, gameManagerHost : String, gameShortName : String) { def toGetGameHighScores = GetGameHighScores(user.id, chatId, messageId, inlineMessageId) def base64Encode: String = { val payloadJson = marshalling.toJson[Payload](this) val encodedPayload = Base64.getEncoder.encodeToString( payloadJson.getBytes(StandardCharsets.UTF_8)) encodedPayload } } object Payload { def base64Decode(encodedPayload: String): Payload = { val base64payload = URLDecoder.decode(encodedPayload, "UTF-8") val jsonPayload = new String(Base64.getDecoder.decode(base64payload), StandardCharsets.UTF_8) val payload = marshalling.fromJson[Payload](jsonPayload) payload } def forCallbackQuery(gameManagerHost: String)(implicit cbq: CallbackQuery): Payload = { Payload( cbq.from, cbq.message.map(_.source), cbq.message.map(_.messageId), cbq.inlineMessageId, gameManagerHost, cbq.gameShortName.get) // throws if not a game callback } import marshalling._ implicit val payloadEncoder: Encoder[Payload] = deriveEncoder[Payload] implicit val payloadDecoder: Decoder[Payload] = deriveDecoder[Payload] }
Example 114
Source File: YetAnotherAkkaClient.scala From telegram with Apache License 2.0 | 5 votes |
package com.bot4s.telegram.clients import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.marshalling.Marshal import akka.http.scaladsl.model.Uri.Path import akka.http.scaladsl.model._ import akka.http.scaladsl.unmarshalling.Unmarshal import akka.stream.Materializer import akka.stream.scaladsl.{Sink, Source} import cats.instances.future._ import com.bot4s.telegram.api.RequestHandler import com.bot4s.telegram.methods.{Request, Response} import io.circe.{Decoder, Encoder} import slogging.StrictLogging import com.bot4s.telegram.marshalling.responseDecoder import scala.concurrent.{ExecutionContext, Future} class YetAnotherAkkaClient(token: String, telegramHost: String = "api.telegram.org") (implicit system: ActorSystem, materializer: Materializer, ec: ExecutionContext) extends RequestHandler[Future] with StrictLogging { private val flow = Http().outgoingConnectionHttps(telegramHost) import com.bot4s.telegram.marshalling.AkkaHttpMarshalling._ override def sendRequest[R, T <: Request[_]](request: T)(implicit encT: Encoder[T], decR: Decoder[R]): Future[R] = { Source.fromFuture( Marshal(request).to[RequestEntity] .map { re => HttpRequest(HttpMethods.POST, Uri(path = Path(s"/bot$token/" + request.methodName)), entity = re) }) .via(flow) .mapAsync(1)(r => Unmarshal(r.entity).to[Response[R]]) .runWith(Sink.head) .map(processApiResponse[R]) } }
Example 115
Source File: AkkaHttpClient.scala From telegram with Apache License 2.0 | 5 votes |
package com.bot4s.telegram.clients import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.marshalling._ import akka.http.scaladsl.model._ import akka.http.scaladsl.unmarshalling.Unmarshal import akka.stream.Materializer import cats.instances.future._ import com.bot4s.telegram.api.RequestHandler import com.bot4s.telegram.marshalling.AkkaHttpMarshalling import com.bot4s.telegram.marshalling._ import com.bot4s.telegram.methods.{Request, Response} import io.circe.{Decoder, Encoder} import slogging.StrictLogging import scala.concurrent.{ExecutionContext, Future} class AkkaHttpClient(token: String, telegramHost: String = "api.telegram.org") (implicit system: ActorSystem, materializer: Materializer, ec: ExecutionContext) extends RequestHandler[Future] with StrictLogging { import AkkaHttpMarshalling._ private val apiBaseUrl = s"https://$telegramHost/bot$token/" private val http = Http() override def sendRequest[R, T <: Request[_]](request: T)(implicit encT: Encoder[T], decR: Decoder[R]): Future[R] = { Marshal(request).to[RequestEntity] .map { re => HttpRequest(HttpMethods.POST, Uri(apiBaseUrl + request.methodName), entity = re) } .flatMap(http.singleRequest(_)) .flatMap(r => Unmarshal(r.entity).to[Response[R]]) .map(t => processApiResponse[R](t)) } }
Example 116
Source File: AkkaHttpMarshalling.scala From telegram with Apache License 2.0 | 5 votes |
package com.bot4s.telegram.marshalling import akka.http.scaladsl.marshalling.{Marshaller, Marshalling, ToEntityMarshaller} import akka.http.scaladsl.model._ import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller} import com.bot4s.telegram.marshalling import com.bot4s.telegram.methods.{JsonRequest, MultipartRequest, Request} import com.bot4s.telegram.models.{AkkaInputFile, InputFile} import io.circe.{Decoder, Encoder} object AkkaHttpMarshalling { implicit def camelCaseJsonUnmarshaller[R](implicit decR: Decoder[R]): FromEntityUnmarshaller[R] = { Unmarshaller .stringUnmarshaller .forContentTypes(ContentTypes.`application/json`) .map(marshalling.fromJson[R]) } implicit def underscore_case_marshaller[T <: Request[_]](implicit encT: Encoder[T]): ToEntityMarshaller[T] = { Marshaller.strict { request => request match { // JSON-only request case r: JsonRequest[_] => Marshalling.Opaque(() => HttpEntity(ContentTypes.`application/json`, marshalling.toJson(request))) // Request with multipart payload case r: MultipartRequest[_] => val files = r.getFiles val parts = files.map { case (camelKey, inputFile) => val key = CaseConversions.snakenize(camelKey) inputFile match { case InputFile.FileId(id) => Multipart.FormData.BodyPart(key, HttpEntity(id)) case InputFile.Contents(filename, contents) => Multipart.FormData.BodyPart(key, HttpEntity(ContentTypes.`application/octet-stream`, contents), Map("filename" -> filename)) case InputFile.Path(path) => Multipart.FormData.BodyPart.fromPath(key, MediaTypes.`application/octet-stream`, path) case AkkaInputFile.ByteString(filename, bytes) => Multipart.FormData.BodyPart(key, HttpEntity(MediaTypes.`application/octet-stream`, bytes), Map("filename" -> filename)) case other => throw new RuntimeException(s"InputFile $other not supported") } } val fields = io.circe.parser.parse(marshalling.toJson(request)).fold(throw _, _.asObject.map { _.toMap.mapValues { json => json.asString.getOrElse(marshalling.printer.pretty(json)) } }) val params = fields.getOrElse(Map()) val paramParts = params.map { case (key, value) => Multipart.FormData.BodyPart(key, HttpEntity(value)) } Marshalling.Opaque(() => Multipart.FormData((parts ++ paramParts): _*).toEntity()) } } } }
Example 117
Source File: SttpClient.scala From telegram with Apache License 2.0 | 5 votes |
package com.bot4s.telegram.clients import cats.MonadError import cats.syntax.functor._ import com.bot4s.telegram.api.RequestHandler import com.bot4s.telegram.marshalling.CaseConversions import com.bot4s.telegram.methods.{JsonRequest, MultipartRequest, Response} import com.softwaremill.sttp.{Request => _, Response => _, _} import com.bot4s.telegram.marshalling import com.bot4s.telegram.methods._ import com.bot4s.telegram.models.InputFile import io.circe.parser.parse import io.circe.{Decoder, Encoder} import slogging.StrictLogging import scala.concurrent.duration._ class SttpClient[F[_]](token: String, telegramHost: String = "api.telegram.org") (implicit backend: SttpBackend[F, Nothing], monadError: MonadError[F, Throwable]) extends RequestHandler[F]()(monadError) with StrictLogging { val readTimeout: Duration = 50.seconds private implicit def circeBodySerializer[B : Encoder]: BodySerializer[B] = b => StringBody(marshalling.toJson[B](b), "utf-8", Some(MediaTypes.Json)) private def asJson[B : Decoder]: ResponseAs[B, Nothing] = asString("utf-8").map(s => marshalling.fromJson[B](s)) private val apiBaseUrl = s"https://$telegramHost/bot$token/" override def sendRequest[R, T <: Request[_]](request: T)(implicit encT: Encoder[T], decR: Decoder[R]): F[R] = { val url = apiBaseUrl + request.methodName val sttpRequest: RequestT[Id, String, Nothing] = request match { case r: JsonRequest[_] => sttp.post(uri"$url").body(request) case r: MultipartRequest[_] => val files = r.getFiles val parts = files.map { case (camelKey, inputFile) => val key = CaseConversions.snakenize(camelKey) inputFile match { case InputFile.FileId(id) => multipart(key, id) case InputFile.Contents(filename, contents) => multipart(key, contents).fileName(filename) //case InputFile.Path(path) => multipartFile(key, path) case other => throw new RuntimeException(s"InputFile $other not supported") } } val fields = parse(marshalling.toJson(request)).fold(throw _, _.asObject.map { _.toMap.mapValues { json => json.asString.getOrElse(marshalling.printer.pretty(json)) } }) val params = fields.getOrElse(Map()) sttp.post(uri"$url?$params").multipartBody(parts) } import com.bot4s.telegram.marshalling.responseDecoder val response = sttpRequest .readTimeout(readTimeout) .parseResponseIf(_ => true) // Always parse response .response(asJson[Response[R]]) .send[F]() response .map(_.unsafeBody) .map(processApiResponse[R]) } }
Example 118
Source File: JobTask.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.joex.scheduler import cats.effect.Sync import cats.implicits._ import docspell.common.Ident import docspell.common.syntax.all._ import io.circe.Decoder case class JobTask[F[_]]( name: Ident, task: Task[F, String, Unit], onCancel: Task[F, String, Unit] ) object JobTask { def json[F[_]: Sync, A]( name: Ident, task: Task[F, A, Unit], onCancel: Task[F, A, Unit] )(implicit D: Decoder[A] ): JobTask[F] = { val convert: String => F[A] = str => str.parseJsonAs[A] match { case Right(a) => a.pure[F] case Left(ex) => Sync[F].raiseError(new Exception(s"Cannot parse task arguments: $str", ex)) } JobTask(name, task.contramap(convert), onCancel.contramap(convert)) } }
Example 119
Source File: JobState.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.common import io.circe.{Decoder, Encoder} sealed trait JobState { self: Product => def name: String = productPrefix.toLowerCase } object JobState { case object Success extends JobState {} val all: Set[JobState] = Set(Waiting, Scheduled, Running, Stuck, Failed, Cancelled, Success) val queued: Set[JobState] = Set(Waiting, Scheduled, Stuck) val done: Set[JobState] = Set(Failed, Cancelled, Success) val inProgress: Set[JobState] = Set(Scheduled, Running, Stuck) def parse(str: String): Either[String, JobState] = str.toLowerCase match { case "waiting" => Right(Waiting) case "scheduled" => Right(Scheduled) case "running" => Right(Running) case "stuck" => Right(Stuck) case "failed" => Right(Failed) case "cancelled" => Right(Cancelled) case "success" => Right(Success) case _ => Left(s"Not a job state: $str") } def unsafe(str: String): JobState = parse(str).fold(sys.error, identity) def asString(state: JobState): String = state.name implicit val jobStateEncoder: Encoder[JobState] = Encoder.encodeString.contramap(_.name) implicit val jobStateDecoder: Decoder[JobState] = Decoder.decodeString.emap(JobState.parse) }
Example 120
Source File: NerTag.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.common import io.circe.{Decoder, Encoder} sealed trait NerTag { self: Product => final def name: String = productPrefix.toLowerCase } object NerTag { case object Organization extends NerTag case object Person extends NerTag case object Location extends NerTag case object Misc extends NerTag case object Email extends NerTag case object Website extends NerTag case object Date extends NerTag val all: List[NerTag] = List(Organization, Person, Location) def fromString(str: String): Either[String, NerTag] = str.toLowerCase match { case "organization" => Right(Organization) case "person" => Right(Person) case "location" => Right(Location) case "misc" => Right(Misc) case "email" => Right(Email) case "website" => Right(Website) case "date" => Right(Date) case _ => Left(s"Invalid ner tag: $str") } def unsafe(str: String): NerTag = fromString(str).fold(sys.error, identity) implicit val jsonDecoder: Decoder[NerTag] = Decoder.decodeString.emap(fromString) implicit val jsonEncoder: Encoder[NerTag] = Encoder.encodeString.contramap(_.name) }
Example 121
Source File: LogLevel.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.common import io.circe.{Decoder, Encoder} sealed trait LogLevel { self: Product => def toInt: Int final def name: String = productPrefix.toLowerCase } object LogLevel { case object Debug extends LogLevel { val toInt = 0 } case object Info extends LogLevel { val toInt = 1 } case object Warn extends LogLevel { val toInt = 2 } case object Error extends LogLevel { val toInt = 3 } def fromInt(n: Int): LogLevel = n match { case 0 => Debug case 1 => Info case 2 => Warn case 3 => Error case _ => Debug } def fromString(str: String): Either[String, LogLevel] = str.toLowerCase match { case "debug" => Right(Debug) case "info" => Right(Info) case "warn" => Right(Warn) case "warning" => Right(Warn) case "error" => Right(Error) case _ => Left(s"Invalid log-level: $str") } def unsafeString(str: String): LogLevel = fromString(str).fold(sys.error, identity) implicit val jsonDecoder: Decoder[LogLevel] = Decoder.decodeString.emap(fromString) implicit val jsonEncoder: Encoder[LogLevel] = Encoder.encodeString.contramap(_.name) }
Example 122
Source File: Priority.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.common import cats.Order import cats.implicits._ import io.circe.{Decoder, Encoder} sealed trait Priority { self: Product => final def name: String = productPrefix.toLowerCase } object Priority { case object High extends Priority case object Low extends Priority def fromString(str: String): Either[String, Priority] = str.toLowerCase match { case "high" => Right(High) case "low" => Right(Low) case _ => Left(s"Invalid priority: $str") } def unsafe(str: String): Priority = fromString(str).fold(sys.error, identity) def fromInt(n: Int): Priority = if (n <= toInt(Low)) Low else High def toInt(p: Priority): Int = p match { case Low => 0 case High => 10 } implicit val priorityOrder: Order[Priority] = Order.by[Priority, Int](toInt) implicit val jsonEncoder: Encoder[Priority] = Encoder.encodeString.contramap(_.name) implicit val jsonDecoder: Decoder[Priority] = Decoder.decodeString.emap(fromString) }
Example 123
Source File: Ident.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.common import java.security.SecureRandom import java.util.UUID import cats.Eq import cats.effect.Sync import cats.implicits._ import io.circe.{Decoder, Encoder} import scodec.bits.ByteVector case class Ident(id: String) { def isEmpty: Boolean = id.trim.isEmpty def nonEmpty: Boolean = !isEmpty def /(next: Ident): Ident = new Ident(id + "." + next.id) } object Ident { implicit val identEq: Eq[Ident] = Eq.by(_.id) val chars: Set[Char] = (('A' to 'Z') ++ ('a' to 'z') ++ ('0' to '9') ++ "-_.").toSet def randomUUID[F[_]: Sync]: F[Ident] = Sync[F].delay(unsafe(UUID.randomUUID.toString)) def randomId[F[_]: Sync]: F[Ident] = Sync[F].delay { val random = new SecureRandom() val buffer = new Array[Byte](32) random.nextBytes(buffer) unsafe(ByteVector.view(buffer).toBase58.grouped(11).mkString("-")) } def apply(str: String): Either[String, Ident] = fromString(str) def fromString(s: String): Either[String, Ident] = if (s.forall(chars.contains)) Right(new Ident(s)) else Left(s"Invalid identifier: '$s'. Allowed chars: ${chars.toList.sorted.mkString}") def fromBytes(bytes: ByteVector): Ident = unsafe(bytes.toBase58) def fromByteArray(bytes: Array[Byte]): Ident = fromBytes(ByteVector.view(bytes)) def unsafe(s: String): Ident = fromString(s) match { case Right(id) => id case Left(err) => sys.error(err) } def unapply(arg: String): Option[Ident] = fromString(arg).toOption implicit val encodeIdent: Encoder[Ident] = Encoder.encodeString.contramap(_.id) implicit val decodeIdent: Decoder[Ident] = Decoder.decodeString.emap(Ident.fromString) }
Example 124
Source File: ContactKind.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.common import io.circe.{Decoder, Encoder} sealed trait ContactKind { self: Product => def asString: String = self.productPrefix } object ContactKind { val all = List() case object Phone extends ContactKind case object Mobile extends ContactKind case object Fax extends ContactKind case object Email extends ContactKind case object Docspell extends ContactKind case object Website extends ContactKind def fromString(s: String): Either[String, ContactKind] = s.toLowerCase match { case "phone" => Right(Phone) case "mobile" => Right(Mobile) case "fax" => Right(Fax) case "email" => Right(Email) case "docspell" => Right(Docspell) case "website" => Right(Website) case _ => Left(s"Not a state value: $s") } def unsafe(str: String): ContactKind = fromString(str).fold(sys.error, identity) def asString(s: ContactKind): String = s.asString.toLowerCase implicit val contactKindEncoder: Encoder[ContactKind] = Encoder.encodeString.contramap(_.asString) implicit val contactKindDecoder: Decoder[ContactKind] = Decoder.decodeString.emap(ContactKind.fromString) }
Example 125
Source File: CollectiveState.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.common import io.circe.{Decoder, Encoder} sealed trait CollectiveState object CollectiveState { val all = List(Active, ReadOnly, Closed, Blocked) case object Blocked extends CollectiveState def fromString(s: String): Either[String, CollectiveState] = s.toLowerCase match { case "active" => Right(Active) case "readonly" => Right(ReadOnly) case "closed" => Right(Closed) case "blocked" => Right(Blocked) case _ => Left(s"Unknown state: $s") } def unsafe(str: String): CollectiveState = fromString(str).fold(sys.error, identity) def asString(state: CollectiveState): String = state match { case Active => "active" case Blocked => "blocked" case Closed => "closed" case ReadOnly => "readonly" } implicit val collectiveStateEncoder: Encoder[CollectiveState] = Encoder.encodeString.contramap(CollectiveState.asString) implicit val collectiveStateDecoder: Decoder[CollectiveState] = Decoder.decodeString.emap(CollectiveState.fromString) }
Example 126
Source File: ItemState.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.common import cats.data.NonEmptyList import io.circe.{Decoder, Encoder} sealed trait ItemState { self: Product => final def name: String = productPrefix.toLowerCase def isValid: Boolean = ItemState.validStates.exists(_ == this) def isInvalid: Boolean = ItemState.invalidStates.exists(_ == this) } object ItemState { case object Premature extends ItemState case object Processing extends ItemState case object Created extends ItemState case object Confirmed extends ItemState def fromString(str: String): Either[String, ItemState] = str.toLowerCase match { case "premature" => Right(Premature) case "processing" => Right(Processing) case "created" => Right(Created) case "confirmed" => Right(Confirmed) case _ => Left(s"Invalid item state: $str") } val validStates: NonEmptyList[ItemState] = NonEmptyList.of(Created, Confirmed) val invalidStates: NonEmptyList[ItemState] = NonEmptyList.of(Premature, Processing) def unsafe(str: String): ItemState = fromString(str).fold(sys.error, identity) implicit val jsonDecoder: Decoder[ItemState] = Decoder.decodeString.emap(fromString) implicit val jsonEncoder: Encoder[ItemState] = Encoder.encodeString.contramap(_.name) }
Example 127
Source File: UserTask.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.store.usertask import cats.effect._ import cats.implicits._ import docspell.common._ import docspell.common.syntax.all._ import docspell.store.records.RPeriodicTask import com.github.eikek.calev.CalEvent import io.circe.Decoder import io.circe.Encoder case class UserTask[A]( id: Ident, name: Ident, enabled: Boolean, timer: CalEvent, args: A ) { def encode(implicit E: Encoder[A]): UserTask[String] = copy(args = E(args).noSpaces) } object UserTask { implicit final class UserTaskCodec(ut: UserTask[String]) { def decode[A](implicit D: Decoder[A]): Either[String, UserTask[A]] = ut.args .parseJsonAs[A] .left .map(_.getMessage) .map(a => ut.copy(args = a)) def toPeriodicTask[F[_]: Sync]( account: AccountId ): F[RPeriodicTask] = RPeriodicTask .create[F]( ut.enabled, ut.name, account.collective, ut.args, s"${account.user.id}: ${ut.name.id}", account.user, Priority.Low, ut.timer ) .map(r => r.copy(id = ut.id)) } }
Example 128
Source File: DoobieMeta.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.store.impl import java.time.format.DateTimeFormatter import java.time.{Instant, LocalDate} import docspell.common._ import docspell.common.syntax.all._ import com.github.eikek.calev.CalEvent import doobie._ import doobie.implicits.legacy.instant._ import doobie.util.log.Success import emil.doobie.EmilDoobieMeta import io.circe.{Decoder, Encoder} trait DoobieMeta extends EmilDoobieMeta { implicit val sqlLogging = LogHandler({ case e @ Success(_, _, _, _) => DoobieMeta.logger.trace("SQL " + e) case e => DoobieMeta.logger.error(s"SQL Failure: $e") }) def jsonMeta[A](implicit d: Decoder[A], e: Encoder[A]): Meta[A] = Meta[String].imap(str => str.parseJsonAs[A].fold(ex => throw ex, identity))(a => e.apply(a).noSpaces ) implicit val metaCollectiveState: Meta[CollectiveState] = Meta[String].imap(CollectiveState.unsafe)(CollectiveState.asString) implicit val metaUserState: Meta[UserState] = Meta[String].imap(UserState.unsafe)(UserState.asString) implicit val metaPassword: Meta[Password] = Meta[String].imap(Password(_))(_.pass) implicit val metaIdent: Meta[Ident] = Meta[String].imap(Ident.unsafe)(_.id) implicit val metaContactKind: Meta[ContactKind] = Meta[String].imap(ContactKind.unsafe)(_.asString) implicit val metaTimestamp: Meta[Timestamp] = Meta[Instant].imap(Timestamp(_))(_.value) implicit val metaJobState: Meta[JobState] = Meta[String].imap(JobState.unsafe)(_.name) implicit val metaDirection: Meta[Direction] = Meta[Boolean].imap(flag => if (flag) Direction.Incoming: Direction else Direction.Outgoing: Direction )(d => Direction.isIncoming(d)) implicit val metaPriority: Meta[Priority] = Meta[Int].imap(Priority.fromInt)(Priority.toInt) implicit val metaLogLevel: Meta[LogLevel] = Meta[String].imap(LogLevel.unsafeString)(_.name) implicit val metaLenientUri: Meta[LenientUri] = Meta[String].imap(LenientUri.unsafe)(_.asString) implicit val metaNodeType: Meta[NodeType] = Meta[String].imap(NodeType.unsafe)(_.name) implicit val metaLocalDate: Meta[LocalDate] = Meta[String].imap(str => LocalDate.parse(str))(_.format(DateTimeFormatter.ISO_DATE)) implicit val metaItemState: Meta[ItemState] = Meta[String].imap(ItemState.unsafe)(_.name) implicit val metNerTag: Meta[NerTag] = Meta[String].imap(NerTag.unsafe)(_.name) implicit val metaNerLabel: Meta[NerLabel] = jsonMeta[NerLabel] implicit val metaNerLabelList: Meta[List[NerLabel]] = jsonMeta[List[NerLabel]] implicit val metaItemProposal: Meta[MetaProposal] = jsonMeta[MetaProposal] implicit val metaItemProposalList: Meta[MetaProposalList] = jsonMeta[MetaProposalList] implicit val metaLanguage: Meta[Language] = Meta[String].imap(Language.unsafe)(_.iso3) implicit val metaCalEvent: Meta[CalEvent] = Meta[String].timap(CalEvent.unsafe)(_.asString) } object DoobieMeta extends DoobieMeta { import org.log4s._ private val logger = getLogger }
Example 129
Source File: database.scala From franklin with Apache License 2.0 | 5 votes |
package com.azavea.franklin import cats.implicits._ import com.azavea.stac4s.TemporalExtent import doobie.implicits.javasql._ import doobie.util.meta.Meta import doobie.util.{Read, Write} import io.circe.{Decoder, Encoder} import java.sql.Timestamp import java.time.Instant package object database extends CirceJsonbMeta with GeotrellisWktMeta with Filterables { implicit val instantMeta: Meta[Instant] = Meta[Timestamp].imap(_.toInstant)(Timestamp.from) implicit val instantRead: Read[Instant] = Read[Timestamp].imap(_.toInstant)(Timestamp.from) implicit val instantWrite: Write[Instant] = Write[Timestamp].imap(_.toInstant)(Timestamp.from) def stringToInstant: String => Either[Throwable, Instant] = (s: String) => Either.catchNonFatal(Instant.parse(s)) def temporalExtentToString(te: TemporalExtent): String = { te.value match { case Some(start) :: Some(end) :: _ if start != end => s"${start.toString}/${end.toString}" case Some(start) :: Some(end) :: _ if start == end => s"${start.toString}" case Some(start) :: None :: _ => s"${start.toString}/.." case None :: Some(end) :: _ => s"../${end.toString}" } } def temporalExtentFromString(str: String): Either[String, TemporalExtent] = { str.split("/").toList match { case ".." :: endString :: _ => val parsedEnd: Either[Throwable, Instant] = stringToInstant(endString) parsedEnd match { case Left(_) => Left(s"Could not decode instant: $str") case Right(end: Instant) => Right(TemporalExtent(None, end)) } case startString :: ".." :: _ => val parsedStart: Either[Throwable, Instant] = stringToInstant(startString) parsedStart match { case Left(_) => Left(s"Could not decode instant: $str") case Right(start: Instant) => Right(TemporalExtent(start, None)) } case startString :: endString :: _ => val parsedStart: Either[Throwable, Instant] = stringToInstant(startString) val parsedEnd: Either[Throwable, Instant] = stringToInstant(endString) (parsedStart, parsedEnd).tupled match { case Left(_) => Left(s"Could not decode instant: $str") case Right((start: Instant, end: Instant)) => Right(TemporalExtent(start, end)) } case _ => Either.catchNonFatal(Instant.parse(str)) match { case Left(_) => Left(s"Could not decode instant: $str") case Right(t: Instant) => Right(TemporalExtent(t, t)) } } } implicit val encoderTemporalExtent: Encoder[TemporalExtent] = Encoder.encodeString.contramap[TemporalExtent] { extent => temporalExtentToString(extent) } implicit val decoderTemporalExtent: Decoder[TemporalExtent] = Decoder.decodeString.emap { str => temporalExtentFromString(str) } }
Example 130
Source File: SearchFilters.scala From franklin with Apache License 2.0 | 5 votes |
package com.azavea.franklin.database import cats.implicits._ import com.azavea.franklin.api.schemas.bboxToString import com.azavea.franklin.datamodel.{PaginationToken, Query} import com.azavea.stac4s.{Bbox, TemporalExtent} import eu.timepit.refined.types.numeric.NonNegInt import geotrellis.vector.Geometry import geotrellis.vector.{io => _, _} import io.circe.generic.semiauto._ import io.circe.refined._ import io.circe.{Decoder, HCursor} import java.net.URLEncoder import java.nio.charset.StandardCharsets final case class SearchFilters( bbox: Option[Bbox], datetime: Option[TemporalExtent], intersects: Option[Geometry], collections: List[String], items: List[String], limit: Option[NonNegInt], query: Map[String, List[Query]], next: Option[PaginationToken] ) { def asQueryParameters: String = { val bboxQP = bbox map { box => s"bbox=${bboxToString(box)}" } val datetimeQP = datetime map { tempExtent => s"datetime=${SearchFilters.encodeString(temporalExtentToString(tempExtent))}" } val collectionsQP = collections.toNel map { _ => s"""collections=${SearchFilters.encodeString(collections.mkString(","))}""" } val itemsQP = items.toNel map { _ => s"""ids=${SearchFilters.encodeString(items.mkString(","))}""" } List(bboxQP, datetimeQP, collectionsQP, itemsQP).flatten.mkString("&") } } object SearchFilters { def encodeString(s: String): String = URLEncoder.encode(s, StandardCharsets.UTF_8.toString) implicit val searchFilterDecoder = new Decoder[SearchFilters] { final def apply(c: HCursor): Decoder.Result[SearchFilters] = for { bbox <- c.downField("bbox").as[Option[Bbox]] datetime <- c.downField("datetime").as[Option[TemporalExtent]] intersects <- c.downField("intersects").as[Option[Geometry]] collectionsOption <- c.downField("collections").as[Option[List[String]]] itemsOption <- c.downField("items").as[Option[List[String]]] limit <- c.downField("limit").as[Option[NonNegInt]] query <- c.get[Option[Map[String, List[Query]]]]("query") paginationToken <- c.get[Option[PaginationToken]]("next") } yield { SearchFilters( bbox, datetime, intersects, collectionsOption.getOrElse(List.empty), itemsOption.getOrElse(List.empty), limit, query getOrElse Map.empty, paginationToken ) } } implicit val searchFilterEncoder = deriveEncoder[SearchFilters] }
Example 131
Source File: ExtensionName.scala From franklin with Apache License 2.0 | 5 votes |
package com.azavea.franklin.extensions.validation import io.circe.{Decoder, Encoder} sealed abstract class ExtensionName(val repr: String) { override def toString: String = repr } object ExtensionName { def fromString(s: String): ExtensionName = s.toLowerCase match { case "label" => Label case "layer" => Layer case _ => Unchecked(s) } implicit val encExtensionName: Encoder[ExtensionName] = Encoder.encodeString.contramap(_.repr) implicit val decExtensionName: Decoder[ExtensionName] = Decoder.decodeString.map(fromString) } case object Label extends ExtensionName("label") case object Layer extends ExtensionName("layer") case class Unchecked(underlying: String) extends ExtensionName(underlying)
Example 132
Source File: PagingLinkExtension.scala.scala From franklin with Apache License 2.0 | 5 votes |
package com.azavea.franklin.extensions.paging import com.azavea.franklin.database.SearchFilters import com.azavea.stac4s.extensions.LinkExtension import eu.timepit.refined.types.string.NonEmptyString import io.circe.generic.semiauto._ import io.circe.refined._ import io.circe.syntax._ import io.circe.{Decoder, Encoder, Json} // https://github.com/radiantearth/stac-api-spec/blob/7a6e12868113c94b17dead8989f49d978d5dd865/api-spec.md#paging-extension // the method for us is always POST, since otherwise we toss the params in the query string // and don't use this final case class PagingLinkExtension( headers: Map[NonEmptyString, String], body: SearchFilters, merge: Boolean ) object PagingLinkExtension { implicit val decPagingLinkExtension: Decoder[PagingLinkExtension] = deriveDecoder implicit val encPagingLinkExtension: Encoder.AsObject[PagingLinkExtension] = Encoder .AsObject[Map[String, Json]] .contramapObject((linkExtensionFields: PagingLinkExtension) => Map( "method" -> "POST".asJson, "headers" -> linkExtensionFields.headers.asJson, "body" -> linkExtensionFields.body.asJson, "merge" -> linkExtensionFields.merge.asJson ) ) implicit val linkExtensionPagingLinkExtension: LinkExtension[PagingLinkExtension] = LinkExtension.instance }
Example 133
Source File: CollectionItemsResponse.scala From franklin with Apache License 2.0 | 5 votes |
package com.azavea.franklin.datamodel import com.azavea.stac4s.{StacItem, StacLink} import io.circe.{Decoder, Encoder} final case class CollectionItemsResponse( features: List[StacItem], links: List[StacLink] ) object CollectionItemsResponse { implicit val encCollectionItemsResponse: Encoder[CollectionItemsResponse] = Encoder.forProduct3( "type", "features", "links" )(resp => ("FeatureCollection", resp.features, resp.links)) implicit val decCollectionItemsResponse: Decoder[CollectionItemsResponse] = Decoder.forProduct3( "type", "features", "links" )((_: String, features: List[StacItem], links: List[StacLink]) => CollectionItemsResponse(features, links) ) }
Example 134
Source File: PaginationToken.scala From franklin with Apache License 2.0 | 5 votes |
package com.azavea.franklin.datamodel import com.azavea.stac4s.meta._ import eu.timepit.refined.types.numeric.PosInt import io.circe.generic.semiauto._ import io.circe.parser._ import io.circe.refined._ import io.circe.syntax._ import io.circe.{Decoder, Encoder} import sttp.tapir.DecodeResult import java.time.Instant import java.util.Base64 final case class PaginationToken( timestampAtLeast: Instant, serialIdGreaterThan: PosInt ) object PaginationToken { implicit class ToTapirDecodeResult[T](circeResult: Either[io.circe.Error, T]) { def toDecodeResult: DecodeResult[T] = { circeResult match { case Left(err) => DecodeResult.Error(err.getMessage, err) case Right(value) => DecodeResult.Value(value) } } } implicit val dec: Decoder[PaginationToken] = deriveDecoder implicit val enc: Encoder[PaginationToken] = deriveEncoder val b64Encoder = Base64.getEncoder() val b64Decoder = Base64.getDecoder() def encPaginationToken(token: PaginationToken): String = b64Encoder.encodeToString( token.asJson.noSpaces.getBytes ) def decPaginationToken(encoded: String): DecodeResult[PaginationToken] = { val jsonString: String = new String(b64Decoder.decode(encoded)) val circeResult = for { js <- parse(jsonString) decoded <- js.as[PaginationToken] } yield decoded circeResult.toDecodeResult } }
Example 135
Source File: CirceYaml.scala From bazel-deps with MIT License | 5 votes |
package com.github.johnynek.bazel_deps import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.dataformat.yaml.YAMLFactory import io.circe.jackson.CirceJsonModule import io.circe.{Decoder, Json, ParsingFailure, Parser} import scala.util.control.NonFatal object Yaml extends Parser { private[this] val mapper = new ObjectMapper(new YAMLFactory()).registerModule(CirceJsonModule) private[this] val factory = mapper.getFactory override def parse(input: String): Either[ParsingFailure, Json] = try { Right(mapper.readValue(factory.createParser(input), classOf[Json])) } catch { case NonFatal(error) => Left(ParsingFailure(error.getMessage, error)) } }
Example 136
Source File: StringUnmarshaller.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.admin.directives import akka.http.scaladsl.unmarshalling.{FromStringUnmarshaller, Unmarshaller} import ch.epfl.bluebrain.nexus.admin.exceptions.AdminError.InvalidFormat import com.typesafe.scalalogging.Logger import io.circe.parser._ import io.circe.{Decoder, Json} object StringUnmarshaller { private val logger = Logger[this.type] def unmarshallJson[A: Decoder]: FromStringUnmarshaller[A] = unmarshaller { value => parse(value).left.map { err => logger.warn(s"Failed to convert string '$value' to Json", err) InvalidFormat } } private def unmarshaller[A]( f: String => Either[Throwable, Json] )(implicit dec: Decoder[A]): FromStringUnmarshaller[A] = Unmarshaller.strict[String, A] { case "" => throw Unmarshaller.NoContentException case string => f(string).flatMap(_.as[A]) match { case Right(value) => value case Left(err) => throw new IllegalArgumentException(err) } } }
Example 137
Source File: EventSerializer.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.admin.persistence import akka.actor.ExtendedActorSystem import akka.serialization.SerializerWithStringManifest import ch.epfl.bluebrain.nexus.admin.organizations.OrganizationEvent import ch.epfl.bluebrain.nexus.admin.projects.ProjectEvent import ch.epfl.bluebrain.nexus.commons.serialization.AkkaCoproductSerializer import ch.epfl.bluebrain.nexus.rdf.implicits._ import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig import ch.epfl.bluebrain.nexus.service.config.Settings import io.circe.generic.extras.Configuration import io.circe.generic.extras.semiauto.{deriveConfiguredDecoder, deriveConfiguredEncoder} import io.circe.{Decoder, Encoder} import shapeless.{:+:, CNil} import scala.annotation.nowarn @nowarn("cat=unused") class EventSerializer(system: ExtendedActorSystem) extends SerializerWithStringManifest { implicit private val httpConfig: HttpConfig = Settings(system).serviceConfig.http implicit private val config: Configuration = Configuration.default.withDiscriminator("@type") implicit private val projectEventDecoder: Decoder[ProjectEvent] = deriveConfiguredDecoder[ProjectEvent] implicit private val projectEventEncoder: Encoder[ProjectEvent] = deriveConfiguredEncoder[ProjectEvent] implicit private val organizationEventDecoder: Decoder[OrganizationEvent] = deriveConfiguredDecoder[OrganizationEvent] implicit private val organizationEventEncoder: Encoder[OrganizationEvent] = deriveConfiguredEncoder[OrganizationEvent] private val serializer = new AkkaCoproductSerializer[OrganizationEvent :+: ProjectEvent :+: CNil](1129) override val identifier: Int = serializer.identifier override def manifest(o: AnyRef): String = serializer.manifest(o) override def toBinary(o: AnyRef): Array[Byte] = serializer.toBinary(o) override def fromBinary(bytes: Array[Byte], manifest: String): AnyRef = serializer.fromBinary(bytes, manifest) }
Example 138
Source File: ProjectDescription.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.admin.projects import ch.epfl.bluebrain.nexus.rdf.Iri import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri import ch.epfl.bluebrain.nexus.rdf.implicits._ import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig import io.circe.{Decoder, DecodingFailure} def vocabOrGenerated(organization: String, label: String)(implicit http: HttpConfig): Option[AbsoluteIri] = vocab orElse Iri.absolute(s"${http.prefixIri.asString}/vocabs/$organization/$label/").toOption } object ProjectDescription { final case class Mapping(prefix: String, namespace: AbsoluteIri) implicit val mappingDecoder: Decoder[Mapping] = Decoder.instance { hc => for { prefix <- hc.downField("prefix").as[String] namespace <- hc.downField("namespace").as[String] iri <- Iri.absolute(namespace).left.map(err => DecodingFailure(err, hc.history)) } yield Mapping(prefix, iri) } implicit val descriptionDecoder: Decoder[ProjectDescription] = Decoder.instance { hc => for { desc <- hc.downField("description").as[Option[String]] lam = hc.downField("apiMappings").as[List[Mapping]].getOrElse(List.empty) map = lam.map(am => am.prefix -> am.namespace).toMap base <- hc.downField("base").as[Option[AbsoluteIri]] voc <- hc.downField("vocab").as[Option[AbsoluteIri]] } yield ProjectDescription(desc, map, base, voc) } }
Example 139
Source File: ElasticSearchDecoder.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.commons.es.client import cats.implicits._ import ch.epfl.bluebrain.nexus.commons.search.QueryResult.{ScoredQueryResult, UnscoredQueryResult} import ch.epfl.bluebrain.nexus.commons.search.{QueryResult, QueryResults} import ch.epfl.bluebrain.nexus.commons.search.QueryResults.{ScoredQueryResults, UnscoredQueryResults} import io.circe.{Decoder, Json} class ElasticSearchDecoder[A](implicit D: Decoder[A]) { private type ErrorOrResults = Either[Json, List[QueryResult[A]]] private def queryResults(json: Json, scored: Boolean): ErrorOrResults = { def queryResult(result: Json): Option[QueryResult[A]] = { result.hcursor.get[A]("_source") match { case Right(s) if scored => Some(ScoredQueryResult(result.hcursor.get[Float]("_score").getOrElse(0f), s)) case Right(s) => Some(UnscoredQueryResult(s)) case _ => None } } val hitsList = json.hcursor.downField("hits").downField("hits").focus.flatMap(_.asArray).getOrElse(Vector.empty) hitsList .foldM(List.empty[QueryResult[A]])((acc, json) => queryResult(json).map(_ :: acc).toRight(json)) .map(_.reverse) } private def token(json: Json): Option[String] = { val hits = json.hcursor.downField("hits").downField("hits") val length = hits.values.fold(1)(_.size) hits.downN(length - 1).downField("sort").focus.map(_.noSpaces) } private def decodeScoredQueryResults(maxScore: Float): Decoder[QueryResults[A]] = Decoder.decodeJson.emap { json => queryResults(json, scored = true) match { case Right(list) => Right(ScoredQueryResults(fetchTotal(json), maxScore, list, token(json))) // $COVERAGE-OFF$ case Left(errJson) => Left(s"Could not decode source from value '$errJson'") // $COVERAGE-ON$ } } private val decodeUnscoredResults: Decoder[QueryResults[A]] = Decoder.decodeJson.emap { json => queryResults(json, scored = false) match { case Right(list) => Right(UnscoredQueryResults(fetchTotal(json), list, token(json))) // $COVERAGE-OFF$ case Left(errJson) => Left(s"Could not decode source from value '$errJson'") // $COVERAGE-ON$ } } private def fetchTotal(json: Json): Long = json.hcursor.downField("hits").downField("total").get[Long]("value").getOrElse(0L) val decodeQueryResults: Decoder[QueryResults[A]] = Decoder.decodeJson.flatMap( _.hcursor.downField("hits").get[Float]("max_score").toOption.filterNot(f => f.isInfinite || f.isNaN) match { case Some(maxScore) => decodeScoredQueryResults(maxScore) case None => decodeUnscoredResults } ) } object ElasticSearchDecoder { final def apply[A](implicit D: Decoder[A]): Decoder[QueryResults[A]] = new ElasticSearchDecoder[A].decodeQueryResults }
Example 140
Source File: EventSource.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg.client import java.util.UUID import akka.NotUsed import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.model.headers.OAuth2BearerToken import akka.http.scaladsl.model.{HttpRequest, HttpResponse} import akka.persistence.query.{NoOffset, Offset, Sequence, TimeBasedUUID} import akka.stream.Materializer import akka.stream.alpakka.sse.scaladsl.{EventSource => SSESource} import akka.stream.scaladsl.Source import ch.epfl.bluebrain.nexus.iam.auth.AccessToken import ch.epfl.bluebrain.nexus.rdf.implicits._ import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri import com.typesafe.scalalogging.Logger import io.circe.Decoder import io.circe.parser.decode import scala.concurrent.{ExecutionContext, Future} import scala.util.Try trait EventSource[A] { def apply[A: Decoder]( config: KgClientConfig )(implicit as: ActorSystem, mt: Materializer, ec: ExecutionContext): EventSource[A] = new EventSource[A] { private val logger = Logger[this.type] private val http = Http() private def addCredentials(request: HttpRequest)(implicit cred: Option[AccessToken]): HttpRequest = cred.map(token => request.addCredentials(OAuth2BearerToken(token.value))).getOrElse(request) private def send(request: HttpRequest)(implicit cred: Option[AccessToken]): Future[HttpResponse] = http.singleRequest(addCredentials(request)).map { resp => if (!resp.status.isSuccess()) logger.warn(s"HTTP response when performing SSE request: status = '${resp.status}'") resp } private def toOffset(id: String): Offset = Try(TimeBasedUUID(UUID.fromString(id))).orElse(Try(Sequence(id.toLong))).getOrElse(NoOffset) override def apply(iri: AbsoluteIri, offset: Option[String])(implicit cred: Option[AccessToken] ): Source[(Offset, A), NotUsed] = SSESource(iri.asAkka, send, offset, config.sseRetryDelay).flatMapConcat { sse => val offset = sse.id.map(toOffset).getOrElse(NoOffset) decode[A](sse.data) match { case Right(ev) => Source.single(offset -> ev) case Left(err) => logger.error(s"Failed to decode admin event '$sse'", err) Source.empty } } } }
Example 141
Source File: PermissionsRoutes.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam.routes import akka.http.javadsl.server.Rejections._ import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import ch.epfl.bluebrain.nexus.iam.acls.Acls import ch.epfl.bluebrain.nexus.iam.permissions.Permissions import ch.epfl.bluebrain.nexus.iam.realms.Realms import ch.epfl.bluebrain.nexus.iam.routes.PermissionsRoutes.PatchPermissions import ch.epfl.bluebrain.nexus.iam.routes.PermissionsRoutes.PatchPermissions.{Append, Replace, Subtract} import ch.epfl.bluebrain.nexus.iam.types.Permission import ch.epfl.bluebrain.nexus.iam.types.ResourceF._ import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig import ch.epfl.bluebrain.nexus.service.directives.AuthDirectives import ch.epfl.bluebrain.nexus.service.marshallers.instances._ import io.circe.{Decoder, DecodingFailure} import kamon.instrumentation.akka.http.TracingDirectives.operationName import monix.eval.Task import monix.execution.Scheduler.Implicits.global class PermissionsRoutes(permissions: Permissions[Task], acls: Acls[Task], realms: Realms[Task])(implicit http: HttpConfig ) extends AuthDirectives(acls, realms) { def routes: Route = (pathPrefix("permissions") & pathEndOrSingleSlash) { operationName(s"/${http.prefix}/permissions") { extractCaller { implicit caller => concat( get { parameter("rev".as[Long].?) { case Some(rev) => complete(permissions.fetchAt(rev).runNotFound) case None => complete(permissions.fetch.runToFuture) } }, (put & parameter("rev" ? 0L)) { rev => entity(as[PatchPermissions]) { case Replace(set) => complete(permissions.replace(set, rev).runToFuture) case _ => reject(validationRejection("Only @type 'Replace' is permitted when using 'put'.")) } }, delete { parameter("rev".as[Long]) { rev => complete(permissions.delete(rev).runToFuture) } }, (patch & parameter("rev" ? 0L)) { rev => entity(as[PatchPermissions]) { case Append(set) => complete(permissions.append(set, rev).runToFuture) case Subtract(set) => complete(permissions.subtract(set, rev).runToFuture) case _ => reject(validationRejection("Only @type 'Append' or 'Subtract' is permitted when using 'patch'.")) } } ) } } } } object PermissionsRoutes { sealed private[routes] trait PatchPermissions extends Product with Serializable private[routes] object PatchPermissions { final case class Append(permissions: Set[Permission]) extends PatchPermissions final case class Subtract(permissions: Set[Permission]) extends PatchPermissions final case class Replace(permissions: Set[Permission]) extends PatchPermissions implicit val patchPermissionsDecoder: Decoder[PatchPermissions] = Decoder.instance { hc => for { permissions <- hc.get[Set[Permission]]("permissions") tpe = hc.get[String]("@type").getOrElse("Replace") patch <- tpe match { case "Replace" => Right(Replace(permissions)) case "Append" => Right(Append(permissions)) case "Subtract" => Right(Subtract(permissions)) case _ => Left(DecodingFailure("@type field must have Append or Subtract value", hc.history)) } } yield patch } } }
Example 142
Source File: EventSerializer.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam.io import java.nio.charset.Charset import akka.actor.ExtendedActorSystem import akka.serialization.SerializerWithStringManifest import ch.epfl.bluebrain.nexus.iam.acls.AclEvent import ch.epfl.bluebrain.nexus.iam.permissions.PermissionsEvent import ch.epfl.bluebrain.nexus.iam.realms.RealmEvent import ch.epfl.bluebrain.nexus.iam.types.GrantType.Camel._ import ch.epfl.bluebrain.nexus.rdf.Iri.Url import ch.epfl.bluebrain.nexus.rdf.implicits._ import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig import ch.epfl.bluebrain.nexus.service.config.Settings import io.circe.generic.extras.Configuration import io.circe.generic.extras.semiauto._ import io.circe.parser._ import io.circe.syntax._ import io.circe.{Decoder, Encoder, Printer} class EventSerializer(system: ExtendedActorSystem) extends SerializerWithStringManifest { private val utf8 = Charset.forName("UTF-8") private val printer = Printer.noSpaces.copy(dropNullValues = true) implicit private[io] val http: HttpConfig = Settings(system).serviceConfig.http implicit private[io] val config: Configuration = Configuration.default.withDiscriminator("@type") implicit private[io] val urlEncoder: Encoder[Url] = Encoder.encodeString.contramap(_.asUri) implicit private[io] val urlDecoder: Decoder[Url] = Decoder.decodeString.emap(Url.apply) implicit private[io] val permissionEventEncoder: Encoder[PermissionsEvent] = deriveConfiguredEncoder[PermissionsEvent] implicit private[io] val permissionEventDecoder: Decoder[PermissionsEvent] = deriveConfiguredDecoder[PermissionsEvent] implicit private[io] val aclEventEncoder: Encoder[AclEvent] = deriveConfiguredEncoder[AclEvent] implicit private[io] val aclEventDecoder: Decoder[AclEvent] = deriveConfiguredDecoder[AclEvent] implicit private[io] val realmEventEncoder: Encoder[RealmEvent] = deriveConfiguredEncoder[RealmEvent] implicit private[io] val realmEventDecoder: Decoder[RealmEvent] = deriveConfiguredDecoder[RealmEvent] override val identifier: Int = 1225 override def manifest(o: AnyRef): String = o match { case _: PermissionsEvent => "permissions-event" case _: AclEvent => "acl-event" case _: RealmEvent => "realm-event" case other => throw new IllegalArgumentException( s"Cannot determine manifest for unknown type: '${other.getClass.getCanonicalName}'" ) } override def toBinary(o: AnyRef): Array[Byte] = o match { case ev: PermissionsEvent => ev.asJson.printWith(printer).getBytes(utf8) case ev: AclEvent => ev.asJson.printWith(printer).getBytes(utf8) case ev: RealmEvent => ev.asJson.printWith(printer).getBytes(utf8) case other => throw new IllegalArgumentException(s"Cannot serialize unknown type: '${other.getClass.getCanonicalName}'") } override def fromBinary(bytes: Array[Byte], manifest: String): AnyRef = manifest match { case "permissions-event" => val str = new String(bytes, utf8) decode[PermissionsEvent](str) .getOrElse(throw new IllegalArgumentException(s"Cannot deserialize value: '$str' to 'PermissionsEvent'")) case "acl-event" => val str = new String(bytes, utf8) decode[AclEvent](str) .getOrElse(throw new IllegalArgumentException(s"Cannot deserialize value: '$str' to 'AclEvent'")) case "realm-event" => val str = new String(bytes, utf8) decode[RealmEvent](str) .getOrElse(throw new IllegalArgumentException(s"Cannot deserialize value: '$str' to 'RealmEvent'")) case other => throw new IllegalArgumentException(s"Cannot deserialize type with unknown manifest: '$other'") } }
Example 143
Source File: ElasticSearchDecoderSpec.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.commons.es.client import ch.epfl.bluebrain.nexus.commons.search.QueryResults import ch.epfl.bluebrain.nexus.commons.search.QueryResult.ScoredQueryResult import ch.epfl.bluebrain.nexus.commons.search.QueryResults.{ScoredQueryResults, UnscoredQueryResults} import ch.epfl.bluebrain.nexus.util.Resources import io.circe.{Decoder, Json} import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike class ElasticSearchDecoderSpec extends AnyWordSpecLike with Matchers with Resources { "A ElasticSearchDecoder" should { implicit val D: Decoder[QueryResults[Json]] = ElasticSearchDecoder[Json] "decode ElasticSearch response " in { val response = jsonContentOf("/commons/es/elastic_response.json") val json1 = Json.obj("key" -> Json.fromString("a"), "key2" -> Json.fromString("b")) val json2 = Json.obj("key" -> Json.fromString("c"), "key2" -> Json.fromString("d")) response.as[QueryResults[Json]].toOption.get shouldEqual ScoredQueryResults( 2L, 1f, List(ScoredQueryResult(0.5f, json1), ScoredQueryResult(0.8f, json2)) ) } "decode ElasticSearch empty response" in { val response = jsonContentOf("/commons/es/elastic_response_0.json") response.as[QueryResults[Json]].toOption.get shouldEqual UnscoredQueryResults(0L, List.empty) } } }
Example 144
Source File: ResourceDecoderSpec.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg.serializers import java.time.Instant import akka.http.scaladsl.testkit.ScalatestRouteTest import ch.epfl.bluebrain.nexus.commons.test.{EitherValues, Resources} import ch.epfl.bluebrain.nexus.iam.types.Identity.User import ch.epfl.bluebrain.nexus.kg.TestHelper import ch.epfl.bluebrain.nexus.kg.config.Schemas import ch.epfl.bluebrain.nexus.kg.resources.ProjectIdentifier.ProjectRef import ch.epfl.bluebrain.nexus.kg.resources.{Id, ResourceF, ResourceGraph} import ch.epfl.bluebrain.nexus.rdf.implicits._ import io.circe.Decoder import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike import org.scalatest.{Inspectors, OptionValues} class ResourceDecoderSpec extends AnyWordSpecLike with Matchers with Inspectors with EitherValues with ScalatestRouteTest with OptionValues with Resources with TestHelper { private val json = jsonContentOf("/serialization/resource.json") private val projectRef = ProjectRef(genUUID) private val id = url"http://example.com/prefix/myId" private val graph = json.toGraph(id).rightValue implicit private val decoder: Decoder[ResourceGraph] = ResourceF.resourceGraphDecoder(projectRef) private val model = ResourceF( Id(projectRef, url"http://example.com/prefix/myId"), 1L, Set(url"https://example.com/vocab/A", url"https://example.com/vocab/B"), deprecated = false, Map.empty, None, Instant.parse("2020-01-17T12:45:01.479676Z"), Instant.parse("2020-01-17T13:45:01.479676Z"), User("john", "bbp"), User("brenda", "bbp"), Schemas.unconstrainedRef, graph ) "A resource" should { "be decoded" in { json.as[ResourceGraph].rightValue shouldEqual model } } }
Example 145
Source File: GrantTypeSpec.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam.types import ch.epfl.bluebrain.nexus.util.EitherValues import ch.epfl.bluebrain.nexus.iam.types.GrantType._ import io.circe.{Decoder, Encoder, Json} import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike import org.scalatest.Inspectors class GrantTypeSpec extends AnyWordSpecLike with Matchers with Inspectors with EitherValues { "A GrantType" when { "using Camel encoders" should { import GrantType.Camel._ val map = Map( AuthorizationCode -> "authorizationCode", Implicit -> "implicit", Password -> "password", ClientCredentials -> "clientCredentials", DeviceCode -> "deviceCode", RefreshToken -> "refreshToken" ) "be encoded properly" in { val encoder = implicitly[Encoder[GrantType]] forAll(map.toList) { case (gt, expected) => encoder(gt) shouldEqual Json.fromString(expected) } } "be decoded properly" in { val decoder = implicitly[Decoder[GrantType]] forAll(map.toList) { case (expected, gt) => decoder.decodeJson(Json.fromString(gt)).rightValue shouldEqual expected } } "fail to decode for unknown string" in { val decoder = implicitly[Decoder[GrantType]] decoder.decodeJson(Json.fromString("incorrect")).leftValue } } "using Snake encoders" should { import GrantType.Snake._ val map = Map( AuthorizationCode -> "authorization_code", Implicit -> "implicit", Password -> "password", ClientCredentials -> "client_credentials", DeviceCode -> "device_code", RefreshToken -> "refresh_token" ) "be encoded properly" in { val encoder = implicitly[Encoder[GrantType]] forAll(map.toList) { case (gt, expected) => encoder(gt) shouldEqual Json.fromString(expected) } } "be decoded properly" in { val decoder = implicitly[Decoder[GrantType]] forAll(map.toList) { case (expected, gtString) => decoder.decodeJson(Json.fromString(gtString)).rightValue shouldEqual expected } } "fail to decode for unknown string" in { val decoder = implicitly[Decoder[GrantType]] decoder.decodeJson(Json.fromString("incorrect")).leftValue } } } }
Example 146
Source File: RdfCirceInstances.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.rdf.jsonld.instances import ch.epfl.bluebrain.nexus.rdf.{GraphDecoder, GraphEncoder, Iri} import ch.epfl.bluebrain.nexus.rdf.Iri.{AbsoluteIri, Path, RelativeIri, Url, Urn} import io.circe.{Decoder, Encoder, Json} import io.circe.parser._ import cats.implicits._ trait RdfCirceInstances { implicit final val absoluteIriEncoder: Encoder[AbsoluteIri] = Encoder.encodeString.contramap(_.asString) implicit final val absoluteIriDecoder: Decoder[AbsoluteIri] = Decoder.decodeString.emap(Iri.absolute) implicit final val iriPathEncoder: Encoder[Path] = Encoder.encodeString.contramap(_.asString) implicit final val iriPathDecoder: Decoder[Path] = Decoder.decodeString.emap(Path.apply) implicit final val iriEncoder: Encoder[Iri] = Encoder.encodeString.contramap(_.asString) implicit final val iriDecoder: Decoder[Iri] = Decoder.decodeString.emap(Iri.apply) implicit final def urlEncoder(implicit E: Encoder[AbsoluteIri]): Encoder[Url] = E.contramap(identity) implicit final val urlDecoder: Decoder[Url] = Decoder.decodeString.emap(Url.apply) implicit final def urnEncoder(implicit E: Encoder[AbsoluteIri]): Encoder[Urn] = E.contramap(identity) implicit final val urnDecoder: Decoder[Urn] = Decoder.decodeString.emap(Urn.apply) implicit final val relativeIriEncoder: Encoder[RelativeIri] = Encoder.encodeString.contramap(_.asString) implicit final val relativeIriDecoder: Decoder[RelativeIri] = Decoder.decodeString.emap(Iri.relative) implicit final val jsonGraphEncoder: GraphEncoder[Json] = GraphEncoder.graphEncodeString.contramap(_.noSpaces) implicit final val jsonGraphDecoder: GraphDecoder[Json] = GraphDecoder.graphDecodeString.emap(str => parse(str).leftMap(_.message)) } object RdfCirceInstances extends RdfCirceInstances
Example 147
Source File: AbstractHttpClient.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.cli.clients import cats.effect.{Sync, Timer} import cats.implicits._ import ch.epfl.bluebrain.nexus.cli.CliError.ClientError import ch.epfl.bluebrain.nexus.cli.CliError.ClientError.{SerializationError, Unexpected} import ch.epfl.bluebrain.nexus.cli.config.EnvConfig import ch.epfl.bluebrain.nexus.cli.{logRetryErrors, ClientErrOr, Console} import io.circe.Decoder import org.http4s.circe.CirceEntityDecoder._ import org.http4s.client.Client import org.http4s.{Request, Response} import retry.CatsEffect._ import retry.RetryPolicy import retry.syntax.all._ import scala.reflect.ClassTag import scala.util.control.NonFatal class AbstractHttpClient[F[_]: Timer](client: Client[F], env: EnvConfig)(implicit protected val F: Sync[F], protected val console: Console[F] ) { protected val retry = env.httpClient.retry protected def successCondition[A] = retry.condition.notRetryFromEither[A] _ implicit protected val retryPolicy: RetryPolicy[F] = retry.retryPolicy implicit protected def logOnError[A] = logRetryErrors[F, A]("interacting with an HTTP API") protected def executeDiscard[A](req: Request[F], returnValue: => A): F[ClientErrOr[A]] = execute(req, _.body.compile.drain.as(Right(returnValue))) protected def executeParse[A: Decoder](req: Request[F])(implicit A: ClassTag[A]): F[ClientErrOr[A]] = execute( req, _.attemptAs[A].value.map( _.leftMap(err => SerializationError(err.message, s"The response payload was not of type '${A.runtimeClass.getSimpleName}'") ) ) ) private def execute[A](req: Request[F], f: Response[F] => F[ClientErrOr[A]]): F[ClientErrOr[A]] = client .fetch(req)(ClientError.errorOr[F, A](r => f(r))) .recoverWith { case NonFatal(err) => F.delay(Left(Unexpected(Option(err.getMessage).getOrElse("").take(30)))) } .retryingM(successCondition[A]) }
Example 148
Source File: ProjectClient.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.cli.clients import cats.effect.concurrent.Ref import cats.effect.{Sync, Timer} import cats.implicits._ import ch.epfl.bluebrain.nexus.cli.config.EnvConfig import ch.epfl.bluebrain.nexus.cli.sse.{OrgLabel, OrgUuid, ProjectLabel, ProjectUuid} import ch.epfl.bluebrain.nexus.cli.{ClientErrOr, Console} import io.circe.Decoder import io.circe.generic.semiauto.deriveDecoder import org.http4s.client.Client import org.http4s.{Headers, Request} trait ProjectClient[F[_]] { final def apply[F[_]: Sync: Timer]( client: Client[F], env: EnvConfig, cache: Ref[F, Map[(OrgUuid, ProjectUuid), (OrgLabel, ProjectLabel)]], console: Console[F] ): ProjectClient[F] = { implicit val c: Console[F] = console new LiveProjectClient[F](client, env, cache) } private class LiveProjectClient[F[_]: Timer: Console: Sync]( client: Client[F], env: EnvConfig, cache: Ref[F, Map[(OrgUuid, ProjectUuid), (OrgLabel, ProjectLabel)]] ) extends AbstractHttpClient[F](client, env) with ProjectClient[F] { override def labels(org: OrgUuid, proj: ProjectUuid): F[ClientErrOr[(OrgLabel, ProjectLabel)]] = cache.get.flatMap { map => map.get((org, proj)) match { // value in cache, return case Some(value) => F.pure(Right(value)) // value not in cache, fetch, update and return case None => get(org, proj).flatMap { // propagate error case l @ Left(_) => F.pure(l) // success, update cache and return case r @ Right(value) => cache.modify(m => (m.updated((org, proj), value), value)) *> F.pure(r) } } } private def get(org: OrgUuid, proj: ProjectUuid): F[ClientErrOr[(OrgLabel, ProjectLabel)]] = { val uri = env.project(org, proj) val req = Request[F](uri = uri, headers = Headers(env.authorizationHeader.toList)) executeParse[NexusAPIProject](req).map { case Right(NexusAPIProject(orgLabel, projectLabel)) => Right((orgLabel, projectLabel)) case Left(err) => Left(err) } } } final private[ProjectClient] case class NexusAPIProject(`_organizationLabel`: OrgLabel, `_label`: ProjectLabel) private[ProjectClient] object NexusAPIProject { implicit val nexusAPIProjectDecoder: Decoder[NexusAPIProject] = deriveDecoder[NexusAPIProject] } }
Example 149
Source File: Event.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.cli.sse import java.time.Instant import java.util.UUID import ch.epfl.bluebrain.nexus.cli.utils.Codecs import io.circe.generic.semiauto.deriveDecoder import io.circe.{Decoder, Json} import org.http4s.Uri final case class Event( eventType: EventType, resourceId: Uri, rev: Long, organization: OrgUuid, project: ProjectUuid, resourceTypes: Set[Uri], instant: Instant, raw: Json ) object Event extends Codecs { final private[Event] case class APIEvent( `_organizationUuid`: UUID, `_projectUuid`: UUID, `@type`: EventType, `_types`: Option[Set[Uri]], `_resourceId`: Uri, `_rev`: Option[Long], `_instant`: Instant ) { def asEvent(raw: Json): Event = Event( `@type`, `_resourceId`, `_rev`.getOrElse(1L), OrgUuid(`_organizationUuid`), ProjectUuid(`_projectUuid`), `_types`.getOrElse(Set.empty[Uri]), `_instant`, raw ) } private[Event] object APIEvent { implicit val apiEventDecoder: Decoder[APIEvent] = deriveDecoder[APIEvent] } implicit final val eventDecoder: Decoder[Event] = Decoder.instance { cursor => cursor.as[APIEvent].map(_.asEvent(cursor.value)) } }
Example 150
Source File: EventType.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.cli.sse import io.circe.Decoder final def apply(string: String): Either[String, EventType] = string match { case "Created" => Right(Created) case "Updated" => Right(Updated) case "Deprecated" => Right(Deprecated) case "FileCreated" => Right(FileCreated) case "FileUpdated" => Right(FileUpdated) case "FileDigestUpdated" => Right(FileDigestUpdated) case "FileAttributesUpdated" => Right(FileAttributesUpdated) case "TagAdded" => Right(TagAdded) case other => Left(s"'$other' does not match a known event type") } implicit final val eventTypeDecoder: Decoder[EventType] = Decoder.decodeString.emap(apply) }
Example 151
Source File: File.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.storage import akka.http.scaladsl.model.{ContentType, Uri} import ch.epfl.bluebrain.nexus.rdf.implicits._ import ch.epfl.bluebrain.nexus.storage.config.Contexts.resourceCtxUri import scala.annotation.nowarn import io.circe.generic.extras.Configuration import io.circe.generic.extras.semiauto._ import io.circe.{Decoder, Encoder} // $COVERAGE-OFF$ object File { @nowarn("cat=unused") implicit private val config: Configuration = Configuration.default .copy(transformMemberNames = { case "@context" => "@context" case key => s"_$key" }) final case class Digest(algorithm: String, value: String) object Digest { val empty: Digest = Digest("", "") implicit val digestEncoder: Encoder[Digest] = deriveConfiguredEncoder[Digest] implicit val digestDecoder: Decoder[Digest] = deriveConfiguredDecoder[Digest] } } // $COVERAGE-ON$
Example 152
Source File: IamIdentitiesClient.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.storage import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.client.RequestBuilding.Get import akka.http.scaladsl.model.HttpRequest import akka.http.scaladsl.model.headers.OAuth2BearerToken import akka.http.scaladsl.unmarshalling.FromEntityUnmarshaller import akka.util.ByteString import cats.effect.{ContextShift, Effect, IO} import cats.implicits._ import ch.epfl.bluebrain.nexus.rdf.implicits._ import ch.epfl.bluebrain.nexus.storage.IamIdentitiesClient.Identity._ import ch.epfl.bluebrain.nexus.storage.IamIdentitiesClient._ import ch.epfl.bluebrain.nexus.storage.IamIdentitiesClientError.IdentitiesSerializationError import ch.epfl.bluebrain.nexus.storage.config.IamClientConfig import de.heikoseeberger.akkahttpcirce.ErrorAccumulatingCirceSupport.{DecodingFailures => AccDecodingFailures} import io.circe.Decoder.Result import io.circe.{Decoder, DecodingFailure, HCursor} import scala.concurrent.ExecutionContext class IamIdentitiesClient[F[_]](config: IamClientConfig)(implicit F: Effect[F], as: ActorSystem) extends JsonLdCirceSupport { private val um: FromEntityUnmarshaller[Caller] = unmarshaller[Caller] implicit private val ec: ExecutionContext = as.dispatcher implicit private val contextShift: ContextShift[IO] = IO.contextShift(ec) def apply()(implicit credentials: Option[AccessToken]): F[Caller] = credentials match { case Some(token) => execute(Get(config.identitiesIri.asAkka).addCredentials(OAuth2BearerToken(token.value))) case None => F.pure(Caller.anonymous) } private def execute(req: HttpRequest): F[Caller] = { IO.fromFuture(IO(Http().singleRequest(req))).to[F].flatMap { resp => if (resp.status.isSuccess()) IO.fromFuture(IO(um(resp.entity))).to[F].recoverWith { case err: AccDecodingFailures => F.raiseError(IdentitiesSerializationError(err.getMessage)) case err: Error => F.raiseError(IdentitiesSerializationError(err.getMessage)) } else IO.fromFuture(IO(resp.entity.dataBytes.runFold(ByteString(""))(_ ++ _).map(_.utf8String))) .to[F] .flatMap { err => F.raiseError(IamIdentitiesClientError.unsafe(resp.status, err)) } } } } object IamIdentitiesClient { final case class Authenticated(realm: String) extends Identity private def decodeAnonymous(hc: HCursor): Result[Subject] = hc.get[String]("@type").flatMap { case "Anonymous" => Right(Anonymous) case _ => Left(DecodingFailure("Cannot decode Anonymous Identity", hc.history)) } private def decodeUser(hc: HCursor): Result[Subject] = (hc.get[String]("subject"), hc.get[String]("realm")).mapN { case (subject, realm) => User(subject, realm) } private def decodeGroup(hc: HCursor): Result[Identity] = (hc.get[String]("group"), hc.get[String]("realm")).mapN { case (group, realm) => Group(group, realm) } private def decodeAuthenticated(hc: HCursor): Result[Identity] = hc.get[String]("realm").map(Authenticated) private val attempts = List[HCursor => Result[Identity]](decodeAnonymous, decodeUser, decodeGroup, decodeAuthenticated) implicit val identityDecoder: Decoder[Identity] = Decoder.instance { hc => attempts.foldLeft(Left(DecodingFailure("Unexpected", hc.history)): Result[Identity]) { case (acc @ Right(_), _) => acc case (_, f) => f(hc) } } } }
Example 153
Source File: HeroFragmentQuery.scala From sbt-graphql with Apache License 2.0 | 5 votes |
import io.circe.{ Decoder, Encoder } import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder } import sangria.macros._ import types._ object HeroFragmentQuery { object HeroFragmentQuery extends GraphQLQuery { val document: sangria.ast.Document = graphql"""query HeroFragmentQuery { hero { ...CharacterInfo } human(id: "Lea") { ...CharacterInfo } } fragment CharacterInfo on Character { name }""" case class Variables() object Variables { implicit val jsonEncoder: Encoder[Variables] = deriveEncoder[Variables] } case class Data(hero: Hero, human: Option[Human]) object Data { implicit val jsonDecoder: Decoder[Data] = deriveDecoder[Data] } case class Hero(name: Option[String]) extends CharacterInfo object Hero { implicit val jsonDecoder: Decoder[Hero] = deriveDecoder[Hero] implicit val jsonEncoder: Encoder[Hero] = deriveEncoder[Hero] } case class Human(name: Option[String]) extends CharacterInfo object Human { implicit val jsonDecoder: Decoder[Human] = deriveDecoder[Human] implicit val jsonEncoder: Encoder[Human] = deriveEncoder[Human] } } }
Example 154
Source File: EpisodeEnumTypes.scala From sbt-graphql with Apache License 2.0 | 5 votes |
import io.circe.{ Decoder, Encoder } import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder } object types { sealed trait Episode object Episode { case object NEWHOPE extends Episode case object EMPIRE extends Episode case object JEDI extends Episode implicit val jsonDecoder: Decoder[Episode] = Decoder.decodeString.emap({ case "NEWHOPE" => Right(NEWHOPE) case "EMPIRE" => Right(EMPIRE) case "JEDI" => Right(JEDI) case other => Left("invalid enum value: " + other) }) implicit val jsonEncoder: Encoder[Episode] = Encoder.encodeString.contramap({ case NEWHOPE => "NEWHOPE" case EMPIRE => "EMPIRE" case JEDI => "JEDI" }) } }
Example 155
Source File: HeroAndFriends.scala From sbt-graphql with Apache License 2.0 | 5 votes |
import io.circe.{ Decoder, Encoder } import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder } import sangria.macros._ import types._ object HeroAndFriends { object HeroAndFriends extends GraphQLQuery { val document: sangria.ast.Document = graphql"""query HeroAndFriends { hero { name friends { name friends { name friends { name friends { name } } } } } }""" case class Variables() object Variables { implicit val jsonEncoder: Encoder[Variables] = deriveEncoder[Variables] } case class Data(hero: Hero) object Data { implicit val jsonDecoder: Decoder[Data] = deriveDecoder[Data] } case class Hero(name: Option[String], friends: Option[List[Option[Hero.Friends]]]) object Hero { implicit val jsonDecoder: Decoder[Hero] = deriveDecoder[Hero] implicit val jsonEncoder: Encoder[Hero] = deriveEncoder[Hero] case class Friends(name: Option[String], friends: Option[List[Option[Friends.Friends]]]) object Friends { implicit val jsonDecoder: Decoder[Friends] = deriveDecoder[Friends] implicit val jsonEncoder: Encoder[Friends] = deriveEncoder[Friends] case class Friends(name: Option[String], friends: Option[List[Option[Friends.Friends]]]) object Friends { implicit val jsonDecoder: Decoder[Friends] = deriveDecoder[Friends] implicit val jsonEncoder: Encoder[Friends] = deriveEncoder[Friends] case class Friends(name: Option[String], friends: Option[List[Option[Friends.Friends]]]) object Friends { implicit val jsonDecoder: Decoder[Friends] = deriveDecoder[Friends] implicit val jsonEncoder: Encoder[Friends] = deriveEncoder[Friends] case class Friends(name: Option[String]) object Friends { implicit val jsonDecoder: Decoder[Friends] = deriveDecoder[Friends] implicit val jsonEncoder: Encoder[Friends] = deriveEncoder[Friends] } } } } } } }
Example 156
Source File: InputVariables.scala From sbt-graphql with Apache License 2.0 | 5 votes |
import io.circe.{ Decoder, Encoder } import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder } import sangria.macros._ import types._ object InputVariables { object InputVariables extends GraphQLQuery { val document: sangria.ast.Document = graphql"""query InputVariables($$humanId: String!) { human(id: $$humanId) { name homePlanet } }""" case class Variables(humanId: String) object Variables { implicit val jsonEncoder: Encoder[Variables] = deriveEncoder[Variables] } case class Data(human: Option[Human]) object Data { implicit val jsonDecoder: Decoder[Data] = deriveDecoder[Data] } case class Human(name: Option[String], homePlanet: Option[String]) object Human { implicit val jsonDecoder: Decoder[Human] = deriveDecoder[Human] implicit val jsonEncoder: Encoder[Human] = deriveEncoder[Human] } } }
Example 157
Source File: SearchQuery.scala From sbt-graphql with Apache License 2.0 | 5 votes |
import io.circe.{ Decoder, Encoder } import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder } import sangria.macros._ import types._ object SearchQuery { object SearchQuery extends GraphQLQuery { val document: sangria.ast.Document = graphql"""query SearchQuery($$text: String!) { search(text: $$text) { __typename ... on Human { name secretBackstory } ... on Droid { name primaryFunction } ... on Starship { name } } }""" case class Variables(text: String) object Variables { implicit val jsonEncoder: Encoder[Variables] = deriveEncoder[Variables] } case class Data(search: List[Search]) object Data { implicit val jsonDecoder: Decoder[Data] = deriveDecoder[Data] } sealed trait Search { def __typename: String def name: Option[String] } object Search { case class Human(__typename: String, name: Option[String], secretBackstory: Option[String]) extends Search object Human { implicit val jsonDecoder: Decoder[Human] = deriveDecoder[Human] implicit val jsonEncoder: Encoder[Human] = deriveEncoder[Human] } case class Droid(__typename: String, name: Option[String], primaryFunction: Option[String]) extends Search object Droid { implicit val jsonDecoder: Decoder[Droid] = deriveDecoder[Droid] implicit val jsonEncoder: Encoder[Droid] = deriveEncoder[Droid] } case class Starship(__typename: String, name: Option[String]) extends Search object Starship { implicit val jsonDecoder: Decoder[Starship] = deriveDecoder[Starship] implicit val jsonEncoder: Encoder[Starship] = deriveEncoder[Starship] } implicit val jsonDecoder: Decoder[Search] = for (typeDiscriminator <- Decoder[String].prepare(_.downField("__typename")); value <- typeDiscriminator match { case "Human" => Decoder[Human] case "Droid" => Decoder[Droid] case "Starship" => Decoder[Starship] case other => Decoder.failedWithMessage("invalid type: " + other) }) yield value } } }
Example 158
Source File: HeroNameQuery.scala From sbt-graphql with Apache License 2.0 | 5 votes |
import io.circe.{ Decoder, Encoder } import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder } import sangria.macros._ import types._ object HeroNameQuery { object HeroNameQuery extends GraphQLQuery { val document: sangria.ast.Document = graphql"""query HeroNameQuery { hero { name } }""" case class Variables() object Variables { implicit val jsonEncoder: Encoder[Variables] = deriveEncoder[Variables] } case class Data(hero: Hero) object Data { implicit val jsonDecoder: Decoder[Data] = deriveDecoder[Data] } case class Hero(name: Option[String]) object Hero { implicit val jsonDecoder: Decoder[Hero] = deriveDecoder[Hero] implicit val jsonEncoder: Encoder[Hero] = deriveEncoder[Hero] } } }
Example 159
Source File: EpisodeEnum.scala From sbt-graphql with Apache License 2.0 | 5 votes |
import io.circe.{ Decoder, Encoder } import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder } import sangria.macros._ import types._ object EpisodeEnum { object EpisodeEnum extends GraphQLQuery { val document: sangria.ast.Document = graphql"""query EpisodeEnum { hero { name appearsIn } }""" case class Variables() object Variables { implicit val jsonEncoder: Encoder[Variables] = deriveEncoder[Variables] } case class Data(hero: Hero) object Data { implicit val jsonDecoder: Decoder[Data] = deriveDecoder[Data] } case class Hero(name: Option[String], appearsIn: Option[List[Option[Episode]]]) object Hero { implicit val jsonDecoder: Decoder[Hero] = deriveDecoder[Hero] implicit val jsonEncoder: Encoder[Hero] = deriveEncoder[Hero] } } }
Example 160
Source File: MLFlowModelSpec.scala From ForestFlow with Apache License 2.0 | 5 votes |
package ai.forestflow.serving.MLFlow import ai.forestflow.serving.impl.{LocalFileArtifactReader, MLFlowH2OLoader, UnsupportedServableFlavor} import ai.forestflow.serving.interfaces.{ArtifactReader, Loader} import cats.syntax.either._ import ai.forestflow.serving.impl.{LocalFileArtifactReader, MLFlowH2OLoader, UnsupportedServableFlavor} import ai.forestflow.serving.interfaces.ArtifactReader import ai.forestflow.utils.SourceStorageProtocols import io.circe.generic.extras._ import io.circe.generic.extras.semiauto.deriveDecoder import io.circe.{CursorOp, Decoder, DecodingFailure} import ai.forestflow.serving.interfaces.Loader import ai.forestflow.utils.ThrowableImplicits._ import org.joda.time.{DateTimeZone, LocalDateTime} case class MLFlowModelSpec( artifactReader: ArtifactReader, runId: Option[String], timeCreated: Long, flavors: Map[String, Loader] ) { def getServableFlavor: Option[(String, Loader)] = flavors.collectFirst { case (flavor, loader) if !loader.isInstanceOf[UnsupportedServableFlavor] => (flavor, loader) } } object MLFlowModelSpec { implicit val config: Configuration = { val baseConfig = Configuration.default.withSnakeCaseMemberNames baseConfig.copy(transformMemberNames = baseConfig.transformMemberNames andThen { // from snake_case in class to snake_case file case "artifact_reader" => "artifact_path" case "time_created" => "utc_time_created" // utc_time_created is a string! case other => other }) } implicit val decodeTimeCreated: Decoder[Long] = Decoder.decodeString.emap{ tm: String => Either.catchNonFatal[Long]({ var ts = tm.replace(" ", "T") if (ts.takeRight(1) != "Z") ts = ts + "Z" val ll = LocalDateTime.parse(tm.replace(" ", "T")).toDateTime(DateTimeZone.UTC) ll.getMillis } ).leftMap(t => s"timeCreated Decoder Failed: ${t.printableStackTrace}") }.handleErrorWith(_ => Decoder.decodeLong) implicit val decodeMLFlowModel: Decoder[MLFlowModelSpec] = deriveDecoder[MLFlowModelSpec] implicit val decodeArtifactReaderString: Decoder[ArtifactReader] = Decoder.decodeOption[String].emap { artifactPath: Option[String] => Either.catchNonFatal[ArtifactReader]({ artifactPath match { case Some(path) => ArtifactReader.getArtifactReader(path) case _ => LocalFileArtifactReader("") } } ).leftMap(t => s"Artifact Reader Decoder Failed: ${t.printableStackTrace}") } implicit val decodeServableFlavor: Decoder[Map[String, Loader]] = Decoder.decodeMap[String, Map[String, String]].emap { flavors => Either.catchNonFatal[Map[String, Loader]]( flavors .map { case (flavor, props) => (flavor.toLowerCase, props) } .map { case (f@"h2o_mojo", props) => f -> MLFlowH2OLoader(dataPath = props.getOrElse("data", ""), version = props.get("h2o_version")) case (f, props) => f -> UnsupportedServableFlavor(props) case (f, props) => throw DecodingFailure(s"Unexpected or unsupported flavor type [$f] with props $props", List[CursorOp]()) // TODO: Support POJO? // case (f, _) => p -> BasicSourceProvider() } ).leftMap(t => t.printableStackTrace) } }
Example 161
Source File: AffineTransform.scala From evilplot with BSD 3-Clause "New" or "Revised" License | 5 votes |
package com.cibo.evilplot.geometry import com.cibo.evilplot.numeric.Point import io.circe.{Decoder, Encoder} final case class AffineTransform( scaleX: Double = 1, shearX: Double = 0, shearY: Double = 0, scaleY: Double = 1, shiftX: Double = 0, shiftY: Double = 0 ) { def scale(x: Double = 1, y: Double = 1): AffineTransform = this.compose(AffineTransform.scale(x, y)) def translate(dx: Double, dy: Double): AffineTransform = this.compose(AffineTransform.translate(dx, dy)) def rotateDegrees(degs: Double): AffineTransform = rotate(degs / 180 * Math.PI) def flipOverX: AffineTransform = scale(y = -1) def flipOverY: AffineTransform = scale(x = -1) def rotateClockwise: AffineTransform = rotateDegrees(-90) def rotateCounterClockwise: AffineTransform = rotateDegrees(90) def compose(trans: AffineTransform): AffineTransform = { val newScaleX = trans.scaleX * scaleX + trans.shearX * shearY val newShearX = trans.scaleX * shearX + trans.shearX * scaleY val newShiftX = trans.scaleX * shiftX + trans.shearX * shiftY + trans.shiftX val newShearY = trans.shearY * scaleX + trans.scaleY * shearY val newScaleY = trans.shearY * shearX + trans.scaleY * scaleY val newShiftY = trans.shearY * shiftX + trans.scaleY * shiftY + trans.shiftY AffineTransform(newScaleX, newShearX, newShearY, newScaleY, newShiftX, newShiftY) } def apply(x: Double, y: Double): (Double, Double) = { val tx = x * scaleX + y * shearX + shiftX val ty = x * shearY + y * scaleY + shiftY (tx, ty) } def apply(p: Point): Point = Point.tupled(this.apply(p.x, p.y)) } object AffineTransform { implicit val encoder: Encoder[AffineTransform] = io.circe.generic.semiauto.deriveEncoder[AffineTransform] implicit val decoder: Decoder[AffineTransform] = io.circe.generic.semiauto.deriveDecoder[AffineTransform] def identity: AffineTransform = AffineTransform() private def scale(sx: Double, sy: Double): AffineTransform = AffineTransform(scaleX = sx, scaleY = sy) private def translate(dx: Double, dy: Double): AffineTransform = AffineTransform(shiftX = dx, shiftY = dy) private def rotate(theta: Double): AffineTransform = AffineTransform( scaleX = Math.cos(theta), shearX = -Math.sin(theta), shearY = Math.sin(theta), scaleY = Math.cos(theta)) }
Example 162
Source File: Gradient2D.scala From evilplot with BSD 3-Clause "New" or "Revised" License | 5 votes |
package com.cibo.evilplot.geometry import com.cibo.evilplot.JSONUtils.minifyProperties import com.cibo.evilplot.colors.Color import com.cibo.evilplot.numeric.{Point, Point2d} import io.circe.generic.extras.Configuration import io.circe.generic.extras.semiauto._ import io.circe.{Decoder, Encoder, ObjectEncoder} sealed trait Gradient2d { val stops: Seq[GradientStop] } object Gradient2d { implicit val decoder: Decoder[Gradient2d] = deriveDecoder[Gradient2d] implicit val encoder: Encoder[Gradient2d] = deriveEncoder[Gradient2d] } case class GradientStop(offset: Double, color: Color) object GradientStop { implicit val decoder: Decoder[GradientStop] = deriveDecoder[GradientStop] implicit val encoder: Encoder[GradientStop] = deriveEncoder[GradientStop] } case class LinearGradient(x0: Double, y0: Double, x1: Double, y1: Double, stops: Seq[GradientStop]) extends Gradient2d object LinearGradient { implicit val decoder: Decoder[LinearGradient] = deriveDecoder[LinearGradient] implicit val encoder: Encoder[LinearGradient] = deriveEncoder[LinearGradient] def leftToRight(ex: Extent, stops: Seq[GradientStop]): LinearGradient = LinearGradient(0, 0, x1 = ex.width, 0, stops) def rightToLeft(ex: Extent, stops: Seq[GradientStop]): LinearGradient = LinearGradient(x0 = ex.width, 0, 0, 0, stops) def topToBottom(ex: Extent, stops: Seq[GradientStop]): LinearGradient = LinearGradient(0, 0, 0, y1 = ex.height, stops) def bottomToTop(ex: Extent, stops: Seq[GradientStop]): LinearGradient = { LinearGradient(0, y0 = ex.height, 0, 0, stops) } } case class RadialGradient( x0: Double, y0: Double, r0: Double, x1: Double, y1: Double, stops: Seq[GradientStop]) extends Gradient2d object RadialGradient { implicit val decoder: Decoder[RadialGradient] = deriveDecoder[RadialGradient] implicit val encoder: Encoder[RadialGradient] = deriveEncoder[RadialGradient] def withinExtent(extent: Extent, stops: Seq[GradientStop]): RadialGradient = { val radius = extent.height.min(extent.width) / 2 RadialGradient( extent.width / 2, extent.height / 2, radius, extent.width / 2, extent.height / 2, stops ) } }
Example 163
Source File: LineStyle.scala From evilplot with BSD 3-Clause "New" or "Revised" License | 5 votes |
package com.cibo.evilplot.geometry import com.cibo.evilplot.JSONUtils import io.circe.{Decoder, Encoder} import io.circe.generic.extras.Configuration final case class LineStyle( dashPattern: Seq[Double] = Seq.empty[Double], offset: Double = 0.0 ) { require(dashPattern.forall(_ > 0), "A dash pattern must only contain positive values.") } object LineStyle { import io.circe.generic.extras.semiauto._ private implicit val jsonConfig: Configuration = JSONUtils.minifyProperties implicit val lineStyleEncoder: Encoder[LineStyle] = deriveEncoder[LineStyle] implicit val lineStyleDecoder: Decoder[LineStyle] = deriveDecoder[LineStyle] val Solid: LineStyle = LineStyle() val Dotted: LineStyle = LineStyle(Seq(1, 2)) val DashDot: LineStyle = LineStyle(Seq(6, 3, 1, 3)) val Dashed: LineStyle = LineStyle(Seq(6)) def evenlySpaced(dist: Double): LineStyle = LineStyle(Seq(dist)) }
Example 164
Source File: Extent.scala From evilplot with BSD 3-Clause "New" or "Revised" License | 5 votes |
package com.cibo.evilplot.geometry import com.cibo.evilplot.JSONUtils import com.cibo.evilplot.numeric.{Point, Point2d} import io.circe.generic.extras.Configuration import io.circe.{Decoder, Encoder} case class Extent(width: Double, height: Double) { def *(scale: Double): Extent = Extent(scale * width, scale * height) def -(w: Double = 0.0, h: Double = 0.0): Extent = Extent(width - w, height - h) private[evilplot] def contains(p: Point2d): Boolean = { p.x >= 0 && p.x <= width && p.y >= 0 && p.y <= height } } object Extent { private implicit val cfg: Configuration = JSONUtils.minifyProperties implicit val extentEncoder: Encoder[Extent] = io.circe.generic.extras.semiauto.deriveEncoder[Extent] implicit val extentDecoder: Decoder[Extent] = io.circe.generic.extras.semiauto.deriveDecoder[Extent] }
Example 165
Source File: JSONUtils.scala From evilplot with BSD 3-Clause "New" or "Revised" License | 5 votes |
package com.cibo.evilplot import io.circe.generic.extras.Configuration import io.circe.parser.decode import io.circe.syntax._ import io.circe.{Decoder, Encoder, Error} object JSONUtils { // This should only be used for colors, drawables, and extents. private[evilplot] implicit val minifyProperties: Configuration = Configuration.default.copy( transformMemberNames = s => s.take(2).toString, transformConstructorNames = shortenedName ) // scalastyle:off private def shortenedName(s: String): String = { s match { case "EmptyDrawable" => "E" case "Line" => "L" case "Path" => "P" case "Polygon" => "p" case "Rect" => "R" case "BorderRect" => "B" case "Disc" => "D" case "Wedge" => "W" case "Translate" => "T" case "Affine" => "A" case "Scale" => "C" case "Rotate" => "O" case "Group" => "G" case "Resize" => "Re" case "Style" => "S" case "StrokeStyle" => "Y" case "StrokeWeight" => "H" case "LineDash" => "l" case "Text" => "X" case "HSLA" => "c" case "GradientFill" => "gf" case other => other } } // scalastyle:on // Wrap the Circe JSON decode method and return just the desired type, not an Either. // If parsing returns an error, throw the error rather than returning it. def decodeStr[A: Decoder](input: String): A = { val a: Either[Error, A] = decode[A](input) a match { case Left(error) => throw error case Right(result) => result } } // Encode the input object to JSON, then convert the JSON to a string and return it. def encodeObj[A: Encoder](input: A): String = { input.asJson.noSpaces } }
Example 166
Source File: Bounds.scala From evilplot with BSD 3-Clause "New" or "Revised" License | 5 votes |
package com.cibo.evilplot.numeric import scala.language.implicitConversions import io.circe.{Decoder, Encoder} import io.circe.generic.semiauto._ final case class Bounds(min: Double, max: Double) { if (!min.isNaN && !max.isNaN) { require(min <= max, s"Bounds min must be <= max, $min !<= $max") } def pad(p: Double): Bounds = Bounds(min - range * p, max + range * p) def padMax(p: Double): Bounds = Bounds(min, max + range * p) def padMin(p: Double): Bounds = Bounds(min - range * p, max) } object Bounds { implicit val encoder: Encoder[Bounds] = deriveEncoder[Bounds] implicit val decoder: Decoder[Bounds] = deriveDecoder[Bounds] private def lift[T](expr: => T): Option[T] = { try { Some(expr) } catch { case _: Exception => None } } def union(bounds: Seq[Bounds]): Bounds = bounds reduce { _ union _ } def getBy[T](data: Seq[T])(f: T => Double): Option[Bounds] = { val mapped = data.map(f).filterNot(_.isNaN) for { min <- lift(mapped.min) max <- lift(mapped.max) } yield Bounds(min, max) } def of(data: Seq[Double]): Bounds = Bounds.get(data) getOrElse Bounds.empty def get(data: Seq[Double]): Option[Bounds] = { data.foldLeft(None: Option[Bounds]) { (bounds, value) => bounds match { case None => Some(Bounds(value, value)) case Some(Bounds(min, max)) => Some(Bounds(math.min(min, value), math.max(max, value))) } } } def empty: Bounds = Bounds(0d, 0d) def widest(bounds: Seq[Option[Bounds]]): Option[Bounds] = bounds.flatten.foldLeft(None: Option[Bounds]) { (acc, curr) => if (acc.isEmpty) Some(curr) else Some(Bounds(math.min(acc.get.min, curr.min), math.max(acc.get.max, curr.max))) } }
Example 167
Source File: Points.scala From evilplot with BSD 3-Clause "New" or "Revised" License | 5 votes |
package com.cibo.evilplot.numeric import scala.language.implicitConversions import io.circe.{Decoder, Encoder} import io.circe.generic.semiauto._ trait Point2d { val x: Double val y: Double def withXY(x: Double = this.x, y: Double = this.y): Point2d } case class Point3d[Z: Numeric](x: Double, y: Double, z: Z) extends Datum2d[Point3d[Z]] { def withXY(x: Double, y: Double): Point3d[Z] = this.copy(x, y, z) } trait Datum2d[A <: Datum2d[A]] extends Point2d { val x: Double val y: Double def withXY(x: Double = this.x, y: Double = this.y): A } final case class Point(x: Double, y: Double) extends Datum2d[Point] { def -(that: Point): Point = Point(x - that.x, y - that.y) def withXY(x: Double = this.x, y: Double = this.y): Point = this.copy(x = x, y = y) } object Point { implicit val encoder: Encoder[Point] = io.circe.generic.semiauto.deriveEncoder[Point] implicit val decoder: Decoder[Point] = io.circe.generic.semiauto.deriveDecoder[Point] def tupled(t: (Double, Double)): Point = Point(t._1, t._2) implicit def toTuple(p: Point): (Double, Double) = (p.x, p.y) } final case class Point3(x: Double, y: Double, z: Double) object Point3 { def tupled(t: (Double, Double, Double)): Point3 = Point3(t._1, t._2, t._3) }
Example 168
Source File: BoxPlotSummaryStatistics.scala From evilplot with BSD 3-Clause "New" or "Revised" License | 5 votes |
package com.cibo.evilplot.numeric import io.circe.{Decoder, Encoder} import io.circe.generic.semiauto._ case class BoxPlotSummaryStatistics( min: Double, max: Double, lowerWhisker: Double, upperWhisker: Double, lowerQuantile: Double, middleQuantile: Double, upperQuantile: Double, outliers: Seq[Double], allPoints: Seq[Double]) { override def toString: String = { s"""lowerWhisker $lowerWhisker lowerQuantile $lowerQuantile middleQuantile |$middleQuantile upperQuantile $upperQuantile upperWhisker $upperWhisker """.stripMargin } } object BoxPlotSummaryStatistics { implicit val encoder: Encoder[BoxPlotSummaryStatistics] = deriveEncoder[BoxPlotSummaryStatistics] implicit val decoder: Decoder[BoxPlotSummaryStatistics] = deriveDecoder[BoxPlotSummaryStatistics] def apply( data: Seq[Double], quantiles: (Double, Double, Double) = (0.25, 0.50, 0.75), includeAllPoints: Boolean = false): BoxPlotSummaryStatistics = { val sorted = data.sorted require( quantiles._1 < quantiles._2 && quantiles._2 < quantiles._3, "Supplied quantiles must be strictly increasing") val (lowerQuantile, middleQuantile, upperQuantile) = quantile(data, quantiles match { case (l, m, u) => Seq(l, m, u) }) match { case Seq(l, m, u) => (l, m, u) } // Summary stats val min: Double = sorted.head val max: Double = sorted.last val interQuartileRange = upperQuantile - lowerQuantile val lowerWhiskerLimit = lowerQuantile - 1.5 * interQuartileRange val upperWhiskerLimit = upperQuantile + 1.5 * interQuartileRange val outliersLeft = if (min < lowerWhiskerLimit) sorted.takeWhile(_ < lowerWhiskerLimit) else Nil val outliersRight = if (max > upperWhiskerLimit) sorted.dropWhile(_ < upperWhiskerLimit) else Nil val outliers: Seq[Double] = outliersLeft ++ outliersRight val lowerWhisker: Double = math.max(lowerWhiskerLimit, min) val upperWhisker: Double = math.min(upperWhiskerLimit, max) BoxPlotSummaryStatistics( min, max, lowerWhisker, upperWhisker, lowerQuantile, middleQuantile, upperQuantile, outliers, data) } }
Example 169
Source File: package.scala From evilplot with BSD 3-Clause "New" or "Revised" License | 5 votes |
package com.cibo.evilplot import scala.language.implicitConversions import io.circe.{Decoder, Encoder} import io.circe.generic.semiauto._ package object numeric { type Grid = Vector[Vector[Double]] final case class GridData( grid: Grid, xBounds: Bounds, yBounds: Bounds, zBounds: Bounds, xSpacing: Double, ySpacing: Double) private val normalConstant = 1.0 / math.sqrt(2 * math.Pi) // with sigma = 1.0 and mu = 0, like R's dnorm. private[numeric] def probabilityDensityInNormal(x: Double): Double = normalConstant * math.exp(-math.pow(x, 2) / 2) // quantiles using linear interpolation. private[numeric] def quantile(data: Seq[Double], quantiles: Seq[Double]): Seq[Double] = { if (data.isEmpty) Seq.fill(quantiles.length)(Double.NaN) else { val length = data.length val sorted = data.sorted for { quantile <- quantiles _ = require(quantile >= 0.0 && quantile <= 1.0) index = quantile * (length - 1) result = { if (index >= length - 1) sorted.last else { val lower = sorted(math.floor(index).toInt) val upper = sorted(math.ceil(index).toInt) lower + (upper - lower) * (index - math.floor(index)) } } } yield result } } private[numeric] def mean(data: Seq[Double]): Double = data.sum / data.length private[numeric] def variance(data: Seq[Double]): Double = { val _mean = mean(data) data.map(x => math.pow(x - _mean, 2)).sum / (data.length - 1) } private[numeric] def standardDeviation(data: Seq[Double]): Double = math.sqrt(variance(data)) }
Example 170
Source File: ColorBar.scala From evilplot with BSD 3-Clause "New" or "Revised" License | 5 votes |
package com.cibo.evilplot.colors import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} import io.circe.{Decoder, Encoder} sealed trait ColorBar { val nColors: Int def getColor(z: Int): Color } // Use when one color is wanted but a ColorBar is needed. case class SingletonColorBar(color: Color) extends ColorBar { val nColors: Int = 1 def getColor(z: Int): Color = { require(z == 1) color } } // Map a sequence of colors to a continuous variable z. case class ScaledColorBar(colorSeq: Seq[Color], zMin: Double, zMax: Double) extends ColorBar { val nColors: Int = colorSeq.length private val zWidth = (zMax - zMin) / nColors.toFloat def getColor(i: Int): Color = colorSeq(i) def getColor(z: Double): Color = getColor(colorIndex(z)) def colorIndex(z: Double): Int = math.min(math.round(math.floor(math.max(z - zMin, 0.0) / zWidth)).toInt, nColors - 1) def colorValue(i: Int): Double = i * zWidth + zMin } object ColorBar { implicit val encoder: Encoder[ColorBar] = deriveEncoder[ColorBar] implicit val decoder: Decoder[ColorBar] = deriveDecoder[ColorBar] }
Example 171
Source File: Parsers.scala From get-programming-with-scala with MIT License | 5 votes |
package org.example.movies.entities import java.time.LocalDate import io.circe.Decoder import io.circe.parser.decode import io.circe.generic.auto._ import scala.util.Try object Parsers { def parseInt(row: Map[String, String], key: String): Option[Int] = parseAs(row, key, _.toInt) def parseDouble(row: Map[String, String], key: String): Option[Double] = parseAs(row, key, _.toDouble) def parseString(row: Map[String, String], key: String): Option[String] = parseAs(row, key, identity) def parseFloat(row: Map[String, String], key: String): Option[Float] = parseAs(row, key, _.toFloat) def parseLocalDate(row: Map[String, String], key: String): Option[LocalDate] = parseAs(row, key, LocalDate.parse) def parseGenres(row: Map[String, String], key: String): Option[List[Genre]] = parseJsonAs[List[Genre]](row, key) private def parseJsonAs[T: Decoder](row: Map[String, String], key: String): Option[T] = for { rawJson <- parseString(row, key) // for some reason the CSV is using ' rather than " for JSON, // so we need to clean the data before decoding cleanJson = rawJson.replace("'", "\"") // rather than returning an error for invalid JSON, we return no value decodedValue <- decode[T](cleanJson).toOption } yield decodedValue private def parseAs[T](row: Map[String, String], key: String, f: String => T): Option[T] = row.get(key).flatMap { value => // if we cannot parse a value, we return no value Try(f(value)).toOption } }
Example 172
Source File: AkkaHttpLambdaHandlerSpec.scala From scala-server-lambda with MIT License | 5 votes |
package io.github.howardjohn.lambda.akka import akka.actor.ActorSystem import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller} import akka.http.scaladsl.model.MediaTypes.`application/json` import akka.http.scaladsl.model.headers.RawHeader import akka.http.scaladsl.model.{HttpEntity, StatusCodes} import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller} import akka.stream.ActorMaterializer import io.circe.parser.decode import io.circe.syntax._ import io.circe.{Decoder, Encoder} import io.github.howardjohn.lambda.LambdaHandlerBehavior import io.github.howardjohn.lambda.LambdaHandlerBehavior._ import org.scalatest.{BeforeAndAfterAll, FeatureSpec, GivenWhenThen} import scala.concurrent.Future class AkkaHttpLambdaHandlerSpec extends FeatureSpec with LambdaHandlerBehavior with GivenWhenThen with BeforeAndAfterAll { implicit val system: ActorSystem = ActorSystem("test") implicit val materializer: ActorMaterializer = ActorMaterializer() implicit val ec = scala.concurrent.ExecutionContext.Implicits.global val route: Route = path("hello") { (get & parameter("times".as[Int] ? 1)) { times => complete { Seq .fill(times)("Hello World!") .mkString(" ") } } } ~ path("long") { get { Thread.sleep(1000) complete("") } } ~ path("post") { post { entity(as[String]) { body => complete(body) } } } ~ path("json") { post { import CirceJsonMarshalling._ import io.circe.generic.auto._ entity(as[JsonBody]) { entity => complete(LambdaHandlerBehavior.jsonReturn.asJson) } } } ~ path("exception") { get { throw RouteException() } } ~ path("error") { get { complete(StatusCodes.InternalServerError) } } ~ path("header") { get { headerValueByName(inputHeader) { header => respondWithHeaders(RawHeader(outputHeader, outputHeaderValue)) { complete(header) } } } } val handler = new AkkaHttpLambdaHandler(route) scenariosFor(behavior(handler)) override def afterAll(): Unit = { materializer.shutdown() system.terminate() } } object CirceJsonMarshalling { implicit final def unmarshaller[A: Decoder]: FromEntityUnmarshaller[A] = Unmarshaller.stringUnmarshaller .forContentTypes(`application/json`) .flatMap { ctx => mat => json => decode[A](json).fold(Future.failed, Future.successful) } implicit final def marshaller[A: Encoder]: ToEntityMarshaller[A] = Marshaller.withFixedContentType(`application/json`) { a => HttpEntity(`application/json`, a.asJson.noSpaces) } }
Example 173
Source File: AnyValCoders.scala From ticket-booking-aecor with Apache License 2.0 | 5 votes |
package ru.pavkin.booking.common.json import io.circe.{Decoder, Encoder} import shapeless.Unwrapped trait AnyValCoders { implicit def anyValEncoder[V, U]( implicit ev: V <:< AnyVal, V: Unwrapped.Aux[V, U], encoder: Encoder[U]): Encoder[V] = { val _ = ev encoder.contramap(V.unwrap) } implicit def anyValDecoder[V, U]( implicit ev: V <:< AnyVal, V: Unwrapped.Aux[V, U], decoder: Decoder[U], lp: shapeless.LowPriority): Decoder[V] = { val _ = (ev, lp) decoder.map(V.wrap) } } object AnyValCoders extends AnyValCoders
Example 174
Source File: Models.scala From ticket-booking-aecor with Apache License 2.0 | 5 votes |
package ru.pavkin.booking.common.models import cats.Order import cats.implicits._ import cats.kernel.{ Eq, Monoid } import enumeratum._ import io.circe.{ Decoder, Encoder } import io.circe.generic.semiauto._ import ru.pavkin.booking.common.json.AnyValCoders._ import scala.collection.immutable case class Money(amount: BigDecimal) extends AnyVal object Money { implicit val monoid: Monoid[Money] = new Monoid[Money] { def empty: Money = Money(0) def combine(x: Money, y: Money): Money = Money(x.amount + y.amount) } } case class BookingKey(value: String) extends AnyVal case class ClientId(value: String) extends AnyVal object ClientId { implicit val eqInstance: Eq[ClientId] = Eq.fromUniversalEquals } case class ConcertId(value: String) extends AnyVal case class Row(num: Int) extends AnyVal case class SeatNumber(num: Int) extends AnyVal case class Seat(row: Row, number: SeatNumber) object Seat { def seat(row: Int, number: Int): Seat = Seat(Row(row), SeatNumber(number)) implicit val order: Order[Seat] = Order.by(s => (s.row.num, s.number.num)) implicit val decoder: Decoder[Seat] = deriveDecoder implicit val encoder: Encoder[Seat] = deriveEncoder } case class Ticket(seat: Seat, price: Money) object Ticket { implicit val decoder: Decoder[Ticket] = deriveDecoder implicit val encoder: Encoder[Ticket] = deriveEncoder } case class PaymentId(value: String) extends AnyVal sealed trait BookingStatus extends EnumEntry object BookingStatus extends Enum[BookingStatus] with CirceEnum[BookingStatus] { case object AwaitingConfirmation extends BookingStatus case object Confirmed extends BookingStatus case object Denied extends BookingStatus case object Canceled extends BookingStatus case object Settled extends BookingStatus def values: immutable.IndexedSeq[BookingStatus] = findValues }
Example 175
Source File: PostgresBookingViewRepository.scala From ticket-booking-aecor with Apache License 2.0 | 5 votes |
package ru.pavkin.booking.booking.view import java.sql.Timestamp import java.time.Instant import cats.Monad import cats.implicits._ import doobie._ import doobie.implicits._ import doobie.util.transactor.Transactor import io.circe.{ Decoder, Encoder, Json } import io.circe.parser._ import org.postgresql.util.PGobject import ru.pavkin.booking.common.models._ class PostgresBookingViewRepository[F[_]: Monad](transactor: Transactor[F], tableName: String = "bookings") extends BookingViewRepository[F] { implicit val jsonMeta: Meta[Json] = Meta.Advanced .other[PGobject]("json") .timap[Json](a => parse(a.getValue).leftMap[Json](e => throw e).merge)(a => { val o = new PGobject o.setType("json") o.setValue(a.noSpaces) o }) implicit val seatsMeta: Meta[List[Seat]] = jsonMeta.timap( j => Decoder[List[Seat]].decodeJson(j).right.get )(s => Encoder[List[Seat]].apply(s)) implicit val ticketsMeta: Meta[List[Ticket]] = jsonMeta.timap( j => Decoder[List[Ticket]].decodeJson(j).right.get )(s => Encoder[List[Ticket]].apply(s)) implicit val instantMeta: Meta[Instant] = Meta[Timestamp].timap(_.toInstant)(Timestamp.from) implicit val bookingStatusMeta: Meta[BookingStatus] = Meta[String].timap(BookingStatus.withName)(_.entryName) def get(bookingId: BookingKey): F[Option[BookingView]] = queryView(bookingId).option.transact(transactor) def byClient(clientId: ClientId): F[List[BookingView]] = queryForClient(clientId).to[List].transact(transactor) def set(view: BookingView): F[Unit] = Update[BookingView](setViewQuery).run(view).transact(transactor).void def expired(now: Instant): fs2.Stream[F, BookingKey] = queryExpired(now).stream.transact(transactor) def createTable: F[Unit] = createTableQuery.transact(transactor).void private val setViewQuery = s"""INSERT INTO $tableName (booking_id, client_id, concert_id, seats, tickets, status, confirmed_at, expires_at, version) VALUES (?,?,?,?,?,?,?,?,?) ON CONFLICT (booking_id) DO UPDATE SET tickets = EXCLUDED.tickets, status = EXCLUDED.status, confirmed_at = EXCLUDED.confirmed_at, expires_at = EXCLUDED.expires_at, version = EXCLUDED.version;""" private def queryView(bookingId: BookingKey) = (fr"SELECT * FROM " ++ Fragment.const(tableName) ++ fr"WHERE booking_id = $bookingId;") .query[BookingView] private def queryExpired(now: Instant) = (fr"SELECT booking_id FROM " ++ Fragment.const(tableName) ++ fr"WHERE status = ${BookingStatus.Confirmed: BookingStatus} AND expires_at < $now;") .query[BookingKey] private def queryForClient(clientId: ClientId) = (fr"SELECT * FROM " ++ Fragment.const(tableName) ++ fr"WHERE client_id = $clientId;") .query[BookingView] private val createTableQuery = (fr""" CREATE TABLE IF NOT EXISTS """ ++ Fragment.const(tableName) ++ fr""" ( booking_id text NOT NULL PRIMARY KEY, client_id text NOT NULL, concert_id text NOT NULL, seats json NOT NULL, tickets json NOT NULL, status text NOT NULL, confirmed_at timestamptz, expires_at timestamptz, version bigint NOT NULL ); """).update.run }
Example 176
Source File: ErrorInfo.scala From shaclex with MIT License | 5 votes |
package es.weso.schema import cats.Show import com.typesafe.scalalogging.LazyLogging import io.circe.JsonObject._ import io.circe.{ Decoder, Encoder, Json } case class ErrorInfo(msg: String) { def show: String = msg } object ErrorInfo extends LazyLogging { implicit val showErrorInfo = new Show[ErrorInfo] { override def show(e: ErrorInfo): String = e.show } implicit val encodeErrorInfo: Encoder[ErrorInfo] = new Encoder[ErrorInfo] { final def apply(e: ErrorInfo): Json = Json.fromJsonObject( singleton("type", Json.fromString("ErrorInfo")). add("error", Json.fromString(e.msg))) } implicit val decodeErrorInfo: Decoder[ErrorInfo] = Decoder.instance { c => logger.debug(s"Decoding error info: $c") for { msg <- c.get[String]("error") } yield ErrorInfo(msg) } }
Example 177
Source File: Codecs.scala From bay-scalajs.g8 with Apache License 2.0 | 5 votes |
package shared.utils import cats.syntax.either._ import io.circe.Decoder import io.circe.Encoder import java.time._ import java.time.format.DateTimeFormatter trait Codecs extends UpickleCodecs with CirceCodecs object Codecs extends Codecs trait CirceCodecs { // use more stable encodings then standard private val fmt: DateTimeFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSZZZZZ") private val fmtLocal: DateTimeFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS") private val fmtDate: DateTimeFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd") private val fmtTime: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS") def createCirceCodec[T](encode: T => String, decode: String => T): (Encoder[T], Decoder[T]) = (Encoder.encodeString.contramap[T](encode), Decoder.decodeString.emap(str => Either.catchNonFatal(decode(str)).leftMap(_.getMessage))) implicit val (encodeOffsetDateTimeCirce, decodeOffsetDateTimeCirce) = createCirceCodec[OffsetDateTime](fmt.format, OffsetDateTime.parse) implicit val (encodeLocalDateTimeCirce, decodeLocalDateTimeCirce) = createCirceCodec[LocalDateTime](fmtLocal.format, LocalDateTime.parse) implicit val (encodeLocalDateCirce, decodeLocalDateCirce) = createCirceCodec[LocalDate](fmtDate.format, LocalDate.parse) implicit val (encodeLocalTimeCirce, decodeLocalTimeCirce) = createCirceCodec[LocalTime](fmtTime.format, LocalTime.parse) implicit val (encodeDurationCirce, decodeDurationCirce) = createCirceCodec[Duration](_.toString(), Duration.parse) } object CirceCodecs extends CirceCodecs trait UpickleCodecs { import upickle.default._ def createUpickleCode[T](encode: T => String, decode: String => T): (Writer[T], Reader[T]) = (Writer[T](e => upickle.Js.Str(encode(e))), Reader[T] { case upickle.Js.Str(jsStr) => decode(jsStr) }) implicit val (encodeOffsetDateTimeUpickle, decodeOffsetDateTimeUpickle) = createUpickleCode[OffsetDateTime](_.toString(), OffsetDateTime.parse) implicit val (encodeLocalDateTimeUpickle, decodeLocalDateTimeUpickle) = createUpickleCode[LocalDateTime](_.toString(), LocalDateTime.parse) implicit val (encodeLocalDateUpickle, decodeLocalDateUpickle) = createUpickleCode[LocalDate](_.toString(), LocalDate.parse) implicit val (encodeLocalTimeUpickle, decodeLocalTimeUpickle) = createUpickleCode[LocalTime](_.toString(), LocalTime.parse) implicit val (encodeDurationUpickle, decodeDurationUpickle) = createUpickleCode[Duration](_.toString(), Duration.parse) } object UpickleCodecs extends UpickleCodecs
Example 178
Source File: CirceSerialization.scala From kafka-serialization with Apache License 2.0 | 5 votes |
package com.ovoenergy.kafka.serialization.circe import java.nio.charset.StandardCharsets import cats.syntax.either._ import com.ovoenergy.kafka.serialization.core._ import io.circe.parser._ import io.circe.syntax._ import io.circe.{Decoder, Encoder, Error, Json} import org.apache.kafka.common.serialization.{Deserializer => KafkaDeserializer, Serializer => KafkaSerializer} private[circe] trait CirceSerialization { def circeJsonSerializer[T: Encoder]: KafkaSerializer[T] = serializer { (_, data) => data.asJson.noSpaces.getBytes(StandardCharsets.UTF_8) } def circeJsonDeserializer[T: Decoder]: KafkaDeserializer[T] = deserializer { (_, data) => (for { json <- parse(new String(data, StandardCharsets.UTF_8)): Either[Error, Json] t <- json.as[T]: Either[Error, T] } yield t).fold(error => throw new RuntimeException(s"Deserialization failure: ${error.getMessage}", error), identity _) } }
Example 179
Source File: GrantType.scala From nexus-iam with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam.client.types import io.circe.Decoder final case object RefreshToken extends GrantType final implicit val grantTypeDecoder: Decoder[GrantType] = Decoder.decodeString.emap { case "authorizationCode" => Right(AuthorizationCode) case "implicit" => Right(Implicit) case "password" => Right(Password) case "clientCredentials" => Right(ClientCredentials) case "deviceCode" => Right(DeviceCode) case "refreshToken" => Right(RefreshToken) case other => Left(s"Unknown grant type '$other'") } }
Example 180
Source File: Caller.scala From nexus-iam with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam.client.types import ch.epfl.bluebrain.nexus.iam.client.types.Identity._ import io.circe.{Decoder, DecodingFailure} val anonymous: Caller = Caller(Anonymous: Subject, Set[Identity](Anonymous)) final implicit val callerDecoder: Decoder[Caller] = Decoder.instance { cursor => cursor .get[Set[Identity]]("identities") .flatMap { identities => identities.collectFirst { case u: User => u } orElse identities.collectFirst { case Anonymous => Anonymous } match { case Some(subject: Subject) => Right(Caller(subject, identities)) case _ => val pos = cursor.downField("identities").history Left(DecodingFailure("Unable to find a subject in the collection of identities", pos)) } } } }
Example 181
Source File: EventSource.scala From nexus-iam with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam.client import akka.NotUsed import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.model.headers.OAuth2BearerToken import akka.http.scaladsl.model.{HttpRequest, HttpResponse} import akka.stream.Materializer import akka.stream.alpakka.sse.scaladsl.{EventSource => SSESource} import akka.stream.scaladsl.Source import ch.epfl.bluebrain.nexus.iam.client.config.IamClientConfig import ch.epfl.bluebrain.nexus.iam.client.types.AuthToken import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri import ch.epfl.bluebrain.nexus.rdf.implicits._ import com.typesafe.scalalogging.Logger import io.circe.Decoder import io.circe.parser.decode import scala.concurrent.{ExecutionContext, Future} trait EventSource[A] { def apply[A: Decoder]( config: IamClientConfig )(implicit as: ActorSystem, mt: Materializer, ec: ExecutionContext): EventSource[A] = new EventSource[A] { private val logger = Logger[this.type] private val http = Http() private def addCredentials(request: HttpRequest)(implicit cred: Option[AuthToken]): HttpRequest = cred.map(token => request.addCredentials(OAuth2BearerToken(token.value))).getOrElse(request) private def send(request: HttpRequest)(implicit cred: Option[AuthToken]): Future[HttpResponse] = http.singleRequest(addCredentials(request)).map { resp => if (!resp.status.isSuccess()) logger.warn(s"HTTP response when performing SSE request: status = '${resp.status}'") resp } override def apply(iri: AbsoluteIri, offset: Option[String])( implicit cred: Option[AuthToken] ): Source[A, NotUsed] = SSESource(iri.asAkka, send, offset, config.sseRetryDelay).flatMapConcat { sse => decode[A](sse.data) match { case Right(ev) => Source.single(ev) case Left(err) => logger.error(s"Failed to decode admin event '$sse'", err) Source.empty } } } }
Example 182
Source File: PermissionsRoutes.scala From nexus-iam with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam.routes import akka.http.javadsl.server.Rejections._ import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import ch.epfl.bluebrain.nexus.iam.config.AppConfig.HttpConfig import ch.epfl.bluebrain.nexus.iam.directives.AuthDirectives.authenticator import ch.epfl.bluebrain.nexus.iam.marshallers.instances._ import ch.epfl.bluebrain.nexus.iam.permissions.Permissions import ch.epfl.bluebrain.nexus.iam.realms.Realms import ch.epfl.bluebrain.nexus.iam.routes.PermissionsRoutes.PatchPermissions import ch.epfl.bluebrain.nexus.iam.routes.PermissionsRoutes.PatchPermissions.{Append, Replace, Subtract} import ch.epfl.bluebrain.nexus.iam.types.ResourceF._ import ch.epfl.bluebrain.nexus.iam.types.{Caller, Permission} import io.circe.{Decoder, DecodingFailure} import kamon.instrumentation.akka.http.TracingDirectives.operationName import monix.eval.Task import monix.execution.Scheduler.Implicits.global class PermissionsRoutes(permissions: Permissions[Task], realms: Realms[Task])(implicit http: HttpConfig) { def routes: Route = (pathPrefix("permissions") & pathEndOrSingleSlash) { operationName(s"/${http.prefix}/permissions") { authenticateOAuth2Async("*", authenticator(realms)).withAnonymousUser(Caller.anonymous) { implicit caller => concat( get { parameter("rev".as[Long].?) { case Some(rev) => complete(permissions.fetchAt(rev).runNotFound) case None => complete(permissions.fetch.runToFuture) } }, (put & parameter("rev" ? 0L)) { rev => entity(as[PatchPermissions]) { case Replace(set) => complete(permissions.replace(set, rev).runToFuture) case _ => reject(validationRejection("Only @type 'Replace' is permitted when using 'put'.")) } }, delete { parameter("rev".as[Long]) { rev => complete(permissions.delete(rev).runToFuture) } }, (patch & parameter("rev" ? 0L)) { rev => entity(as[PatchPermissions]) { case Append(set) => complete(permissions.append(set, rev).runToFuture) case Subtract(set) => complete(permissions.subtract(set, rev).runToFuture) case _ => reject(validationRejection("Only @type 'Append' or 'Subtract' is permitted when using 'patch'.")) } } ) } } } } object PermissionsRoutes { private[routes] sealed trait PatchPermissions extends Product with Serializable private[routes] object PatchPermissions { final case class Append(permissions: Set[Permission]) extends PatchPermissions final case class Subtract(permissions: Set[Permission]) extends PatchPermissions final case class Replace(permissions: Set[Permission]) extends PatchPermissions implicit val patchPermissionsDecoder: Decoder[PatchPermissions] = Decoder.instance { hc => for { permissions <- hc.get[Set[Permission]]("permissions") tpe = hc.get[String]("@type").getOrElse("Replace") patch <- tpe match { case "Replace" => Right(Replace(permissions)) case "Append" => Right(Append(permissions)) case "Subtract" => Right(Subtract(permissions)) case _ => Left(DecodingFailure("@type field must have Append or Subtract value", hc.history)) } } yield patch } } }
Example 183
Source File: EventSerializer.scala From nexus-iam with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam.io import java.nio.charset.Charset import akka.actor.ExtendedActorSystem import akka.serialization.SerializerWithStringManifest import ch.epfl.bluebrain.nexus.iam.acls.AclEvent import ch.epfl.bluebrain.nexus.iam.config.AppConfig.HttpConfig import ch.epfl.bluebrain.nexus.iam.config.Settings import ch.epfl.bluebrain.nexus.iam.permissions.PermissionsEvent import ch.epfl.bluebrain.nexus.iam.realms.RealmEvent import ch.epfl.bluebrain.nexus.iam.types.GrantType.Camel._ import ch.epfl.bluebrain.nexus.rdf.Iri.Url import ch.epfl.bluebrain.nexus.rdf.implicits._ import io.circe.generic.extras.Configuration import io.circe.generic.extras.semiauto._ import io.circe.parser._ import io.circe.syntax._ import io.circe.{Decoder, Encoder, Printer} class EventSerializer(system: ExtendedActorSystem) extends SerializerWithStringManifest { private val utf8 = Charset.forName("UTF-8") private val printer = Printer.noSpaces.copy(dropNullValues = true) private[io] implicit val http: HttpConfig = Settings(system).appConfig.http private[io] implicit val config: Configuration = Configuration.default.withDiscriminator("@type") private[io] implicit val urlEncoder: Encoder[Url] = Encoder.encodeString.contramap(_.asUri) private[io] implicit val urlDecoder: Decoder[Url] = Decoder.decodeString.emap(Url.apply) private[io] implicit val permissionEventEncoder: Encoder[PermissionsEvent] = deriveConfiguredEncoder[PermissionsEvent] private[io] implicit val permissionEventDecoder: Decoder[PermissionsEvent] = deriveConfiguredDecoder[PermissionsEvent] private[io] implicit val aclEventEncoder: Encoder[AclEvent] = deriveConfiguredEncoder[AclEvent] private[io] implicit val aclEventDecoder: Decoder[AclEvent] = deriveConfiguredDecoder[AclEvent] private[io] implicit val realmEventEncoder: Encoder[RealmEvent] = deriveConfiguredEncoder[RealmEvent] private[io] implicit val realmEventDecoder: Decoder[RealmEvent] = deriveConfiguredDecoder[RealmEvent] override val identifier: Int = 1225 override def manifest(o: AnyRef): String = o match { case _: PermissionsEvent => "permissions-event" case _: AclEvent => "acl-event" case _: RealmEvent => "realm-event" case other => throw new IllegalArgumentException( s"Cannot determine manifest for unknown type: '${other.getClass.getCanonicalName}'" ) } override def toBinary(o: AnyRef): Array[Byte] = o match { case ev: PermissionsEvent => ev.asJson.printWith(printer).getBytes(utf8) case ev: AclEvent => ev.asJson.printWith(printer).getBytes(utf8) case ev: RealmEvent => ev.asJson.printWith(printer).getBytes(utf8) case other => throw new IllegalArgumentException(s"Cannot serialize unknown type: '${other.getClass.getCanonicalName}'") } override def fromBinary(bytes: Array[Byte], manifest: String): AnyRef = manifest match { case "permissions-event" => val str = new String(bytes, utf8) decode[PermissionsEvent](str) .getOrElse(throw new IllegalArgumentException(s"Cannot deserialize value: '$str' to 'PermissionsEvent'")) case "acl-event" => val str = new String(bytes, utf8) decode[AclEvent](str) .getOrElse(throw new IllegalArgumentException(s"Cannot deserialize value: '$str' to 'AclEvent'")) case "realm-event" => val str = new String(bytes, utf8) decode[RealmEvent](str) .getOrElse(throw new IllegalArgumentException(s"Cannot deserialize value: '$str' to 'RealmEvent'")) case other => throw new IllegalArgumentException(s"Cannot deserialize type with unknown manifest: '$other'") } }
Example 184
Source File: GrantTypeSpec.scala From nexus-iam with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam.types import ch.epfl.bluebrain.nexus.commons.test.EitherValues import ch.epfl.bluebrain.nexus.iam.types.GrantType._ import io.circe.{Decoder, Encoder, Json} import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike import org.scalatest.Inspectors class GrantTypeSpec extends AnyWordSpecLike with Matchers with Inspectors with EitherValues { "A GrantType" when { "using Camel encoders" should { import GrantType.Camel._ val map = Map( AuthorizationCode -> "authorizationCode", Implicit -> "implicit", Password -> "password", ClientCredentials -> "clientCredentials", DeviceCode -> "deviceCode", RefreshToken -> "refreshToken" ) "be encoded properly" in { val encoder = implicitly[Encoder[GrantType]] forAll(map.toList) { case (gt, expected) => encoder(gt) shouldEqual Json.fromString(expected) } } "be decoded properly" in { val decoder = implicitly[Decoder[GrantType]] forAll(map.toList) { case (expected, gt) => decoder.decodeJson(Json.fromString(gt)).rightValue shouldEqual expected } } "fail to decode for unknown string" in { val decoder = implicitly[Decoder[GrantType]] decoder.decodeJson(Json.fromString("incorrect")).leftValue } } "using Snake encoders" should { import GrantType.Snake._ val map = Map( AuthorizationCode -> "authorization_code", Implicit -> "implicit", Password -> "password", ClientCredentials -> "client_credentials", DeviceCode -> "device_code", RefreshToken -> "refresh_token" ) "be encoded properly" in { val encoder = implicitly[Encoder[GrantType]] forAll(map.toList) { case (gt, expected) => encoder(gt) shouldEqual Json.fromString(expected) } } "be decoded properly" in { val decoder = implicitly[Decoder[GrantType]] forAll(map.toList) { case (expected, gtString) => decoder.decodeJson(Json.fromString(gtString)).rightValue shouldEqual expected } } "fail to decode for unknown string" in { val decoder = implicitly[Decoder[GrantType]] decoder.decodeJson(Json.fromString("incorrect")).leftValue } } } }
Example 185
Source File: CirceConfigLaws.scala From circe-config with Apache License 2.0 | 5 votes |
package io.circe.config import cats.instances.either._ import cats.laws._ import cats.laws.discipline._ import io.circe.{Decoder, Json, Parser, ParsingFailure} import io.circe.testing.ParserTests import org.scalatest.flatspec.AnyFlatSpec import org.scalatestplus.scalacheck.Checkers import org.scalacheck.{Arbitrary, Prop} import org.typelevel.discipline.Laws import com.typesafe.config.{parser => _, _} class CirceConfigLaws extends AnyFlatSpec { implicit val arbitraryConfigJson: Arbitrary[Json] = Arbitrary { def normalize(json: Json): Json = json.mapObject(_.filterKeys(_.nonEmpty).mapValues(normalize)).mapArray(_.map(normalize)).mapNumber { number => // Lower the precision to the types used internally by // Lightbend Config to ensure that numbers are representable. val double: java.lang.Double = number.toDouble val long: java.lang.Long = double.toLong val json = if (double.isInfinite) // While +/+Infinity can be represented, it cannot be round-tripped. Json.fromInt(42) else if (long == double) // Emulate Lightbend Config's internal cast: // https://github.com/lightbend/config/blob/v1.3.4/config/src/main/java/com/typesafe/config/impl/ConfigNumber.java#L96-L104 Json.fromLong(long) else Json.fromDouble(double).get json.asNumber.get } for (jsonObject <- io.circe.testing.instances.arbitraryJsonObject.arbitrary) yield normalize(Json.fromJsonObject(jsonObject)) } def checkLaws(name: String, ruleSet: Laws#RuleSet): Unit = ruleSet.all.properties.zipWithIndex.foreach { case ((id, prop), 0) => name should s"obey $id" in Checkers.check(prop) case ((id, prop), _) => it should s"obey $id" in Checkers.check(prop) } checkLaws("Parser", ParserTests(parser).fromString) checkLaws( "Parser", ParserTests(parser).fromFunction[Config]("fromConfig")( ConfigFactory.parseString, _.parse, _.decode[Json], _.decodeAccumulating[Json] ) ) checkLaws("Printer", PrinterTests(parser).fromJson) checkLaws("Codec", CodecTests[Config](syntax.configDecoder, parser.parse).fromFunction("fromConfig")) } case class PrinterTests(parser: Parser) extends Laws { def fromJson(implicit A: Arbitrary[Json]): RuleSet = new DefaultRuleSet( name = "printer", parent = None, "roundTrip" -> Prop.forAll { (json: Json) => parser.parse(printer.print(json)) <-> Right(json) } ) } case class CodecTests[A](decoder: Decoder[A], parse: A => Either[ParsingFailure, Json]) extends Laws { def fromFunction(name: String)(implicit arbitraryJson: Arbitrary[Json]): RuleSet = new DefaultRuleSet( name = s"codec[$name]", parent = None, "decodingRoundTrip" -> Prop.forAll { (json: Json) => decoder.decodeJson(json).flatMap(parse) <-> Right(json) } ) }
Example 186
Source File: ConfiguredAsObjectCodec.scala From circe-generic-extras with Apache License 2.0 | 5 votes |
package io.circe.generic.extras.codec import io.circe.{ Decoder, Encoder, HCursor, JsonObject } import io.circe.generic.codec.DerivedAsObjectCodec import io.circe.generic.extras.{ Configuration, JsonKey } import io.circe.generic.extras.decoding.ConfiguredDecoder import io.circe.generic.extras.encoding.ConfiguredAsObjectEncoder import io.circe.generic.extras.util.RecordToMap import scala.annotation.implicitNotFound import shapeless.{ Annotations, Coproduct, Default, HList, LabelledGeneric, Lazy } import shapeless.ops.hlist.ToTraversable import shapeless.ops.record.Keys @implicitNotFound( """Could not find ConfiguredAsObjectCodec for type ${A}. Some possible causes for this: - ${A} isn't a case class or sealed trat - some of ${A}'s members don't have codecs of their own - missing implicit Configuration""" ) abstract class ConfiguredAsObjectCodec[A] extends DerivedAsObjectCodec[A] object ConfiguredAsObjectCodec { implicit def codecForCaseClass[A, R <: HList, D <: HList, F <: HList, K <: HList](implicit gen: LabelledGeneric.Aux[A, R], codec: Lazy[ReprAsObjectCodec[R]], defaults: Default.AsRecord.Aux[A, D], defaultMapper: RecordToMap[D], config: Configuration, fields: Keys.Aux[R, F], fieldsToList: ToTraversable.Aux[F, List, Symbol], keys: Annotations.Aux[JsonKey, A, K], keysToList: ToTraversable.Aux[K, List, Option[JsonKey]] ): ConfiguredAsObjectCodec[A] = new ConfiguredAsObjectCodec[A] { private[this] val decodeA: Decoder[A] = ConfiguredDecoder.decodeCaseClass[A, R, D, F, K]( gen, codec, defaults, defaultMapper, config, fields, fieldsToList, keys, keysToList ) private[this] val encodeA: Encoder.AsObject[A] = ConfiguredAsObjectEncoder.encodeCaseClass[A, R, F, K](gen, codec, config, fields, fieldsToList, keys, keysToList) final def apply(c: HCursor): Decoder.Result[A] = decodeA.apply(c) final override def decodeAccumulating(c: HCursor): Decoder.AccumulatingResult[A] = decodeA.decodeAccumulating(c) final def encodeObject(a: A): JsonObject = encodeA.encodeObject(a) } implicit def codecForAdt[A, R <: Coproduct](implicit gen: LabelledGeneric.Aux[A, R], codec: Lazy[ReprAsObjectCodec[R]], config: Configuration ): ConfiguredAsObjectCodec[A] = new ConfiguredAsObjectCodec[A] { private[this] val decodeA: Decoder[A] = ConfiguredDecoder.decodeAdt[A, R](gen, codec, config) private[this] val encodeA: Encoder.AsObject[A] = ConfiguredAsObjectEncoder.encodeAdt[A, R](gen, codec, config) final def apply(c: HCursor): Decoder.Result[A] = decodeA.apply(c) final override def decodeAccumulating(c: HCursor): Decoder.AccumulatingResult[A] = decodeA.decodeAccumulating(c) final def encodeObject(a: A): JsonObject = encodeA.encodeObject(a) } }
Example 187
Source File: UnwrappedCodec.scala From circe-generic-extras with Apache License 2.0 | 5 votes |
package io.circe.generic.extras.codec import io.circe.{ Codec, Decoder, Encoder, HCursor, Json } import scala.annotation.implicitNotFound import shapeless.{ ::, Generic, HNil, Lazy } @implicitNotFound( """Could not find UnwrappedCodec for type ${A}. Some possible causes for this: - ${A} isn't a case class or sealed trat - some of ${A}'s members don't have codecs of their own - missing implicit Configuration""" ) abstract class UnwrappedCodec[A] extends Codec[A] object UnwrappedCodec { implicit def codecForUnwrapped[A, R](implicit gen: Lazy[Generic.Aux[A, R :: HNil]], decodeR: Decoder[R], encodeR: Encoder[R] ): UnwrappedCodec[A] = new UnwrappedCodec[A] { override def apply(c: HCursor): Decoder.Result[A] = decodeR(c) match { case Right(unwrapped) => Right(gen.value.from(unwrapped :: HNil)) case l @ Left(_) => l.asInstanceOf[Decoder.Result[A]] } override def apply(a: A): Json = encodeR(gen.value.to(a).head) } }
Example 188
Source File: EnumerationCodec.scala From circe-generic-extras with Apache License 2.0 | 5 votes |
package io.circe.generic.extras.codec import io.circe.{ Codec, Decoder, DecodingFailure, HCursor, Json } import io.circe.generic.extras.Configuration import scala.annotation.implicitNotFound import shapeless.{ :+:, CNil, Coproduct, HNil, Inl, Inr, LabelledGeneric, Witness } import shapeless.labelled.{ FieldType, field } @implicitNotFound( """Could not find EnumerationCodec for type ${A}. Some possible causes for this: - ${A} isn't a case class or sealed trat - some of ${A}'s members don't have codecs of their own - missing implicit Configuration""" ) abstract class EnumerationCodec[A] extends Codec[A] object EnumerationCodec { implicit val codecForEnumerationCNil: EnumerationCodec[CNil] = new EnumerationCodec[CNil] { def apply(c: HCursor): Decoder.Result[CNil] = Left(DecodingFailure("Enumeration", c.history)) def apply(a: CNil): Json = sys.error("Cannot encode CNil") } implicit def codecForEnumerationCCons[K <: Symbol, V, R <: Coproduct](implicit witK: Witness.Aux[K], gen: LabelledGeneric.Aux[V, HNil], codecForR: EnumerationCodec[R], config: Configuration = Configuration.default ): EnumerationCodec[FieldType[K, V] :+: R] = new EnumerationCodec[FieldType[K, V] :+: R] { def apply(c: HCursor): Decoder.Result[FieldType[K, V] :+: R] = c.as[String] match { case Right(s) if s == config.transformConstructorNames(witK.value.name) => Right(Inl(field[K](gen.from(HNil)))) case Right(_) => codecForR.apply(c) match { case Right(v) => Right(Inr(v)) case Left(err) => Left(err) } case Left(err) => Left(DecodingFailure("Enumeration", c.history)) } def apply(a: FieldType[K, V] :+: R): Json = a match { case Inl(l) => Json.fromString(config.transformConstructorNames(witK.value.name)) case Inr(r) => codecForR(r) } } implicit def codecForEnumeration[A, R <: Coproduct](implicit gen: LabelledGeneric.Aux[A, R], codecForR: EnumerationCodec[R] ): EnumerationCodec[A] = new EnumerationCodec[A] { def apply(c: HCursor): Decoder.Result[A] = codecForR(c) match { case Right(v) => Right(gen.from(v)) case Left(err) => Left(err) } def apply(a: A): Json = codecForR(gen.to(a)) } }
Example 189
Source File: ReprAsObjectCodec.scala From circe-generic-extras with Apache License 2.0 | 5 votes |
package io.circe.generic.extras.codec import cats.data.Validated import io.circe.{ Decoder, DecodingFailure, HCursor, JsonObject } import io.circe.generic.extras.ConfigurableDeriver import io.circe.generic.extras.decoding.ReprDecoder import io.circe.generic.extras.encoding.ReprAsObjectEncoder import scala.annotation.implicitNotFound import scala.collection.immutable.Map import scala.language.experimental.macros import shapeless.HNil @implicitNotFound( """Could not find ReprAsObjectCodec for type ${A}. Some possible causes for this: - ${A} isn't a case class or sealed trat - some of ${A}'s members don't have codecs of their own - missing implicit Configuration""" ) abstract class ReprAsObjectCodec[A] extends ReprDecoder[A] with ReprAsObjectEncoder[A] object ReprAsObjectCodec { implicit def deriveReprAsObjectCodec[R]: ReprAsObjectCodec[R] = macro ConfigurableDeriver.deriveConfiguredCodec[R] val hnilReprCodec: ReprAsObjectCodec[HNil] = new ReprAsObjectCodec[HNil] { def configuredDecode(c: HCursor)( transformMemberNames: String => String, transformConstructorNames: String => String, defaults: Map[String, Any], discriminator: Option[String] ): Decoder.Result[HNil] = if (c.value.isObject) Right(HNil) else Left(DecodingFailure("HNil", c.history)) def configuredDecodeAccumulating(c: HCursor)( transformMemberNames: String => String, transformConstructorNames: String => String, defaults: Map[String, Any], discriminator: Option[String] ): Decoder.AccumulatingResult[HNil] = if (c.value.isObject) Validated.valid(HNil) else Validated.invalidNel(DecodingFailure("HNil", c.history)) def configuredEncodeObject(a: HNil)( transformMemberNames: String => String, transformDiscriminator: String => String, discriminator: Option[String] ): JsonObject = JsonObject.empty } }
Example 190
Source File: IncompleteConfiguredDecoders.scala From circe-generic-extras with Apache License 2.0 | 5 votes |
package io.circe.generic.extras.decoding import io.circe.{ Decoder, HCursor } import io.circe.generic.extras.Configuration import io.circe.generic.extras.util.RecordToMap import io.circe.generic.util.PatchWithOptions import scala.collection.immutable.Map import shapeless.{ Default, HList, LabelledGeneric } import shapeless.ops.function.FnFromProduct import shapeless.ops.record.RemoveAll private[circe] trait IncompleteConfiguredDecoders { implicit final def decodeIncompleteCaseClass[F, P <: HList, A, D <: HList, T <: HList, R <: HList](implicit ffp: FnFromProduct.Aux[P => A, F], gen: LabelledGeneric.Aux[A, T], removeAll: RemoveAll.Aux[T, P, (P, R)], decode: ReprDecoder[R], defaults: Default.AsRecord.Aux[A, D], defaultMapper: RecordToMap[D], config: Configuration ): ConfiguredDecoder[F] = new ConfiguredDecoder[F](config) { private[this] val defaultMap: Map[String, Any] = if (config.useDefaults) defaultMapper(defaults()) else Map.empty final def apply(c: HCursor): Decoder.Result[F] = decode.configuredDecode(c)( config.transformMemberNames, constructorNameTransformer, defaultMap, None ) match { case Right(r) => Right(ffp(p => gen.from(removeAll.reinsert((p, r))))) case l @ Left(_) => l.asInstanceOf[Decoder.Result[F]] } override final def decodeAccumulating(c: HCursor): Decoder.AccumulatingResult[F] = decode .configuredDecodeAccumulating(c)( config.transformMemberNames, constructorNameTransformer, defaultMap, None ) .map(r => ffp(p => gen.from(removeAll.reinsert((p, r))))) } implicit final def decodeCaseClassPatch[A, D <: HList, R <: HList, O <: HList](implicit gen: LabelledGeneric.Aux[A, R], patch: PatchWithOptions.Aux[R, O], decode: ReprDecoder[O], defaults: Default.AsRecord.Aux[A, D], defaultMapper: RecordToMap[D], config: Configuration ): ConfiguredDecoder[A => A] = new ConfiguredDecoder[A => A](config) { private[this] val defaultMap: Map[String, Any] = if (config.useDefaults) defaultMapper(defaults()) else Map.empty final def apply(c: HCursor): Decoder.Result[A => A] = decode.configuredDecode(c)( config.transformMemberNames, constructorNameTransformer, defaultMap, None ) match { case Right(o) => Right(a => gen.from(patch(gen.to(a), o))) case l @ Left(_) => l.asInstanceOf[Decoder.Result[A => A]] } override final def decodeAccumulating(c: HCursor): Decoder.AccumulatingResult[A => A] = decode .configuredDecodeAccumulating(c)( config.transformMemberNames, constructorNameTransformer, defaultMap, None ) .map(o => a => gen.from(patch(gen.to(a), o))) } }
Example 191
Source File: UnwrappedDecoder.scala From circe-generic-extras with Apache License 2.0 | 5 votes |
package io.circe.generic.extras.decoding import io.circe.{ Decoder, HCursor } import scala.annotation.implicitNotFound import shapeless.{ ::, Generic, HNil, Lazy } @implicitNotFound( """Could not find UnwrappedDecoder for type ${A}. Some possible causes for this: - ${A} isn't a case class or sealed trat - some of ${A}'s members don't have codecs of their own - missing implicit Configuration""" ) abstract class UnwrappedDecoder[A] extends Decoder[A] object UnwrappedDecoder { implicit def decodeUnwrapped[A, R](implicit gen: Lazy[Generic.Aux[A, R :: HNil]], decodeR: Decoder[R] ): UnwrappedDecoder[A] = new UnwrappedDecoder[A] { override def apply(c: HCursor): Decoder.Result[A] = decodeR(c) match { case Right(unwrapped) => Right(gen.value.from(unwrapped :: HNil)) case l @ Left(_) => l.asInstanceOf[Decoder.Result[A]] } } }
Example 192
Source File: EnumerationDecoder.scala From circe-generic-extras with Apache License 2.0 | 5 votes |
package io.circe.generic.extras.decoding import io.circe.{ Decoder, DecodingFailure, HCursor } import io.circe.generic.extras.Configuration import scala.annotation.implicitNotFound import shapeless.{ :+:, CNil, Coproduct, HNil, Inl, Inr, LabelledGeneric, Witness } import shapeless.labelled.{ FieldType, field } @implicitNotFound( """Could not find EnumerationDecoder for type ${A}. Some possible causes for this: - ${A} isn't a case class or sealed trat - some of ${A}'s members don't have codecs of their own - missing implicit Configuration""" ) abstract class EnumerationDecoder[A] extends Decoder[A] object EnumerationDecoder { implicit val decodeEnumerationCNil: EnumerationDecoder[CNil] = new EnumerationDecoder[CNil] { def apply(c: HCursor): Decoder.Result[CNil] = Left(DecodingFailure("Enumeration", c.history)) } implicit def decodeEnumerationCCons[K <: Symbol, V, R <: Coproduct](implicit witK: Witness.Aux[K], gen: LabelledGeneric.Aux[V, HNil], decodeR: EnumerationDecoder[R], config: Configuration = Configuration.default ): EnumerationDecoder[FieldType[K, V] :+: R] = new EnumerationDecoder[FieldType[K, V] :+: R] { def apply(c: HCursor): Decoder.Result[FieldType[K, V] :+: R] = c.as[String] match { case Right(s) if s == config.transformConstructorNames(witK.value.name) => Right(Inl(field[K](gen.from(HNil)))) case Right(_) => decodeR.apply(c) match { case Right(v) => Right(Inr(v)) case Left(err) => Left(err) } case Left(err) => Left(DecodingFailure("Enumeration", c.history)) } } implicit def decodeEnumeration[A, Repr <: Coproduct](implicit gen: LabelledGeneric.Aux[A, Repr], decodeR: EnumerationDecoder[Repr] ): EnumerationDecoder[A] = new EnumerationDecoder[A] { def apply(c: HCursor): Decoder.Result[A] = decodeR(c) match { case Right(v) => Right(gen.from(v)) case Left(err) => Left(err) } } }
Example 193
Source File: ConfiguredJsonCodecWithKeySuite.scala From circe-generic-extras with Apache License 2.0 | 5 votes |
package io.circe.generic.extras import cats.kernel.Eq import io.circe.{ Decoder, Encoder } import io.circe.literal._ import io.circe.testing.CodecTests import org.scalacheck.{ Arbitrary, Gen } import org.scalacheck.Arbitrary.arbitrary object ConfiguredJsonCodecWithKeySuite { implicit val customConfig: Configuration = Configuration.default.withSnakeCaseMemberNames.withDefaults.withDiscriminator("type").withSnakeCaseConstructorNames @ConfiguredJsonCodec sealed trait ConfigExampleBase case class ConfigExampleFoo(thisIsAField: String, a: Int = 0, @JsonKey("myField") b: Double) extends ConfigExampleBase object ConfigExampleFoo { implicit val eqConfigExampleFoo: Eq[ConfigExampleFoo] = Eq.fromUniversalEquals val genConfigExampleFoo: Gen[ConfigExampleFoo] = for { thisIsAField <- arbitrary[String] a <- arbitrary[Int] b <- arbitrary[Double] } yield ConfigExampleFoo(thisIsAField, a, b) implicit val arbitraryConfigExampleFoo: Arbitrary[ConfigExampleFoo] = Arbitrary(genConfigExampleFoo) } object ConfigExampleBase { implicit val eqConfigExampleBase: Eq[ConfigExampleBase] = Eq.fromUniversalEquals val genConfigExampleBase: Gen[ConfigExampleBase] = ConfigExampleFoo.genConfigExampleFoo implicit val arbitraryConfigExampleBase: Arbitrary[ConfigExampleBase] = Arbitrary(genConfigExampleBase) } } class ConfiguredJsonCodecWithKeySuite extends CirceSuite { import ConfiguredJsonCodecWithKeySuite._ checkLaws("Codec[ConfigExampleBase]", CodecTests[ConfigExampleBase].codec) "ConfiguredJsonCodec" should "support key annotation and configuration" in forAll { (f: String, b: Double) => val foo: ConfigExampleBase = ConfigExampleFoo(f, 0, b) val json = json"""{ "type": "config_example_foo", "this_is_a_field": $f, "myField": $b}""" val expected = json"""{ "type": "config_example_foo", "this_is_a_field": $f, "a": 0, "myField": $b}""" assert(Encoder[ConfigExampleBase].apply(foo) === expected) assert(Decoder[ConfigExampleBase].decodeJson(json) === Right(foo)) } }
Example 194
Source File: EnumerationSemiautoDerivedSuite.scala From circe-generic-extras with Apache License 2.0 | 5 votes |
package io.circe.generic.extras import io.circe.{ Codec, Decoder, Encoder } import io.circe.generic.extras.semiauto._ import io.circe.literal._ import io.circe.testing.CodecTests import shapeless.test.illTyped import examples._ class EnumerationSemiautoDerivedSuite extends CirceSuite { implicit val decodeCardinalDirection: Decoder[CardinalDirection] = deriveEnumerationDecoder implicit val encodeCardinalDirection: Encoder[CardinalDirection] = deriveEnumerationEncoder val codecForCardinalDirection: Codec[CardinalDirection] = deriveEnumerationCodec checkLaws("Codec[CardinalDirection]", CodecTests[CardinalDirection].codec) checkLaws( "Codec[CardinalDirection] via Codec", CodecTests[CardinalDirection](codecForCardinalDirection, codecForCardinalDirection).codec ) checkLaws( "Codec[CardinalDirection] via Decoder and Codec", CodecTests[CardinalDirection](implicitly, codecForCardinalDirection).codec ) checkLaws( "Codec[CardinalDirection] via Encoder and Codec", CodecTests[CardinalDirection](codecForCardinalDirection, implicitly).codec ) "deriveEnumerationDecoder" should "not compile on an ADT with case classes" in { implicit val config: Configuration = Configuration.default illTyped("deriveEnumerationDecoder[ExtendedCardinalDirection]") } it should "respect Configuration" in { implicit val config: Configuration = Configuration.default.withSnakeCaseConstructorNames val decodeMary = deriveEnumerationDecoder[Mary] val expected = json""""little_lamb"""" assert(decodeMary.decodeJson(expected) === Right(LittleLamb)) } "deriveEnumerationEncoder" should "not compile on an ADT with case classes" in { implicit val config: Configuration = Configuration.default illTyped("deriveEnumerationEncoder[ExtendedCardinalDirection]") } it should "respect Configuration" in { implicit val config: Configuration = Configuration.default.withSnakeCaseConstructorNames val encodeMary = deriveEnumerationEncoder[Mary] val expected = json""""little_lamb"""" assert(encodeMary(LittleLamb) === expected) } }
Example 195
Source File: persistentEncoderUtil.scala From aecor with MIT License | 5 votes |
package aecor.example import java.nio.ByteBuffer import java.nio.charset.StandardCharsets import aecor.runtime.akkapersistence.serialization.{ DecodingFailure, PersistentDecoder, PersistentEncoder, PersistentRepr } import io.circe.{ Decoder, Encoder, jawn } object persistentEncoderUtil { def circePersistentEncoder[A](implicit encoder: Encoder[A]): PersistentEncoder[A] = PersistentEncoder.instance( e => PersistentRepr("", encoder(e).noSpaces.getBytes(StandardCharsets.UTF_8)) ) def circePersistentDecoder[A](implicit decoder: Decoder[A]): PersistentDecoder[A] = PersistentDecoder.instance( repr => jawn .parseByteBuffer(ByteBuffer.wrap(repr.payload)) .flatMap(decoder.decodeJson) .left .map(DecodingFailure.fromThrowable) ) }
Example 196
Source File: AnyValCirceEncoding.scala From aecor with MIT License | 5 votes |
package aecor.example import io.circe.{ Decoder, Encoder } import shapeless.Unwrapped trait AnyValCirceEncoding { implicit def anyValEncoder[V, U](implicit ev: V <:< AnyVal, V: Unwrapped.Aux[V, U], encoder: Encoder[U]): Encoder[V] = { val _ = ev encoder.contramap(V.unwrap) } implicit def anyValDecoder[V, U](implicit ev: V <:< AnyVal, V: Unwrapped.Aux[V, U], decoder: Decoder[U]): Decoder[V] = { val _ = ev decoder.map(V.wrap) } } object AnyValCirceEncoding extends AnyValCirceEncoding
Example 197
Source File: Algebra.scala From aecor with MIT License | 5 votes |
package aecor.example.account import aecor.encoding.WireProtocol import aecor.example.AnyValCirceEncoding import aecor.example.common.Amount import aecor.example.transaction.TransactionId import aecor.macros.boopickle.BoopickleWireProtocol import cats.tagless.{ Derive, FunctorK } import io.circe.{ Decoder, Encoder } final case class AccountTransactionId(baseTransactionId: TransactionId, kind: AccountTransactionKind) object AccountTransactionId extends AnyValCirceEncoding { implicit def decoder: Decoder[AccountTransactionId] = io.circe.generic.semiauto.deriveDecoder implicit def encoder: Encoder[AccountTransactionId] = io.circe.generic.semiauto.deriveEncoder } sealed abstract class AccountTransactionKind extends Product with Serializable object AccountTransactionKind { case object Normal extends AccountTransactionKind case object Revert extends AccountTransactionKind implicit val decoder: Decoder[AccountTransactionKind] = Decoder[String].emap { case "Normal" => Right(Normal) case "Revert" => Right(Revert) case _ => Left("Unknown AccountTransactionKind") } implicit val encoder: Encoder[AccountTransactionKind] = Encoder[String].contramap(_.toString) } trait Algebra[F[_]] { def open(checkBalance: Boolean): F[Unit] def credit(transactionId: AccountTransactionId, amount: Amount): F[Unit] def debit(transactionId: AccountTransactionId, amount: Amount): F[Unit] } object Algebra { import boopickle.Default._ implicit def functorK: FunctorK[Algebra] = Derive.functorK implicit def wireProtocol: WireProtocol[Algebra] = BoopickleWireProtocol.derive }
Example 198
Source File: PersistentEncoderCirce.scala From aecor with MIT License | 5 votes |
package aecor.tests import java.nio.ByteBuffer import java.nio.charset.StandardCharsets import aecor.runtime.akkapersistence.serialization.{ DecodingFailure, PersistentDecoder, PersistentEncoder, PersistentRepr } import io.circe.{ Decoder, Encoder, jawn } object PersistentEncoderCirce { def circePersistentEncoder[A](implicit encoder: Encoder[A]): PersistentEncoder[A] = PersistentEncoder.instance( e => PersistentRepr("", encoder(e).noSpaces.getBytes(StandardCharsets.UTF_8)) ) def circePersistentDecoder[A](implicit decoder: Decoder[A]): PersistentDecoder[A] = PersistentDecoder.instance( repr => jawn .parseByteBuffer(ByteBuffer.wrap(repr.payload)) .flatMap(decoder.decodeJson) .left .map(DecodingFailure.fromThrowable) ) }
Example 199
Source File: SourceSettings.scala From scylla-migrator with Apache License 2.0 | 5 votes |
package com.scylladb.migrator.config import cats.implicits._ import io.circe.syntax._ import io.circe.{ Decoder, DecodingFailure, Encoder, Json, ObjectEncoder } sealed trait SourceSettings object SourceSettings { case class Cassandra(host: String, port: Int, credentials: Option[Credentials], keyspace: String, table: String, splitCount: Option[Int], connections: Option[Int], fetchSize: Int, preserveTimestamps: Boolean) extends SourceSettings case class Parquet(path: String, credentials: Option[AWSCredentials]) extends SourceSettings implicit val decoder: Decoder[SourceSettings] = Decoder.instance { cursor => cursor.get[String]("type").flatMap { case "cassandra" | "scylla" => Decoder .forProduct9( "host", "port", "credentials", "keyspace", "table", "splitCount", "connections", "fetchSize", "preserveTimestamps")(Cassandra.apply) .apply(cursor) case "parquet" => Decoder .forProduct2("path", "credentials")(Parquet.apply) .apply(cursor) case otherwise => Left(DecodingFailure(s"Unknown source type: ${otherwise}", cursor.history)) } } implicit val encoder: Encoder[SourceSettings] = Encoder.instance { case s: Cassandra => Encoder .forProduct9( "host", "port", "credentials", "keyspace", "table", "splitCount", "connections", "fetchSize", "preserveTimestamps")(Cassandra.unapply(_: Cassandra).get) .encodeObject(s) .add("type", Json.fromString("cassandra")) .asJson case s: Parquet => Encoder .forProduct2("path", "credentials")(Parquet.unapply(_: Parquet).get) .encodeObject(s) .add("type", Json.fromString("parquet")) .asJson } }
Example 200
Source File: MigratorConfig.scala From scylla-migrator with Apache License 2.0 | 5 votes |
package com.scylladb.migrator.config import cats.implicits._ import com.datastax.spark.connector.rdd.partitioner.dht.{ BigIntToken, LongToken, Token } import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder } import io.circe.syntax._ import io.circe.yaml.parser import io.circe.yaml.syntax._ import io.circe.{ Decoder, DecodingFailure, Encoder, Error, Json } case class MigratorConfig(source: SourceSettings, target: TargetSettings, renames: List[Rename], savepoints: Savepoints, skipTokenRanges: Set[(Token[_], Token[_])], validation: Validation) { def render: String = this.asJson.asYaml.spaces2 } object MigratorConfig { implicit val tokenEncoder: Encoder[Token[_]] = Encoder.instance { case LongToken(value) => Json.obj("type" := "long", "value" := value) case BigIntToken(value) => Json.obj("type" := "bigint", "value" := value) } implicit val tokenDecoder: Decoder[Token[_]] = Decoder.instance { cursor => for { tpe <- cursor.get[String]("type").right result <- tpe match { case "long" => cursor.get[Long]("value").right.map(LongToken(_)) case "bigint" => cursor.get[BigInt]("value").right.map(BigIntToken(_)) case otherwise => Left(DecodingFailure(s"Unknown token type '$otherwise'", Nil)) } } yield result } implicit val migratorConfigDecoder: Decoder[MigratorConfig] = deriveDecoder[MigratorConfig] implicit val migratorConfigEncoder: Encoder[MigratorConfig] = deriveEncoder[MigratorConfig] def loadFrom(path: String): MigratorConfig = { val configData = scala.io.Source.fromFile(path).mkString parser .parse(configData) .leftWiden[Error] .flatMap(_.as[MigratorConfig]) .valueOr(throw _) } }