diff --git a/README.md b/README.md index 23961f6..78db969 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ val allPersonRules: NonEmptyList[Rule[Id, Person]] = NonEmptyList.of( .targetInfo("age") .contramap(_.age) ) -// allPersonRules: NonEmptyList[Rule[Id, Person]] = NonEmptyList(RuleImpl(scala.Function1$$Lambda$8362/0x0000000802349290@6b3982a9,Check UK citizenship,None,Some(citizenship)), RuleImpl(scala.Function1$$Lambda$8362/0x0000000802349290@1f4bc8ea,Check Age >= 18,None,Some(age))) +// allPersonRules: NonEmptyList[Rule[Id, Person]] = NonEmptyList(RuleImpl(scala.Function1$$Lambda$10486/0x00000008029eb390@3b64b963,Check UK citizenship,None,Some(citizenship)), RuleImpl(scala.Function1$$Lambda$10486/0x00000008029eb390@65d4d410,Check Age >= 18,None,Some(age))) ``` N.B. Importing even the `erules-generic` you can use macro to auto-generate the target info using `contramapTarget` method. @@ -119,7 +119,7 @@ result.unsafeRunSync().asReport[String] // - Rule: Check UK citizenship // - Description: // - Target: citizenship -// - Execution time: 220042 nanoseconds +// - Execution time: 123167 nanoseconds // // - Verdict: Right(Deny) // - Because: Only UK citizenship is allowed! @@ -128,7 +128,7 @@ result.unsafeRunSync().asReport[String] // - Rule: Check Age >= 18 // - Description: // - Target: age -// - Execution time: 19292 nanoseconds +// - Execution time: 16709 nanoseconds // // - Verdict: Right(Deny) // - Because: Only >= 18 age are allowed! diff --git a/core/src/main/scala/erules/core/EvalReason.scala b/core/src/main/scala/erules/core/EvalReason.scala index 9e30a7d..782224d 100644 --- a/core/src/main/scala/erules/core/EvalReason.scala +++ b/core/src/main/scala/erules/core/EvalReason.scala @@ -7,7 +7,7 @@ import cats.Show * @param message * reason message */ -case class EvalReason(message: String) +case class EvalReason(message: String) extends AnyVal object EvalReason extends EvalReasonInstances with EvalReasonSyntax { def stringifyList(reasons: List[EvalReason]): String = diff --git a/core/src/main/scala/erules/core/RuleResultsInterpreterVerdict.scala b/core/src/main/scala/erules/core/RuleResultsInterpreterVerdict.scala index 3d3f741..7730902 100644 --- a/core/src/main/scala/erules/core/RuleResultsInterpreterVerdict.scala +++ b/core/src/main/scala/erules/core/RuleResultsInterpreterVerdict.scala @@ -5,7 +5,7 @@ import erules.core.RuleResultsInterpreterVerdict.{Allowed, Denied} /** ADT to define the possible responses of the engine evaluation. */ -sealed trait RuleResultsInterpreterVerdict[T] extends Serializable { +sealed trait RuleResultsInterpreterVerdict[-T] extends Serializable { /** Result reasons */ diff --git a/modules/circe/README.md b/modules/circe/README.md index fa7603a..d448d3d 100644 --- a/modules/circe/README.md +++ b/modules/circe/README.md @@ -53,7 +53,7 @@ val allPersonRules: NonEmptyList[Rule[Id, Person]] = NonEmptyList.of( .targetInfo("age") .contramap(_.age) ) -// allPersonRules: NonEmptyList[Rule[Id, Person]] = NonEmptyList(RuleImpl(scala.Function1$$Lambda$8362/0x0000000802349290@705bbf9a,Check UK citizenship,None,Some(citizenship)), RuleImpl(scala.Function1$$Lambda$8362/0x0000000802349290@1d14745f,Check Age >= 18,None,Some(age))) +// allPersonRules: NonEmptyList[Rule[Id, Person]] = NonEmptyList(RuleImpl(scala.Function1$$Lambda$10486/0x00000008029eb390@1ea18d05,Check UK citizenship,None,Some(citizenship)), RuleImpl(scala.Function1$$Lambda$10486/0x00000008029eb390@531ca4f4,Check Age >= 18,None,Some(age))) ``` Import @@ -111,13 +111,11 @@ result.unsafeRunSync().asJsonReport // "verdict" : { // "type" : "Deny", // "reasons" : [ -// { -// "message" : "Only UK citizenship is allowed!" -// } +// "Only UK citizenship is allowed!" // ] // }, // "executionTime" : { -// "length" : 91167, +// "length" : 125334, // "unit" : "NANOSECONDS" // } // }, @@ -130,13 +128,11 @@ result.unsafeRunSync().asJsonReport // "verdict" : { // "type" : "Deny", // "reasons" : [ -// { -// "message" : "Only >= 18 age are allowed!" -// } +// "Only >= 18 age are allowed!" // ] // }, // "executionTime" : { -// "length" : 10750, +// "length" : 56500, // "unit" : "NANOSECONDS" // } // } diff --git a/modules/circe/src/main/scala/erules/circe/instances.scala b/modules/circe/src/main/scala/erules/circe/instances.scala index 699097e..3f703e1 100644 --- a/modules/circe/src/main/scala/erules/circe/instances.scala +++ b/modules/circe/src/main/scala/erules/circe/instances.scala @@ -2,6 +2,7 @@ package erules.circe import erules.circe.report.{JsonReportInstances, JsonReportSyntax} import erules.core.* +import io.circe.generic.semiauto.deriveEncoder object implicits extends CirceAllInstances with CirceAllSyntax @@ -15,6 +16,9 @@ private[circe] trait BasicTypesCirceInstances { import io.circe.* import io.circe.syntax.* + implicit final val evalReasonCirceEncoder: Encoder[EvalReason] = + Encoder.encodeString.contramap(_.message) + implicit def engineResultCirceEncoder[T: Encoder]: Encoder[EngineResult[T]] = io.circe.generic.semiauto.deriveEncoder[EngineResult[T]] @@ -27,7 +31,7 @@ private[circe] trait BasicTypesCirceInstances { } implicit def ruleResultCirceEncoder[T]: Encoder[RuleResult[T, RuleVerdict]] = - io.circe.generic.semiauto.deriveEncoder[RuleResult[T, RuleVerdict]] + deriveEncoder[RuleResult[T, RuleVerdict]] implicit def ruleCirceEncoder[T]: Encoder[AnyTypedRule[T]] = Encoder.instance { v => @@ -46,9 +50,6 @@ private[circe] trait BasicTypesCirceInstances { "reasons" -> Json.fromValues(v.reasons.map(_.asJson)) ) } - - implicit final val evalReasonCirceEncoder: Encoder[EvalReason] = - io.circe.generic.semiauto.deriveEncoder[EvalReason] } //---------- SYNTAX ---------- diff --git a/modules/circe/src/test/scala/erules/circe/report/JsonReportEncoderSpec.scala b/modules/circe/src/test/scala/erules/circe/report/JsonReportEncoderSpec.scala index f86c8c2..39c072b 100644 --- a/modules/circe/src/test/scala/erules/circe/report/JsonReportEncoderSpec.scala +++ b/modules/circe/src/test/scala/erules/circe/report/JsonReportEncoderSpec.scala @@ -16,7 +16,7 @@ class JsonReportEncoderSpec extends munit.CatsEffectSuite { case class Foo(x: String, y: Int) val allowYEqZero: Rule[Id, Foo] = Rule("Check Y value").partially[Id, Foo] { case Foo(_, 0) => - Allow.withoutReasons + Allow.because("reason") } val engine: IO[RulesEngineIO[Foo]] = @@ -33,27 +33,28 @@ class JsonReportEncoderSpec extends munit.CatsEffectSuite { obtained = result, returns = json""" { - "data" : { - "x" : "TEST", - "y" : 0 - }, - "verdict" : { - "type" : "Allowed", - "evaluatedRules" : [ - { - "rule" : { - "name" : "Check Y value", - "fullDescription" : "Check Y value" - }, - "verdict" : { - "type" : "Allow", - "reasons" : [ - ] - } - } - ] + "data" : { + "x" : "TEST", + "y" : 0 + }, + "verdict" : { + "type" : "Allowed", + "evaluatedRules" : [ + { + "rule" : { + "name" : "Check Y value", + "fullDescription" : "Check Y value" + }, + "verdict" : { + "type" : "Allow", + "reasons" : [ + "reason" + ] + } } - }""" + ] + } + }""" ) }