Port HTTP JSON API binary to 2.13 (#8824)

Tests are still missing. Simply haven’t found the time yet, I’ll
tackle those separately.

changelog_begin
changelog_end
This commit is contained in:
Moritz Kiefer 2021-02-12 09:54:47 +01:00 committed by GitHub
parent 94262e9f9a
commit c8b82f8e7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 146 additions and 142 deletions

View File

@ -183,7 +183,9 @@ jobs:
//ledger/... \
//ledger-service/... \
//triggers/... \
-//ledger-service/http-json/... \
-//ledger-service/http-json:tests \
-//ledger-service/http-json:integration-tests \
-//ledger-service/http-json:failure-tests \
-//ledger-service/http-json-perf/... \
-//ledger-service/http-json-testing/... \
//daml-script/dump/... \
@ -206,7 +208,9 @@ jobs:
-//language-support/scala/codegen-sample-app/... \
-//ledger/ledger-api-test-tool/... \
-//ledger/ledger-api-test-tool-on-canton/... \
-//ledger-service/http-json/... \
-//ledger-service/http-json:tests \
-//ledger-service/http-json:integration-tests \
-//ledger-service/http-json:failure-tests \
-//ledger-service/http-json-perf/... \
-//ledger-service/http-json-testing/...
displayName: 'Build'

View File

@ -7,9 +7,11 @@ load(
"da_scala_library",
"da_scala_test",
"lf_scalacopts",
"silencer_plugin",
)
load("//rules_daml:daml.bzl", "daml_compile")
load("@os_info//:os_info.bzl", "is_windows")
load("@scala_version//:index.bzl", "scala_version_suffix")
hj_scalacopts = lf_scalacopts + [
"-P:wartremover:traverser:org.wartremover.warts.NonUnitStatements",
@ -19,9 +21,30 @@ da_scala_library(
name = "http-json",
srcs = glob(["src/main/scala/**/*.scala"]),
plugins = [
"@maven//:org_typelevel_kind_projector_2_12_12",
"@maven//:org_typelevel_kind_projector_{}".format(scala_version_suffix),
silencer_plugin,
],
scala_deps = [
"@maven//:com_chuusai_shapeless",
"@maven//:com_github_scopt_scopt",
"@maven//:com_lihaoyi_sourcecode",
"@maven//:com_typesafe_akka_akka_http",
"@maven//:com_typesafe_akka_akka_http_core",
"@maven//:com_typesafe_scala_logging_scala_logging",
"@maven//:io_spray_spray_json",
"@maven//:org_scala_lang_modules_scala_collection_compat",
"@maven//:org_scalaz_scalaz_core",
"@maven//:org_tpolecat_doobie_core",
"@maven//:org_tpolecat_doobie_free",
"@maven//:org_tpolecat_doobie_postgres",
"@maven//:org_typelevel_cats_core",
"@maven//:org_typelevel_cats_effect",
"@maven//:org_typelevel_cats_free",
"@maven//:org_typelevel_cats_kernel",
],
scalacopts = hj_scalacopts + [
"-P:silencer:lineContentFilters=import scala.collection.compat",
],
scalacopts = hj_scalacopts,
tags = ["maven_coordinates=com.daml:http-json:__VERSION__"],
visibility = ["//visibility:public"],
runtime_deps = [
@ -44,22 +67,6 @@ da_scala_library(
"//libs-scala/doobie-slf4j",
"//libs-scala/ports",
"//libs-scala/scala-utils",
"@maven//:com_chuusai_shapeless_2_12",
"@maven//:com_github_scopt_scopt_2_12",
"@maven//:com_lihaoyi_sourcecode_2_12",
"@maven//:com_typesafe_akka_akka_http_2_12",
"@maven//:com_typesafe_akka_akka_http_core_2_12",
"@maven//:com_typesafe_scala_logging_scala_logging_2_12",
"@maven//:io_spray_spray_json_2_12",
"@maven//:org_scala_lang_modules_scala_collection_compat_2_12",
"@maven//:org_scalaz_scalaz_core_2_12",
"@maven//:org_tpolecat_doobie_core_2_12",
"@maven//:org_tpolecat_doobie_free_2_12",
"@maven//:org_tpolecat_doobie_postgres_2_12",
"@maven//:org_typelevel_cats_core_2_12",
"@maven//:org_typelevel_cats_effect_2_12",
"@maven//:org_typelevel_cats_free_2_12",
"@maven//:org_typelevel_cats_kernel_2_12",
],
)
@ -67,6 +74,26 @@ da_scala_binary(
name = "http-json-binary",
main_class = "com.daml.http.Main",
resources = [":src/main/resources/logback.xml"],
scala_deps = [
"@maven//:com_chuusai_shapeless",
"@maven//:com_github_scopt_scopt",
"@maven//:com_lihaoyi_sourcecode",
"@maven//:com_typesafe_akka_akka_http",
"@maven//:com_typesafe_akka_akka_http_core",
"@maven//:com_typesafe_akka_akka_http_spray_json",
"@maven//:com_typesafe_akka_akka_slf4j",
"@maven//:com_typesafe_scala_logging_scala_logging",
"@maven//:io_spray_spray_json",
"@maven//:org_scala_lang_modules_scala_collection_compat",
"@maven//:org_scalaz_scalaz_core",
"@maven//:org_tpolecat_doobie_core",
"@maven//:org_tpolecat_doobie_free",
"@maven//:org_tpolecat_doobie_postgres",
"@maven//:org_typelevel_cats_core",
"@maven//:org_typelevel_cats_effect",
"@maven//:org_typelevel_cats_free",
"@maven//:org_typelevel_cats_kernel",
],
scalacopts = hj_scalacopts,
tags = [
"maven_coordinates=com.daml:http-json-deploy:__VERSION__",
@ -90,24 +117,6 @@ da_scala_binary(
"//libs-scala/ports",
"//libs-scala/scala-utils",
"@maven//:ch_qos_logback_logback_classic",
"@maven//:com_chuusai_shapeless_2_12",
"@maven//:com_github_scopt_scopt_2_12",
"@maven//:com_lihaoyi_sourcecode_2_12",
"@maven//:com_typesafe_akka_akka_http_2_12",
"@maven//:com_typesafe_akka_akka_http_core_2_12",
"@maven//:com_typesafe_akka_akka_http_spray_json_2_12",
"@maven//:com_typesafe_akka_akka_slf4j_2_12",
"@maven//:com_typesafe_scala_logging_scala_logging_2_12",
"@maven//:io_spray_spray_json_2_12",
"@maven//:org_scala_lang_modules_scala_collection_compat_2_12",
"@maven//:org_scalaz_scalaz_core_2_12",
"@maven//:org_tpolecat_doobie_core_2_12",
"@maven//:org_tpolecat_doobie_free_2_12",
"@maven//:org_tpolecat_doobie_postgres_2_12",
"@maven//:org_typelevel_cats_core_2_12",
"@maven//:org_typelevel_cats_effect_2_12",
"@maven//:org_typelevel_cats_free_2_12",
"@maven//:org_typelevel_cats_kernel_2_12",
],
)

View File

@ -14,7 +14,7 @@ import scala.util.Try
object Cli extends StrictLogging {
private[http] def parseConfig(
args: Seq[String],
args: collection.Seq[String],
getEnvVar: String => Option[String] = sys.env.get,
): Option[Config] =
configParser(getEnvVar).parse(args, Config.Empty)

View File

@ -49,7 +49,7 @@ class CommandService(
val et: ET[ActiveContract[lav1.value.Value]] = for {
command <- either(createCommand(input))
request = submitAndWaitRequest(jwtPayload, input.meta, command)
response <- rightT(logResult('create, submitAndWaitForTransaction(jwt, request)))
response <- rightT(logResult(Symbol("create"), submitAndWaitForTransaction(jwt, request)))
contract <- either(exactlyOneActiveContract(response))
} yield contract
@ -66,7 +66,9 @@ class CommandService(
val request = submitAndWaitRequest(jwtPayload, input.meta, command)
val et: ET[ExerciseResponse[lav1.value.Value]] = for {
response <- rightT(logResult('exercise, submitAndWaitForTransactionTree(jwt, request)))
response <- rightT(
logResult(Symbol("exercise"), submitAndWaitForTransactionTree(jwt, request))
)
exerciseResult <- either(exerciseResult(response))
contracts <- either(contracts(response))
} yield ExerciseResponse(exerciseResult, contracts)
@ -84,7 +86,7 @@ class CommandService(
command <- either(createAndExerciseCommand(input))
request = submitAndWaitRequest(jwtPayload, input.meta, command)
response <- rightT(
logResult('createAndExercise, submitAndWaitForTransactionTree(jwt, request))
logResult(Symbol("createAndExercise"), submitAndWaitForTransactionTree(jwt, request))
)
exerciseResult <- either(exerciseResult(response))
contracts <- either(contracts(response))
@ -105,7 +107,7 @@ class CommandService(
input: CreateCommand[lav1.value.Record]
): Error \/ lav1.commands.Command.Command.Create = {
resolveTemplateId(input.templateId)
.toRightDisjunction(Error('createCommand, cannotResolveTemplateId(input.templateId)))
.toRightDisjunction(Error(Symbol("createCommand"), cannotResolveTemplateId(input.templateId)))
.map(tpId => Commands.create(refApiIdentifier(tpId), input.payload))
}
@ -134,7 +136,7 @@ class CommandService(
): Error \/ lav1.commands.Command.Command.CreateAndExercise =
resolveTemplateId(input.templateId)
.toRightDisjunction(
Error('createAndExerciseCommand, cannotResolveTemplateId(input.templateId))
Error(Symbol("createAndExerciseCommand"), cannotResolveTemplateId(input.templateId))
)
.map(tpId =>
Commands
@ -165,7 +167,12 @@ class CommandService(
activeContracts(response).flatMap {
case Seq(x) => \/-(x)
case xs @ _ =>
-\/(Error('exactlyOneActiveContract, s"Expected exactly one active contract, got: $xs"))
-\/(
Error(
Symbol("exactlyOneActiveContract"),
s"Expected exactly one active contract, got: $xs",
)
)
}
private def activeContracts(
@ -173,7 +180,7 @@ class CommandService(
): Error \/ ImmArraySeq[ActiveContract[lav1.value.Value]] =
response.transaction
.toRightDisjunction(
Error('activeContracts, s"Received response without transaction: $response")
Error(Symbol("activeContracts"), s"Received response without transaction: $response")
)
.flatMap(activeContracts)
@ -183,20 +190,22 @@ class CommandService(
Transactions
.allCreatedEvents(tx)
.traverse(ActiveContract.fromLedgerApi(_))
.leftMap(e => Error('activeContracts, e.shows))
.leftMap(e => Error(Symbol("activeContracts"), e.shows))
}
private def contracts(
response: lav1.command_service.SubmitAndWaitForTransactionTreeResponse
): Error \/ List[Contract[lav1.value.Value]] =
response.transaction
.toRightDisjunction(Error('contracts, s"Received response without transaction: $response"))
.toRightDisjunction(
Error(Symbol("contracts"), s"Received response without transaction: $response")
)
.flatMap(contracts)
private def contracts(
tx: lav1.transaction.TransactionTree
): Error \/ List[Contract[lav1.value.Value]] =
Contract.fromTransactionTree(tx).leftMap(e => Error('contracts, e.shows)).map(_.toList)
Contract.fromTransactionTree(tx).leftMap(e => Error(Symbol("contracts"), e.shows)).map(_.toList)
private def exerciseResult(
a: lav1.command_service.SubmitAndWaitForTransactionTreeResponse
@ -209,7 +218,7 @@ class CommandService(
result.toRightDisjunction(
Error(
'choiceArgument,
Symbol("choiceArgument"),
s"Cannot get exerciseResult from the first ExercisedEvent of gRPC response: ${a.toString}",
)
)

View File

@ -313,7 +313,7 @@ private[http] object ContractsFetch {
/** Plan inserts, deletes from an in-order batch of create/archive events. */
private def partitionInsertsDeletes(
txes: Traversable[lav1.event.Event]
txes: Iterable[lav1.event.Event]
): InsertDeleteStep.LAV1 = {
val csb = Vector.newBuilder[lav1.event.CreatedEvent]
val asb = Map.newBuilder[String, lav1.event.ArchivedEvent]
@ -492,12 +492,16 @@ private[http] object ContractsFetch {
(queries.deleteContracts(step.deletes.keySet) *>
queries.insertContracts(
step.inserts map (dbc =>
dbc copy (templateId =
stidMap getOrElse (dbc.templateId, throw new IllegalStateException(
"template ID missing from prior retrieval; impossible"
)),
signatories = domain.Party.unsubst(dbc.signatories),
observers = domain.Party.unsubst(dbc.observers)),
dbc.copy(
templateId = stidMap.getOrElse(
dbc.templateId,
throw new IllegalStateException(
"template ID missing from prior retrieval; impossible"
),
),
signatories = domain.Party.unsubst(dbc.signatories),
observers = domain.Party.unsubst(dbc.observers),
),
)
))
}.void

View File

@ -18,7 +18,6 @@ import com.daml.http.json.JsonProtocol.LfValueDatabaseCodec.{
import com.daml.http.query.ValuePredicate
import com.daml.http.util.ApiValueToLfValueConverter
import com.daml.http.util.FutureUtil.toFuture
import util.Collections._
import util.{ContractStreamStep, InsertDeleteStep}
import com.daml.jwt.domain.Jwt
import com.daml.ledger.api.refinements.{ApiTypes => lar}
@ -33,7 +32,7 @@ import scalaz.syntax.traverse._
import scalaz.{-\/, OneAnd, Show, Tag, \/, \/-}
import spray.json.JsValue
import scala.language.higherKinds
import scala.collection.compat._
import scala.concurrent.{ExecutionContext, Future}
class ContractsService(
@ -323,7 +322,7 @@ class ContractsService(
val (errors, converted) = step.toInsertDelete.partitionMapPreservingIds { apiEvent =>
domain.ActiveContract
.fromLedgerApi(apiEvent)
.leftMap(e => Error('searchInMemory, e.shows))
.leftMap(e => Error(Symbol("searchInMemory"), e.shows))
.flatMap(apiAcToLfAc): Error \/ Ac
}
val convertedInserts = converted.inserts filter { ac =>
@ -401,7 +400,7 @@ class ContractsService(
ac: domain.ActiveContract[ApiValue]
): Error \/ domain.ActiveContract[LfValue] =
ac.traverse(ApiValueToLfValueConverter.apiValueToLfValue)
.leftMap(e => Error('apiAcToLfAc, e.shows))
.leftMap(e => Error(Symbol("apiAcToLfAc"), e.shows))
private[http] def valuePredicate(
templateId: domain.TemplateId.RequiredPkg,
@ -411,7 +410,7 @@ class ContractsService(
private def lfValueToJsValue(a: LfValue): Error \/ JsValue =
\/.fromTryCatchNonFatal(LfValueCodec.apiValueToJsValue(a)).leftMap(e =>
Error('lfValueToJsValue, e.description)
Error(Symbol("lfValueToJsValue"), e.description)
)
private[http] def resolveTemplateIds[Tid <: domain.TemplateId.OptionalPkg](
@ -421,7 +420,7 @@ class ContractsService(
import scalaz.syntax.foldable._
xs.toSet.partitionMap { x =>
resolveTemplateId(x) toLeftDisjunction x
resolveTemplateId(x).toLeft(x)
}
}
}

View File

@ -153,7 +153,7 @@ object HttpService extends StrictLogging {
LedgerClientJwt.getActiveContracts(client),
LedgerClientJwt.getCreatesAndArchivesSince(client),
LedgerClientJwt.getTermination(client),
LedgerReader.damlLfTypeLookup(packageService.packageStore _),
LedgerReader.damlLfTypeLookup(() => packageService.packageStore),
contractDao,
)
@ -196,7 +196,7 @@ object HttpService extends StrictLogging {
contractsService,
packageService.resolveTemplateId,
decoder,
LedgerReader.damlLfTypeLookup(packageService.packageStore _),
LedgerReader.damlLfTypeLookup(() => packageService.packageStore),
wsConfig,
)
@ -277,7 +277,7 @@ object HttpService extends StrictLogging {
packageService: PackageService
): (DomainJsonEncoder, DomainJsonDecoder) = {
val lfTypeLookup = LedgerReader.damlLfTypeLookup(packageService.packageStore _) _
val lfTypeLookup = LedgerReader.damlLfTypeLookup(() => packageService.packageStore) _
val jsValueToApiValueConverter = new JsValueToApiValueConverter(lfTypeLookup)
val apiValueToJsValueConverter = new ApiValueToJsValueConverter(

View File

@ -200,7 +200,7 @@ object WebSocketService {
val (resolved, unresolved, q) = request.queries.zipWithIndex
.foldMap { case (gacr, ix) =>
val (resolved, unresolved) =
gacr.templateIds.toSet.partitionMap(x => resolveTemplateId(x) toLeftDisjunction x)
gacr.templateIds.toSet.partitionMap(x => resolveTemplateId(x).toLeft(x))
val q: CompiledQueries = prepareFilters(resolved, gacr.query, lookupType)
(resolved, unresolved, q transform ((_, p) => NonEmptyList((p, ix))))
}
@ -295,14 +295,11 @@ object WebSocketService {
resolveTemplateId: PackageService.ResolveTemplateId,
lookupType: TypeLookup,
): StreamPredicate[Positive] = {
import util.Collections._
val (resolvedWithKey, unresolved) =
request.toSet.partitionMap { x: CKR[LfV] =>
resolveTemplateId(x.ekey.templateId)
.map((_, x.ekey.key))
.toLeftDisjunction(x.ekey.templateId)
.toLeft(x.ekey.templateId)
}
// invariant: every set is non-empty
@ -398,7 +395,11 @@ class WebSocketService(
.throttle(config.throttleElem, config.throttlePer, config.maxBurst, config.mode)
@SuppressWarnings(
Array("org.wartremover.warts.NonUnitStatements", "org.wartremover.warts.JavaSerializable")
Array(
"org.wartremover.warts.NonUnitStatements",
"org.wartremover.warts.JavaSerializable",
"org.wartremover.warts.Serializable",
)
)
private def connCounter[A]: Flow[A, A, NotUsed] =
Flow[A]
@ -560,7 +561,7 @@ class WebSocketService(
StepAndErrors[Pos, JsValue](Seq.empty, LiveBegin(offset))
private def removePhantomArchives[A, B](remove: Option[Set[domain.ContractId]]) =
remove cata (removePhantomArchives_[A, B], Flow[StepAndErrors[A, B]])
remove.cata(removePhantomArchives_[A, B], Flow[StepAndErrors[A, B]])
private def removePhantomArchives_[A, B](
initialState: Set[domain.ContractId]
@ -573,7 +574,7 @@ class WebSocketService(
domain.ContractId.unsubst(idstep.inserts.map(_._1.contractId))
val (deletesToEmit, deletesToHold) = s0 partition idstep.deletes.keySet
val s1: Set[String] = deletesToHold ++ newInserts
val a1 = a0.copy(step = a0.step.mapDeletes(_ filterKeys deletesToEmit))
val a1 = a0.copy(step = a0.step.mapDeletes(_.view.filterKeys(deletesToEmit).toMap))
(s1, if (a1.nonEmpty) Some(a1) else None)
@ -609,7 +610,7 @@ class WebSocketService(
.fromLedgerApi(ce)
.liftErr(ServerError)
.flatMap(_.traverse(apiValueToLfValue).liftErr(ServerError)),
)
)(implicitly[Factory[ServerError, Seq[ServerError]]])
StepAndErrors(
errors ++ aerrors,
dstep mapInserts { inserts: Vector[domain.ActiveContract[LfV]] =>

View File

@ -37,7 +37,6 @@ import scalaz.{
import spray.json.JsValue
import scala.annotation.tailrec
import scala.language.higherKinds
object domain {
@ -268,7 +267,7 @@ object domain {
ArchivedContract.fromLedgerApi(archived).map(a => Contract(-\/(a)))
case lav1.event.Event.Event.Empty =>
val errorMsg = s"Expected either Created or Archived event, got: Empty"
-\/(Error('Contract_fromLedgerApi, errorMsg))
-\/(Error(Symbol("Contract_fromLedgerApi"), errorMsg))
}
def fromTreeEvent(
@ -295,7 +294,7 @@ object domain {
loop(exercised.childEventIds.toVector ++ tail, newAcc)
case lav1.transaction.TreeEvent.Kind.Empty =>
val errorMsg = s"Expected either Created or Exercised event, got: Empty"
-\/(Error('Contract_fromTreeEvent, errorMsg))
-\/(Error(Symbol("Contract_fromTreeEvent"), errorMsg))
}
}
@ -374,7 +373,7 @@ object domain {
h: PackageService.ResolveKeyType,
): Error \/ LfType =
f(templateId)
.leftMap(e => Error('ActiveContract_hasTemplateId_lfType, e.shows))
.leftMap(e => Error(Symbol("ActiveContract_hasTemplateId_lfType"), e.shows))
}
}
@ -457,7 +456,7 @@ object domain {
h: PackageService.ResolveKeyType,
): Error \/ LfType =
h(templateId)
.leftMap(e => Error('EnrichedContractKey_hasTemplateId_lfType, e.shows))
.leftMap(e => Error(Symbol("EnrichedContractKey_hasTemplateId_lfType"), e.shows))
}
}
@ -476,7 +475,7 @@ object domain {
private[this] implicit final class ErrorOps[A](private val o: Option[A]) extends AnyVal {
def required(label: String): Error \/ A =
o toRightDisjunction Error('ErrorOps_required, s"Missing required field $label")
o toRightDisjunction Error(Symbol("ErrorOps_required"), s"Missing required field $label")
}
type LfType = iface.Type
@ -507,7 +506,7 @@ object domain {
f: PackageService.ResolveTemplateRecordType,
g: PackageService.ResolveChoiceArgType,
h: PackageService.ResolveKeyType,
) = basis lfType (nt(fa), templateId, f, g, h)
) = basis.lfType(nt(fa), templateId, f, g, h)
}
}
}
@ -558,7 +557,7 @@ object domain {
h: PackageService.ResolveKeyType,
): Error \/ LfType =
g(templateId, fa.choice)
.leftMap(e => Error('ExerciseCommand_hasTemplateId_lfType, e.shows))
.leftMap(e => Error(Symbol("ExerciseCommand_hasTemplateId_lfType"), e.shows))
}
}

View File

@ -15,8 +15,6 @@ import scalaz.syntax.traverse._
import scalaz.{Traverse, \/, \/-}
import spray.json.{JsValue, JsonReader}
import scala.language.higherKinds
class DomainJsonDecoder(
resolveTemplateId: PackageService.ResolveTemplateId,
resolveTemplateRecordType: PackageService.ResolveTemplateRecordType,

View File

@ -36,7 +36,7 @@ object JsonProtocol extends DefaultJsonProtocol with ExtraFormats {
JsString(obj.coid)
override def read(json: JsValue) = json match {
case JsString(s) =>
ContractId fromString s fold (deserializationError(_), identity)
ContractId.fromString(s).fold(deserializationError(_), identity)
case _ => deserializationError("ContractId must be a string")
}
}

View File

@ -9,8 +9,6 @@ import scalaz.syntax.traverse._
import scalaz.{-\/, Bitraverse, Show, Traverse, \/, \/-}
import spray.json.{JsValue, JsonReader, _}
import scala.language.higherKinds
object SprayJson {
sealed abstract class Error extends Product with Serializable
final case class JsonReaderError(value: String, message: String) extends Error

View File

@ -56,9 +56,13 @@ sealed abstract class ValuePredicate extends Product with Serializable {
}
case OptionalMatch(oq) =>
oq map go cata (csq => { case V.ValueOptional(Some(v)) => csq(v); case _ => false }, {
case V.ValueOptional(None) => true; case _ => false
})
oq.map(go)
.cata(
csq => { case V.ValueOptional(Some(v)) => csq(v); case _ => false },
{
case V.ValueOptional(None) => true; case _ => false
},
)
case range: Range[a] =>
implicit val ord: Order[a] = range.ord
@ -348,13 +352,13 @@ object ValuePredicate {
)(V.ValueText)
private[this] val DateRangeExpr = RangeExpr(
{ case JsString(q) =>
Time.Date fromString q fold (predicateParseError(_), identity)
Time.Date.fromString(q).fold(predicateParseError(_), identity)
},
{ case V.ValueDate(v) => v },
)(V.ValueDate)
private[this] val TimestampRangeExpr = RangeExpr(
{ case JsString(q) =>
Time.Timestamp fromString q fold (predicateParseError(_), identity)
Time.Timestamp.fromString(q).fold(predicateParseError(_), identity)
},
{ case V.ValueTimestamp(v) => v },
)(V.ValueTimestamp)
@ -362,14 +366,19 @@ object ValuePredicate {
RangeExpr(
{
case JsString(q) =>
Numeric checkWithinBoundsAndRound (scale, BigDecimal(
q
)) fold (predicateParseError, identity)
Numeric
.checkWithinBoundsAndRound(
scale,
BigDecimal(
q
),
)
.fold(predicateParseError, identity)
case JsNumber(q) =>
Numeric checkWithinBoundsAndRound (scale, q) fold (predicateParseError, identity)
Numeric.checkWithinBoundsAndRound(scale, q).fold(predicateParseError, identity)
},
{ case V.ValueNumeric(v) => v setScale scale },
)(qv => V.ValueNumeric(Numeric assertFromBigDecimal (scale, qv)))
)(qv => V.ValueNumeric(Numeric.assertFromBigDecimal(scale, qv)))
private[this] implicit val `jBD order`: Order[java.math.BigDecimal] =
Order.fromScalaOrdering

View File

@ -3,29 +3,10 @@
package com.daml.http.util
import scalaz.{NonEmptyList, OneAnd, \/}
import scala.collection.TraversableLike
import scalaz.{NonEmptyList, OneAnd}
object Collections {
implicit final class `cdhuc TraversableOps`[A, Self](private val self: TraversableLike[A, Self])
extends AnyVal {
import collection.generic.CanBuildFrom
def partitionMap[E, B, Es, That](
f: A => E \/ B
)(implicit es: CanBuildFrom[Self, E, Es], that: CanBuildFrom[Self, B, That]): (Es, That) = {
val esb = es(self.repr)
val thatb = that(self.repr)
self foreach { a =>
f(a) fold (esb.+=, thatb.+=)
}
(esb.result, thatb.result)
}
}
implicit final class `cdhuc Nel Ops`[A](private val self: NonEmptyList[A]) extends AnyVal {
def collect[B](f: A PartialFunction B): Option[NonEmptyList[B]] =
self.list.collect(f).toNel

View File

@ -4,14 +4,13 @@
package com.daml.http
package util
import Collections._
import InsertDeleteStep.{Cid, Inserts}
import scalaz.{Semigroup, \/}
import scalaz.std.tuple._
import scalaz.syntax.functor._
import scala.collection.generic.CanBuildFrom
import scala.collection.compat._
private[http] sealed abstract class ContractStreamStep[+D, +C] extends Product with Serializable {
import ContractStreamStep._
@ -46,14 +45,14 @@ private[http] sealed abstract class ContractStreamStep[+D, +C] extends Product w
mapInserts(_ map f)
def partitionBimap[LD, DD, LC, CC, LDS](f: D => (LD \/ DD), g: C => (LC \/ CC))(implicit
LDS: CanBuildFrom[Map[String, D], LD, LDS]
LDS: Factory[LD, LDS]
): (LDS, Inserts[LC], ContractStreamStep[DD, CC]) =
this match {
case Acs(inserts) =>
val (lcs, ins) = inserts partitionMap g
(LDS().result(), lcs, Acs(ins))
case lb @ LiveBegin(_) => (LDS().result(), Inserts.empty, lb)
case Txn(step, off) => step partitionBimap (f, g) map (Txn(_, off))
val (lcs, ins) = inserts partitionMap (x => g(x).toEither)
(LDS.newBuilder.result(), lcs, Acs(ins))
case lb @ LiveBegin(_) => (LDS.newBuilder.result(), Inserts.empty, lb)
case Txn(step, off) => step.partitionBimap(f, g)(LDS).map(Txn(_, off))
}
def mapInserts[CC](f: Inserts[C] => Inserts[CC]): ContractStreamStep[D, CC] = this match {

View File

@ -7,7 +7,6 @@ import scalaz.syntax.show._
import scalaz.{-\/, Applicative, EitherT, Functor, Show, \/, \/-}
import scala.concurrent.{ExecutionContext, Future}
import scala.language.higherKinds
import scala.util.Try
object FutureUtil {

View File

@ -10,9 +10,8 @@ import com.daml.ledger.api.v1.{event => evv1}
import scalaz.{Monoid, \/, \/-}
import scalaz.syntax.tag._
import scala.collection.generic.CanBuildFrom
import scala.collection.compat._
import scala.runtime.AbstractFunction1
import scala.language.higherKinds
private[http] final case class InsertDeleteStep[+D, +C](
inserts: InsertDeleteStep.Inserts[C],
@ -38,19 +37,18 @@ private[http] final case class InsertDeleteStep[+D, +C](
def partitionMapPreservingIds[LC, CC](
f: C => (LC \/ CC)
): (Inserts[LC], InsertDeleteStep[D, CC]) = {
val (_, lcs, step) = partitionBimap(\/-(_), f)
val (_, lcs, step) = partitionBimap(\/-(_), f)(implicitly[Factory[Unit, List[Unit]]])
(lcs, step)
}
/** Results undefined if cid(cc) != cid(c) */
def partitionBimap[LD, DD, LC, CC, LDS](f: D => (LD \/ DD), g: C => (LC \/ CC))(implicit
LDS: CanBuildFrom[Map[String, D], LD, LDS]
LDS: Factory[LD, LDS]
): (LDS, Inserts[LC], InsertDeleteStep[DD, CC]) = {
import Collections._
import scalaz.std.tuple._, scalaz.syntax.traverse._
val (lcs, ins) = inserts partitionMap g
val (lds, del) = deletes partitionMap (_ traverse f)
(lds, lcs, copy(inserts = ins, deletes = del))
import scalaz.std.tuple._, scalaz.std.either._, scalaz.syntax.traverse._
val (lcs, ins) = inserts partitionMap (x => g(x).toEither)
val (lds, del) = deletes.toList.partitionMap(_.traverse(x => f(x).toEither))
(LDS.fromSpecific(lds), lcs, copy(inserts = ins, deletes = del.toMap))
}
}
@ -72,7 +70,7 @@ private[http] object InsertDeleteStep extends WithLAV1[InsertDeleteStep] {
// we always use the Last semigroup for D
implicit def `IDS monoid`[D, C: Cid]: Monoid[InsertDeleteStep[D, C]] =
Monoid instance (_ append _, Empty)
Monoid.instance(_ append _, Empty)
def appendForgettingDeletes[D, C](leftInserts: Inserts[C], right: InsertDeleteStep[Any, C])(
implicit cid: Cid[C]

View File

@ -3,8 +3,6 @@
package com.daml.http.util
import language.higherKinds
/** {{{
* object IsTyped extends NewBoolean.Named {
* val SinglyTyped = False

View File

@ -8,7 +8,7 @@ import akka.stream.Materializer
import akka.stream.scaladsl.{Source, StreamConverters}
import com.google.protobuf
import scala.collection.JavaConverters._
import scala.jdk.CollectionConverters._
object ProtobufByteStrings {

View File

@ -3,8 +3,6 @@
package com.daml.http.json
import com.daml.http.util.Collections._
import akka.actor.ActorSystem
import akka.stream.Materializer
import akka.stream.scaladsl.Source
@ -19,6 +17,7 @@ import scalaz.syntax.show._
import scalaz.{Show, \/}
import spray.json._
import scala.collection.compat._
import scala.concurrent.duration._
import scala.concurrent.{Await, ExecutionContext, Future}
@ -43,7 +42,7 @@ class ResponseFormatsTest
val jsValWarnings: Option[JsValue] = warnings.map(_.toJson)
val (failures, successes): (Vector[JsString], Vector[JsValue]) =
input.toVector.partitionMap(_.leftMap(e => JsString(e.shows)))
input.toVector.partitionMap(_.leftMap(e => JsString(e.shows)).toEither)
val jsValSource = Source[DummyError \/ JsValue](input)