From 8e625ec3620323c8749bd6544ced72981ccab789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20W=C3=B3jcik?= Date: Mon, 8 Jan 2024 09:15:55 +0100 Subject: [PATCH 1/3] Add deprecation to .refine, introduce .refineUnsafe instead --- README.md | 2 +- docs/_docs/modules/cats.md | 2 +- docs/_docs/overview.md | 2 +- docs/_docs/reference/refinement.md | 2 +- .../src/io/github/iltotore/iron/conversion.scala | 14 +++++++++++++- main/src/io/github/iltotore/iron/package.scala | 16 ++++++++++++++-- 6 files changed, 31 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 73e06f86..07802b35 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ log(1.0) //Automatically verified at compile time. log(-1.0) //Compile-time error: Should be strictly positive val runtimeValue: Double = ??? -log(runtimeValue.refine) //Explicitly refine your external values at runtime. +log(runtimeValue.refineUnsafe) //Explicitly refine your external values at runtime. runtimeValue.refineEither.map(log) //Use monadic style for functional validation runtimeValue.refineEither[Positive].map(log) //More explicitly diff --git a/docs/_docs/modules/cats.md b/docs/_docs/modules/cats.md index 87160067..126bff1c 100644 --- a/docs/_docs/modules/cats.md +++ b/docs/_docs/modules/cats.md @@ -100,7 +100,7 @@ import io.github.iltotore.iron.constraint.all.* //} import io.github.iltotore.iron.cats.given -val name1: String :| Alphanumeric = "Martin".refine +val name1: String :| Alphanumeric = "Martin".refineUnsafe val name2: String :| Alphanumeric = "George" val age1: Int :| Greater[0] = 60 diff --git a/docs/_docs/overview.md b/docs/_docs/overview.md index 2c7f1bb8..3fdc23b0 100644 --- a/docs/_docs/overview.md +++ b/docs/_docs/overview.md @@ -51,7 +51,7 @@ case class User(age: Int :| Positive) ```scala sc-compile-with:BetterUser.scala User(1) //Compiles User(-1) //Does not compile -User(-1.refine) //Compiles but fails at runtime. Useful for runtime checks such as form validation. +User(-1.refineUnsafe) //Compiles but fails at runtime. Useful for runtime checks such as form validation. //See also `refineOption` and `refineEither` ``` diff --git a/docs/_docs/reference/refinement.md b/docs/_docs/reference/refinement.md index 9d2e1802..5176236b 100644 --- a/docs/_docs/reference/refinement.md +++ b/docs/_docs/reference/refinement.md @@ -96,7 +96,7 @@ You can imperatively refine a value at runtime (much like an assertion) using th ```scala val runtimeString: String = ??? -val username: String :| Alphanumeric = runtimeString.refine //or more explicitly, refine[LowerCase]. +val username: String :| Alphanumeric = runtimeString.refineUnsafe //or more explicitly, refineUnsafe[LowerCase]. ``` The `refine` extension method tests the constraint at runtime, throwing an `IllegalArgumentException` if the value diff --git a/main/src/io/github/iltotore/iron/conversion.scala b/main/src/io/github/iltotore/iron/conversion.scala index 1343ab1e..300009a2 100644 --- a/main/src/io/github/iltotore/iron/conversion.scala +++ b/main/src/io/github/iltotore/iron/conversion.scala @@ -77,8 +77,20 @@ extension [A, C1](value: A :| C1) * @throws an [[IllegalArgumentException]] if the constraint is not satisfied. * @see [[refine]]. */ + @deprecated("Use refineFurtherUnsafe instead. refineFurther will be removed in 3.0") inline def refineFurther[C2](using inline constraint: Constraint[A, C2]): A :| (C1 & C2) = - (value: A).refine[C2].assumeFurther[C1] + refineFurtherUnsafe[C2] + + /** + * Refine the given value again at runtime. + * + * @param constraint the new constraint to test. + * @return this value refined with `C1 & C2`. + * @throws an [[IllegalArgumentException]] if the constraint is not satisfied. + * @see [[refine]]. + */ + inline def refineFurtherUnsafe[C2](using inline constraint: Constraint[A, C2]): A :| (C1 & C2) = + (value: A).refineUnsafe[C2].assumeFurther[C1] /** * Refine the given value again at runtime, resulting in an [[Either]]. diff --git a/main/src/io/github/iltotore/iron/package.scala b/main/src/io/github/iltotore/iron/package.scala index 8b1a7a97..63b21b5e 100644 --- a/main/src/io/github/iltotore/iron/package.scala +++ b/main/src/io/github/iltotore/iron/package.scala @@ -38,8 +38,8 @@ object IronType: * @tparam A the refined type. * @tparam C the constraint applied to the type. * @return the given value typed as [[IronType]]. - * @note this does not check if the constraint is satisfied. Use [[package.refine]] to refine a value at runtime. - * @see [[package.autoRefine]], [[package.refine]], [[package.refineEither]], [[package.refineOption]] + * @note this does not check if the constraint is satisfied. Use [[package.refineUnsafe]] to refine a value at runtime. + * @see [[package.autoRefine]], [[package.refineUnsafe]], [[package.refineEither]], [[package.refineOption]] */ inline def apply[A, C](value: A): IronType[A, C] = value @@ -64,7 +64,19 @@ extension [A](value: A) * @throws an [[IllegalArgumentException]] if the constraint is not satisfied. * @see [[autoRefine]], [[refineEither]], [[refineOption]]. */ + @deprecated("Use refineUnsafe instead. refine will be removed in 3.0.0") inline def refine[B](using inline constraint: Constraint[A, B]): A :| B = + refineUnsafe[B] + + /** + * Refine the given value at runtime. + * + * @param constraint the constraint to test with the value to refine. + * @return this value as [[IronType]]. + * @throws an [[IllegalArgumentException]] if the constraint is not satisfied. + * @see [[autoRefine]], [[refineEither]], [[refineOption]]. + */ + inline def refineUnsafe[B](using inline constraint: Constraint[A, B]): A :| B = if constraint.test(value) then value else throw IllegalArgumentException(constraint.message) From 9d8ca23915a26d05cb37667c05ffe6d437590614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20W=C3=B3jcik?= Date: Mon, 8 Jan 2024 09:17:41 +0100 Subject: [PATCH 2/3] Replace missing renames --- main/src/io/github/iltotore/iron/conversion.scala | 2 +- main/src/io/github/iltotore/iron/package.scala | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/main/src/io/github/iltotore/iron/conversion.scala b/main/src/io/github/iltotore/iron/conversion.scala index 300009a2..2e0f19b3 100644 --- a/main/src/io/github/iltotore/iron/conversion.scala +++ b/main/src/io/github/iltotore/iron/conversion.scala @@ -75,7 +75,7 @@ extension [A, C1](value: A :| C1) * @param constraint the new constraint to test. * @return this value refined with `C1 & C2`. * @throws an [[IllegalArgumentException]] if the constraint is not satisfied. - * @see [[refine]]. + * @see [[refineUnsafe]]. */ @deprecated("Use refineFurtherUnsafe instead. refineFurther will be removed in 3.0") inline def refineFurther[C2](using inline constraint: Constraint[A, C2]): A :| (C1 & C2) = diff --git a/main/src/io/github/iltotore/iron/package.scala b/main/src/io/github/iltotore/iron/package.scala index 63b21b5e..3dc0730c 100644 --- a/main/src/io/github/iltotore/iron/package.scala +++ b/main/src/io/github/iltotore/iron/package.scala @@ -52,7 +52,7 @@ extension [A](value: A) * * @param constraint the constraint to test with the value to refine. * @return a constrained value, without performing constraint checks. - * @see [[autoRefine]], [[refine]]. + * @see [[autoRefine]], [[refineUnsafe]]. */ inline def assume[B]: A :| B = value @@ -85,7 +85,7 @@ extension [A](value: A) * * @param constraint the constraint to test with the value to refine. * @return a [[Right]] containing this value as [[IronType]] or a [[Left]] containing the constraint message. - * @see [[autoRefine]], [[refine]], [[refineOption]]. + * @see [[autoRefine]], [[refineUnsafe]], [[refineOption]]. */ inline def refineEither[B](using inline constraint: Constraint[A, B]): Either[String, A :| B] = Either.cond(constraint.test(value), value, constraint.message) @@ -95,7 +95,7 @@ extension [A](value: A) * * @param constraint the constraint to test with the value to refine. * @return an Option containing this value as [[IronType]] or [[None]]. - * @see [[autoRefine]], [[refine]], [[refineEither]]. + * @see [[autoRefine]], [[refineUnsafe]], [[refineEither]]. */ inline def refineOption[B](using inline constraint: Constraint[A, B]): Option[A :| B] = Option.when(constraint.test(value))(value) \ No newline at end of file From 600feb2af815603c4c5b494373e1b376854b6801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20W=C3=B3jcik?= Date: Mon, 8 Jan 2024 09:23:47 +0100 Subject: [PATCH 3/3] Leftover --- main/src/io/github/iltotore/iron/conversion.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/io/github/iltotore/iron/conversion.scala b/main/src/io/github/iltotore/iron/conversion.scala index 2e0f19b3..4d9b3d09 100644 --- a/main/src/io/github/iltotore/iron/conversion.scala +++ b/main/src/io/github/iltotore/iron/conversion.scala @@ -87,7 +87,7 @@ extension [A, C1](value: A :| C1) * @param constraint the new constraint to test. * @return this value refined with `C1 & C2`. * @throws an [[IllegalArgumentException]] if the constraint is not satisfied. - * @see [[refine]]. + * @see [[refineUnsafe]]. */ inline def refineFurtherUnsafe[C2](using inline constraint: Constraint[A, C2]): A :| (C1 & C2) = (value: A).refineUnsafe[C2].assumeFurther[C1]