8000 Releases · arainko/ducktape · GitHub
[go: up one dir, main page]

Skip to content

Releases

ducktape 0.1.10

Choose a tag to compare

@arainko arainko released this 15 Jul 16:56
9b89f3b

This release brings Transformer.Fallible automatic derivation for coproducts courtesy of @gregor-i along with new and shiny config options for your fallible coproduct transformations like Case.fallibleConst or Case.fallibleComputed.

This release also bumps the Scala version to 3.3.0 (a LTS release) which means all users of this lib also need to bump their projects to 3.3.0 (there's literally no reason not to as Scala 3 is backwards compatible).

What's Changed

New Contributors

Full Changelog: v0.1.9...v0.1.10

ducktape 0.1.9

Choose a tag to compare

@arainko arainko released this 28 Jun 09:28
5545371

This release contains two new features:

  • support for transformations between non-singleton coproducts - ducktape is now able to transform between coproduct elements that have the same name
  • betweenMaps - a Transformer and Transformer.Fallible instanstance to transform between different kinds of Maps (eg. Map[K1, V1] -> Map[K2, V2] given that there exists a Transformer for K1 -> K2 and V1 -> V2, SortedMap -> TreeMap etc.)

What's Changed

  • [issue#61] More advanced coproduct transformations by @arainko in #63
  • [issue #64] add total and fallible transformers between maps of different kind by @arainko in #65

Full Changelog: v0.1.8...v0.1.9

ducktape 0.1.8

Choose a tag to compare

@arainko arainko released this 18 May 18:49
6f6def2

This is release contains a fix for #60

What's Changed

Full Changelog: v0.1.7...v0.1.8

ducktape 0.1.7

Choose a tag to compare

@arainko arainko released this 02 May 14:28
bc5233a

This is a eighth release in the 0.1.x line and it is fully backwards binary-compatible with previous releases.

This a bugfix release for the issue reported here #54 - this is an upstream issue, but the workaround was easy enough on my side to resolve it.

What's Changed

  • 0.1.5 -> 0.1.6 by @arainko in #53
  • [Issue#54] Move contents of fallibleSyntax.scala to syntax.scala by @arainko in #55

Full Changelog: v0.1.6...v0.1.7

ducktape 0.1.6

Choose a tag to compare

@arainko arainko released this 01 May 21:06
030e2a6

This is a seventh release in the 0.1.x line and it is fully backwards binary-compatible with previous releases.

This release included two major features:

  • Fallible Transformers - for when your model has an elaborate construction scheme and plain field mappings just do not cut it - head on over to the docs to read more
  • Scala.js and Scala Native releases - all you've got to do is add an additional % to your dependency, like this:
libraryDependencies += "io.github.arainko" %%% "ducktape" % "0.1.6"

(cross-compilation and CI jobs for this project were made easier and less painful with sbt-typelevel, thank you!)

What's Changed

Full Changelog: v0.1.5...v0.1.6

ducktape 0.1.5

Choose a tag to compare

@arainko arainko released this 23 Apr 20:55
f1a30c4

This is a sixth release in the 0.1.x line and it is fully backwards binary-compatible with previous releases.

This release includes a number of changes and features:

  1. A new and shiny Field.default config option that uses a field's default value (if it has one) to complete a transformation. Once again thank you very much @saeltz for working on this. (#38)
  2. Multiple configurations on the same field will now emit a warning (with instructions on how to suppress it if it's desired behavior) (#40 )
  3. All of the Transformer instances got a new and shiny names (instead of compiler-generated ones, these are now deprecated), eg. the automatically derived transformer for products is now betweenProducts, the transformer between collections is betweenCollections etc. (#37)
  4. A bug causing a lot of compiler strain and weird implicit search results when trying to transform between primitives and AnyVal classes was fixed (#37)

What's Changed

  • [Issue #40] warn on repeated configs by @arainko in #43
  • [Issue#37] Fix anyval transformers and standardize instance names by @arainko in #44
  • #38 Support default parameters in case class to case class by @saeltz in #39
  • Field.default follow-up by @arainko in #46
  • 0.1.4 -> 0.1.5 in docs by @arainko in #47

New Contributors

Full Changelog: v0.1.4...v0.1.5

ducktape 0.1.4

Choose a tag to compare

@arainko arainko released this 26 Mar 12:22
adf0370

This is a fifth release of ducktape in the 0.1.x line and it is fully backwards binary-compatible with previous releases.

This release includes a small bugfix for the optimization edge case discussed in #41 and some nicer error messages when an instance of Transformer is missing.

What's Changed

  • [Issue #8] Document recursive transformers and add nicer error messages when a Transformer is missing by @arainko in #36
  • fix #41 by @arainko in #42

Full Changelog: v0.1.3...v0.1.4

ducktape 0.1.3

Choose a tag to compare

@arainko arainko released this 10 Feb 22:03
d5ddb67

This is a fourth release of ducktape in the 0.1.x line and it is fully backwards binary-compatible with previous releases.

This release contains a new case class to case class configuration options that allows us to get matching fields from a different case class, an example:

import io.github.arainko.ducktape.*

final case class Person(firstName: String, lastName: String, age: Int)
final case class PersonButMoreFields(firstName: String, lastName: String, age: Int, socialSecurityNo: String)
val person = Person("Jerry", "Smith", 20)

final case class FieldSource(lastName: String, socialSecurityNo: String)
// 4. Grab and use all matching fields from a different case class (a compiletime error will be issued if none of the fields match)
val withAllMatchingFields = 
  person
    .into[PersonButMoreFields]
    .transform(Field.allMatching(FieldSource("SourcedLastName", "SOURCED-SSN")))
// withAllMatchingFields: PersonButMoreFields = PersonButMoreFields(
//   firstName = "Jerry",
//   lastName = "SourcedLastName",
//   age = 20,
//   socialSecurityNo = "SOURCED-SSN"
// )

It'll also issue a compiletime failure in case none of the fields of the case class you pass in match the any of the fields from the source case class

What's Changed

Full Changelog: v0.1.2...v0.1.3

ducktape 0.1.2

Choose a tag to compare

@arainko arainko released this 07 Jan 00:52
4e4fa09

This a third release of ducktape in the 0.1.x line and it is fully backwards binary-compatible with previous releases.

This release contains a bugfix for a very weird interaction between the derivation of Transformer.Identity and type path references in case classes. More info here.

What's Changed

Full Changelog: v0.1.1...v0.1.2

ducktape 0.1.1

Choose a tag to compare

@arainko arainko released this 13 Dec 11:31
89e99db

This a second release of ducktape in the 0.1.x line and it is fully backwards binary-compatible with previous releases.

The theme of this release is more refinement in code generation. A lot of Transformer instances do not make it to runtime now (eg. when transforming Option[A] => Optioin[B], A => Option[B], CollectionA[A] => Collection[B] etc.).

For the curious there's now Transformer.Debug.showCode to see the code that's being generated at compile time.

--- nitty gritty stuff --

  • resolve an issue where implicit resolution in a macro (eg. Expr.summon and Implicits.search) was failing and a fallback to scala.compiletime.summonInline was needed

A solution to this issue was to create a macro that creates the typeclass instance itself not a macro that only does the underlying transformation.
Eg.

// OG version
inline def transform[A, B](value: A): B = ${ transformMacro[A, B]('value) }
def transformMacro[A: Type, B: Type](value: Expr[A])(using Quotes): Expr[B] = ??? // do the transformation here

inline given Transformer[A, B] = (a: A) => transform[A, B](a) // <-- this seems to trip implicit search with Expr.summon/Implicits.search but not summonInline

// fixed version
inline def transformer[A, B]: Transformer[A, B] =  ${ transformerMacro[A, B]('value) }
def transformerMacro[A: Type, B: Type](using Quotes): Expr[Transformer[A, B] = ??? // do the transformation but also build an instance of the typeclass at the same time

inline given Transformer[A, B] =  transformer[A, B] // <-- this doesn't trip Expr.summon/Implicits.search - weird weird weird 

This fix allowed me to greatly simplify logic of Transformer normalization, which can now be done straight after getting our hands on an instance of a transformer instead of going through the whole tree to transform some specific nodes after (summonInline expands some time after the initial inlining?)

Examples:

case class Person(int: Int, str: String, inside: Inside)
case class Person2(int: Int, str: String, inside: Inside2)

case class Inside(str: String, int: Int, inside: EvenMoreInside)
case class Inside2(int: Int, str: String, inside: Option[EvenMoreInside2])

case class EvenMoreInside(str: String, int: Int)
case class EvenMoreInside2(str: String, int: Int)

val person = Person(1, "2", Inside("2", 1, EvenMoreInside("asd", 3)))
person.to[Person2]

person.to[Person2] now expands to:

to[Person](person)[Person2]((inline$make$i1[Person, Person2](ForProduct)((((source: Person) =>
 new Person2(
    int = source.int,
     str = source.str,
     inside = new Inside2(
      int = source.inside.int,
      str = source.inside.str,
      inside = Some.apply[EvenMoreInside2](
        new EvenMoreInside2(
          str = source.inside.inside.str,
          int = source.inside.inside.int
        )
      )
 ))): Transformer[Person, Person2])): ForProduct[Person, Person2]))

Note how inside expands to a Some(...), in the previous version this call would allocate two more instances of Transformer and then do the transformation, now it does the transformation without any extra allocations.

It also rewrites collection-to-collection transformation to

val transformedCollection = sourceCollectio.map(src => ... /* transform from src to dest */).to(destCollectionFactory)

Just as in the Some(...) example, no intermediate transformers are needed anymore!

I also plan to special case invocations of to do rewrite the AST to contain the transformation lifted from the supplied transformer so in some cases the library will be able to get rid of an additional transformer instance.

What's Changed

  • Add MiMa by @arainko in #20
  • Resolve a longstanding issue with resolving Transformers in macros & more Transformer AST rewrites to get rid of unnecessary runtime instances by @arainko in #21
  • 0.1.1 docs (A look at the code section), LiftTransformationModule now actually encapsulates all the logic of lifting transformations by @arainko in #23

Full Changelog: 0.1.0...v0.1.1

0