8000 [0.2.x] Fallible transformers by arainko · Pull Request #122 · arainko/ducktape · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2ebccec
bring back Mode, Transformer.Fallible etc
arainko Jan 6, 2024
298fb20
implement first batch of fallible transformations (of the accumulatin…
arainko Jan 16, 2024
71c15ce
factor out PlanInterpret.ifStatement
arainko Jan 16, 2024
14a7f7f
finish up accumulating interpreter
arainko Jan 16, 2024
0ae0cca
initial shot at fail fast transformations
arainko Jan 17, 2024
75e9d63
finish up fail fast transformations
arainko Jan 18, 2024
779f175
plug in error reporting
arainko Jan 18, 2024
62ba3ba
plug in configs
arainko Jan 19, 2024
0234f11
More fallible configs
arainko Jan 20, 2024
244fa0b
kind of, sort of, resolve the issue with fallibleComputed not inferin…
arainko Jan 21, 2024
e6ace86
rename Refiner to Backend
arainko Jan 21, 2024
abfc441
finish porting the library (a few issues still remain)
arainko Feb 2, 2024
0793414
trying to fix bad owners
arainko Feb 4, 2024
326f594
keep o ntrying to fix bad owners
arainko Feb 4, 2024
3c3c0d5
it works ;
arainko Feb 4, 2024
07beb4e
roughly port over tests
arainko Feb 4, 2024
05ea6ec
more tests
arainko Feb 6, 2024
2394364
fix wrong type of config
arainko Feb 6, 2024
853c95b
turn off Xcheckmacros for now, bring back accummulating tests
arainko Feb 11, 2024
fa354d7
fix a weird thing in `ProductBinder`, try adding more tests
arainko Feb 15, 2024
a12e965
add more tests and uncover a compiler crash
arainko Feb 17, 2024
92caec7
finalize tests
arainko Feb 24, 2024
58cc0ca
clean up deprecation messages, delete Playground
arainko Feb 24, 2024
5196bf0
disable deprecations in tests
arainko Feb 24, 2024
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
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ lazy val ducktape =
.enablePlugins(TypelevelMimaPlugin)
.in(file("ducktape"))
.settings(
scalacOptions ++= List("-Xcheck-macros", "-deprecation", "-Werror", "-Wunused:all"),
scalacOptions ++= List("-deprecation", "-Wunused:all"),
Test / scalacOptions --= List("-deprecation"),
libraryDependencies += "org.scalameta" %%% "munit" % "1.0.0-M10" % Test
)
.dependsOn(tooling)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
package io.github.arainko.ducktape

import io.github.arainko.ducktape.internal.Transformations
import io.github.arainko.ducktape.internal.{ FallibleTransformations, TotalTransformations }

final class AppliedBuilder[Source, Dest](value: Source) {
final class AppliedBuilder[Source, Dest] private[ducktape] (value: Source) {
inline def transform(inline config: Field[Source, Dest] | Case[Source, Dest]*): Dest =
Transformations.between[Source, Dest](value, "transformation", config*)
TotalTransformations.between[Source, Dest](value, "transformation", config*)

def fallible[F[+x], M <: Mode[F]](using M): AppliedBuilder.Fallible[F, M, Source, Dest] =
AppliedBuilder.Fallible[F, M, Source, Dest](value)
}

object AppliedBuilder {

final class Fallible[F[+x], M <: Mode[F], Source, Dest] private[ducktape] (source: Source)(using F: M) {

inline def transform(
inline config: Field.Fallible[F, Source, Dest] | Case.Fallible[F, Source, Dest]*
): F[Dest] =
FallibleTransformations.between[F, Source, Dest](source, F, "transformation", config*)
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package io.github.arainko.ducktape

import io.github.arainko.ducktape.internal.Transformations
import io.github.arainko.ducktape.internal.{ FallibleTransformations, TotalTransformations }

final class AppliedViaBuilder[Source, Dest, Func, Args <: FunctionArguments] private (value: Source, function: Func) {
inline def transform(inline config: Field[Source, Args] | Case[Source, Args]*): Dest =
Transformations.via[Source, Dest, Func, Args](value, function, "transformation", config*)
TotalTransformations.via[Source, Dest, Func, Args](value, function, "transformation", config*)

def fallible[F[+x], M <: Mode[F]](using M): AppliedViaBuilder.Fallible[F, M, Source, Dest, Func, Args] =
AppliedViaBuilder.Fallible[F, M, Source, Dest, Func, Args](value, function)
}

object AppliedViaBuilder {
Expand All @@ -16,4 +19,15 @@ object AppliedViaBuilder {
internal.Function
.encodeAsType[[args <: FunctionArguments, retTpe] =>> AppliedViaBuilder[A, retTpe, Func, args]](function, inst)
}

final class Fallible[F[+x], M <: Mode[F], Source, Dest, Func, Args <: FunctionArguments] private[ducktape] (
source: Source,
function: Func
)(using F: M) {

inline def transform(
inline config: Field.Fallible[F, Source, Args] | Case.Fallible[F, Source, Args]*
): F[Dest] = FallibleTransformations.via[F, Source, Dest, Func, Args](source, function, F, "transformation", config*)

}
}
58 changes: 53 additions & 5 deletions ducktape/src/main/scala/io/github/arainko/ducktape/Case.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,23 @@ package io.github.arainko.ducktape

import scala.annotation.compileTimeOnly

opaque type Case[A, B] = Unit
opaque type Case[A, B] <: Case.Fallible[Nothing, A, B] = Case.Fallible[Nothing, A, B]

object Case {
opaque type Fallible[+F[x], A, B] = Unit

@compileTimeOnly("Case.fallibleConst is only useable as a case configuration for transformations")
def fallibleConst[F[+x], A, B, SourceTpe, DestTpe](
selector: Selector ?=> A => SourceTpe,
value: F[DestTpe]
): Case.Fallible[F, A, B] = ???

@compileTimeOnly("Case.fallibleConst is only useable as a case configuration for transformations")
def fallibleComputed[F[+x], A, B, SourceTpe, DestTpe](
selector: Selector ?=> A => SourceTpe,
function: SourceTpe => F[DestTpe]
): Case.Fallible[F, A, B] = ???

@compileTimeOnly("Case.const is only useable as a case configuration for transformations")
def const[A, B, SourceTpe, DestTpe](selector: Selector ?=> A => SourceTpe, value: DestTpe): Case[A, B] = ???

Expand All @@ -13,7 +27,7 @@ object Case {

@deprecated(
message = "Use the variant that accepts a path selector instead (Case.const(_.at[SourceSubtype], ...))",
since = "0.2.0-M1"
since = "ducktape 0.2.0-M1"
)
@compileTimeOnly("'Case.const' needs to be erased from the AST with a macro.")
def const[SourceSubtype]: Case.Const[SourceSubtype] = ???
Expand All @@ -30,18 +44,52 @@ object Case {

@deprecated(
message = "Use the variant that accepts a path selector instead (Case.computed(_.at[SourceSubtype], ...))",
since = "0.2.0-M1"
since = "ducktape 0.2.0-M1"
)
@compileTimeOnly("'Case.computed' needs to be erased from the AST with a macro.")
@compileTimeOnly("Case.computed is only useable as a case configuration for transformations")
def computed[SourceSubtype]: Case.Computed[SourceSubtype] = ???

opaque type Computed[SourceSubtype] = Unit

object Computed {
extension [SourceSubtype](inst: Computed[SourceSubtype]) {

@compileTimeOnly("'Case.computed' needs to be erased from the AST with a macro.")
@compileTimeOnly("Case.computed is only useable as a case configuration for transformations")
def apply[Source >: SourceSubtype, Dest](f: SourceSubtype => Dest): Case[Source, Dest] = ???
}
}

@deprecated(
message = "Use the variant that accepts a path selector instead (Case.fallibleConst(_.at[SourceSubtype], ...))",
since = "ducktape 0.2.0-M3"
)
@compileTimeOnly("Case.fallibleConst is only useable as a case configuration for transformations")
def fallibleConst[SourceSubtype]: Case.FallibleConst[SourceSubtype] = ???

opaque type FallibleConst[SourceSubtype] = Unit

object FallibleConst {
extension [SourceSubtype](inst: FallibleConst[SourceSubtype]) {

@compileTimeOnly("'Case.fallibleConst' needs to be erased from the AST with a macro.")
def apply[F[+x], Source, Dest](const: F[Dest]): Case.Fallible[F, Source, Dest] = ???
}
}

@deprecated(
message = "Use the variant that accepts a path selector instead (Case.fallibleComputed(_.at[SourceSubtype], ...))",
since = "ducktape 0.2.0-M3"
)
@compileTimeOnly("Case.fallibleComputed is only useable as a case configuration for transformations")
def fallibleComputed[SourceSubtype]: Case.FallibleComputed[SourceSubtype] = ???

opaque type FallibleComputed[SourceSubtype] = Unit

object FallibleComputed {
extension [SourceSubtype](inst: FallibleComputed[SourceSubtype]) {

@compileTimeOnly("Case.fallibleComputed is only useable as a case configuration for transformations")
def apply[F[+x], Source, Dest](const: SourceSubtype => F[Dest]): Case.Fallible[F, Source, Dest] = ???
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
package io.github.arainko.ducktape

import io.github.arainko.ducktape.internal.Transformations
import io.github.arainko.ducktape.internal.{ FallibleTransformations, TotalTransformations }

final class DefinitionBuilder[Source, Dest] {
inline def build(inline config: Field[Source, Dest] | Case[Source, Dest]*): Transformer[Source, Dest] = source =>
Transformations.between[Source, Dest](source, "definition", config*)
final class DefinitionBuilder[Source, Dest] private[ducktape] {
inline def build(inline config: Field[Source, Dest] | Case[Source, Dest]*): Transformer[Source, Dest] =
Transformer.Derived.FromFunction(source => TotalTransformations.between[Source, Dest](source, "definition", config*))

def fallible[F[+x], M <: Mode[F]](using M): DefinitionBuilder.Fallible[F, M, Source, Dest] =
DefinitionBuilder.Fallible[F, M, Source, Dest]
}

object DefinitionBuilder {

final class Fallible[F[+x], M <: Mode[F], Source, Dest] private[ducktape] (using F: M) {
inline def build(
inline config: Case.Fallible[F, Source, Dest] | Field.Fallible[F, Source, Dest]*
): Transformer.Fallible[F, Source, Dest] =
Transformer.Fallible.Derived.FromFunction(source =>
FallibleTransformations.between[F, Source, Dest](source, F, "definition", config*)
)

}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package io.github.arainko.ducktape

import io.github.arainko.ducktape.internal.Transformations
import io.github.arainko.ducktape.internal.{ FallibleTransformations, TotalTransformations }

final class DefinitionViaBuilder[Source, Dest, Func, Args <: FunctionArguments] private (function: Func) {
transparent inline def build(inline config: Field[Source, Args] | Case[Source, Args]*): Transformer[Source, Dest] =
new Transformer[Source, Dest] {
def transform(value: Source): Dest =
Transformations.via[Source, Dest, Func, Args](value, function, "definition", config*)
}
inline def build(inline config: Field[Source, Args] | Case[Source, Args]*): Transformer[Source, Dest] =
Transformer.Derived.FromFunction(value =>
TotalTransformations.via[Source, Dest, Func, Args](value, function, "definition", config*)
)

def fallible[F[+x], M <: Mode[F]](using M): DefinitionViaBuilder.Fallible[F, M, Source, Dest, Func, Args] =
DefinitionViaBuilder.Fallible[F, M, Source, Dest, Func, Args](function)
}

object DefinitionViaBuilder {
Expand All @@ -29,4 +31,17 @@ object DefinitionViaBuilder {
}
}
}

final class Fallible[F[+x], M <: Mode[F], Source, Dest, Func, ArgSelector <: FunctionArguments] private[ducktape] (
function: Func
)(using F: M) {

inline def build(
inline config: Field.Fallible[F, Source, ArgSelector] | Case.Fallible[F, Source, ArgSelector]*
): Transformer.Fallible[F, Source, Dest] =
Transformer.Fallible.Derived.FromFunction(value =>
FallibleTransformations.via[F, Source, Dest, Func, ArgSelector](value, function, F, "definition", config*)
)

}
}
16 changes: 15 additions & 1 deletion ducktape/src/main/scala/io/github/arainko/ducktape/Field.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,23 @@ import scala.annotation.compileTimeOnly
// Kept around for source compat with 0.1.x
def Arg: Field.type = Field

opaque type Field[A, B] = Unit
opaque type Field[A, B] <: Field.Fallible[Nothing, A, B] = Field.Fallible[Nothing, A, B]

object Field {
opaque type Fallible[+F[+x], A, B] = Unit

@compileTimeOnly("Field.fallibleConst is only useable as a field configuration for transformations")
def fallibleConst[F[+x], A, B, DestFieldTpe](
selector: Selector ?=> B => DestFieldTpe,
value: F[DestFieldTpe]
): Field.Fallible[F, A, B] = ???

@compileTimeOnly("Field.fallibleComputed is only useable as a field configuration for transformations")
def fallibleComputed[F[+x], A, B, DestFieldTpe](
selector: Selector ?=> B => DestFieldTpe,
function: A => F[DestFieldTpe]
): Field.Fallible[F, A, B] = ???

@compileTimeOnly("Field.const is only useable as a field configuration for transformations")
def const[A, B, DestFieldTpe, ConstTpe](selector: Selector ?=> B => DestFieldTpe, value: ConstTpe): Field[A, B] = ???

Expand Down
Loading
0