From 9b98cb7c3247f8a736f5c4715b89ed4d489d0372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Youn=20M=C3=A9lois?= Date: Thu, 24 Oct 2024 18:25:53 +0200 Subject: [PATCH] Remove iron integration trait scope restriction (#4111) --- .../sttp/iron/codec/iron/TapirCodecIron.scala | 8 +++--- .../scala-3/com/example/RefinedString.scala | 25 +++++++++++++++++++ .../codec/iron/TapirCodecIronTestScala3.scala | 10 ++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 integrations/iron/src/test/scala-3/com/example/RefinedString.scala diff --git a/integrations/iron/src/main/scala/sttp/iron/codec/iron/TapirCodecIron.scala b/integrations/iron/src/main/scala/sttp/iron/codec/iron/TapirCodecIron.scala index b040b38d87..e1b1fec702 100644 --- a/integrations/iron/src/main/scala/sttp/iron/codec/iron/TapirCodecIron.scala +++ b/integrations/iron/src/main/scala/sttp/iron/codec/iron/TapirCodecIron.scala @@ -209,7 +209,7 @@ trait TapirCodecIron extends DescriptionWitness with LowPriorityValidatorForPred } -private[iron] trait ValidatorForPredicate[Value, Predicate] { +trait ValidatorForPredicate[Value, Predicate] { def validator: Validator[Value] def makeErrors(value: Value, errorMessage: String): List[ValidationError[_]] lazy val containsMinSizePositive: Boolean = validator.asPrimitiveValidators.exists { @@ -218,12 +218,12 @@ private[iron] trait ValidatorForPredicate[Value, Predicate] { } } -private[iron] trait PrimitiveValidatorForPredicate[Value, Predicate] extends ValidatorForPredicate[Value, Predicate] { +trait PrimitiveValidatorForPredicate[Value, Predicate] extends ValidatorForPredicate[Value, Predicate] { def validator: Validator.Primitive[Value] def makeErrors(value: Value, errorMessage: String): List[ValidationError[_]] } -private[iron] object ValidatorForPredicate { +object ValidatorForPredicate { def fromPrimitiveValidator[Value, Predicate]( primitiveValidator: Validator.Primitive[Value] ): PrimitiveValidatorForPredicate[Value, Predicate] = @@ -235,7 +235,7 @@ private[iron] object ValidatorForPredicate { } // #3938: the two-level low-priority validators are needed because of implicit resolution changes in Scala 3.6 -private[iron] trait LowPriorityValidatorForPredicate extends LowPriorityValidatorForPredicate2 { +trait LowPriorityValidatorForPredicate extends LowPriorityValidatorForPredicate2 { inline given validatorForDescribedAnd[N, P](using id: IsDescription[P], diff --git a/integrations/iron/src/test/scala-3/com/example/RefinedString.scala b/integrations/iron/src/test/scala-3/com/example/RefinedString.scala new file mode 100644 index 0000000000..b820e9f486 --- /dev/null +++ b/integrations/iron/src/test/scala-3/com/example/RefinedString.scala @@ -0,0 +1,25 @@ +package com.example + +import io.github.iltotore.iron.* +import sttp.tapir.Validator +import sttp.tapir.codec.iron.PrimitiveValidatorForPredicate +import sttp.tapir.codec.iron.ValidatorForPredicate + +final class RefinedStringConstraint + +object RefinedStringConstraint { + + given Constraint[String, RefinedStringConstraint] with { + + override inline def test(value: String): Boolean = value.nonEmpty + + override inline def message: String = "Should not be empty" + } + + given PrimitiveValidatorForPredicate[String, RefinedStringConstraint] = + ValidatorForPredicate.fromPrimitiveValidator(Validator.pattern[String]("^.+")) +} + +opaque type RefinedString = String :| RefinedStringConstraint + +object RefinedString extends RefinedTypeOps[String, RefinedStringConstraint, RefinedString] diff --git a/integrations/iron/src/test/scala-3/sttp/iron/codec/iron/TapirCodecIronTestScala3.scala b/integrations/iron/src/test/scala-3/sttp/iron/codec/iron/TapirCodecIronTestScala3.scala index 4a9d7b1159..6af7435fea 100644 --- a/integrations/iron/src/test/scala-3/sttp/iron/codec/iron/TapirCodecIronTestScala3.scala +++ b/integrations/iron/src/test/scala-3/sttp/iron/codec/iron/TapirCodecIronTestScala3.scala @@ -18,6 +18,9 @@ import io.github.iltotore.iron.constraint.all.* import sttp.tapir.Validator import sttp.tapir.ValidationError +import com.example.RefinedString +import com.example.RefinedStringConstraint + class TapirCodecIronTestScala3 extends AnyFlatSpec with Matchers { val schema: Schema[Double :| Positive] = summon[Schema[Double :| Positive]] @@ -321,4 +324,11 @@ class TapirCodecIronTestScala3 extends AnyFlatSpec with Matchers { summon[Schema[NewtypeInt]] summon[Codec[String, NewtypeInt, TextPlain]] + "Instances for opaque refined type defined outside of source" should "be correctly derived" in: + summon[Schema[RefinedString]] + summon[Codec[String, RefinedString, TextPlain]] + + "Instance of validator for constraint defined outside of source" should "be correctly derived" in: + summon[PrimitiveValidatorForPredicate[String, RefinedStringConstraint]] + }