Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Close #32 - Add InlinedRefined #33

Merged
merged 1 commit into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .scalafix-scala3.conf
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ rules = [
OptionMatchToRight

SimplifyForYield
ThrowableToNonFatal
// ThrowableToNonFatal
UnnecessaryCase
UnnecessaryMatch
UnnecessarySort
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package refined4s

import scala.compiletime.*

/** @author Kevin Lee
* @since 2023-08-12
*/
trait InlinedRefined[A] extends RefinedBase[A] {

inline def inlinedInvalidReason(inline a: A): String

inline def inlinedPredicate(inline a: A): Boolean

inline def apply(inline a: A): Type =
inline if inlinedPredicate(a) then a.asInstanceOf[Type] // scalafix:ok DisableSyntax.asInstanceOf
else error("Invalid value: [" + codeOf(a) + "]. " + inlinedInvalidReason(a))

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package refined4s

import hedgehog._
import hedgehog.runner._

/** @author Kevin Lee
* @since 2023-08-14
*/
object InlinedRefinedSpec extends Properties {
override def tests: List[Test] = List(
example("test InlinedRefined with valid value", testInlinedRefined)
)

def testInlinedRefined: Result = {
import InlinedRefinedType.*

Something(1)
Result.success
}

// def testInlinedRefined2: Result = {
// import InlinedRefinedType.*
//
// val a = 1
// // This should not compile.
// Something(a)
// Result.failure
// }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package refined4s

object InlinedRefinedType {
type Something = Something.Type
object Something extends InlinedRefined[Int] {
import scala.compiletime.*
import scala.quoted.*
override inline def inlinedInvalidReason(inline a: Int): String =
"The number is a negative Int. [a: " + codeOf(a) + "]"

private def inlinedPredicate0(a: Expr[Int])(using Quotes): Expr[Boolean] = {
import quotes.reflect.*
a.asTerm match {
case Inlined(_, _, Literal(IntConstant(num))) =>
try {
validate(num)
Expr(true)
} catch {
case _: Throwable => Expr(false)
}
case _ =>
report.error(
"Something must be a Int literal.",
a,
)
Expr(false)
}

}

override inline def inlinedPredicate(inline a: Int): Boolean = ${ inlinedPredicate0('a) }

override def invalidReason(a: Int): String = s"The number is a negative Int. [a: ${a.toString}"

override def predicate(a: Int): Boolean =
try {
validate(a)
true
} catch {
case _: Throwable => false
}
}

def validate(a: Int): Int =
if (a >= 0) a else sys.error("The number should be non-negative number.")

}