Skip to content

Releases: arainko/chanterelle

chanterelle 0.1.3

15 Feb 11:56
4550fb1

Choose a tag to compare

chanterelle 0.1.3

This release features a milestone feature - deep merging of named tuples. Take a quick peek at the examples from the docs:

import chanterelle.*

val tup = (field1 = 1, field2 = (level1Field1 = 3, level1Field2 = (level2Field = 4)))
val mergee = (field2 = (level1Field3 = 5, level1Field2 = (anotherField = 6)))

val transformed = tup.transform(_.merge(mergee))

// evaluates to: 
// (field1 = 1, field2 = (level1Field1 = 3, level1Field2 = (level2Field = 4, anotherField = 6), level1Field3 = 5))

...or if you want to be more precise in applying your merges you can try the .regional modifier:

val tup = (field1 = 1, field2 = (level1Field1 = 3, level1Field2 = (level2Field = 4)))
val mergee = (level1Field2 = (anotherField = 6))

val transformed = tup.transform(_.merge(mergee).regional(_.field2))

// evaluates to:
// (field1 = 1, field2 = (level1Field1 = 3, level1Field2 = (level2Field = 4, anotherField = 6)))

The rules of merging are as follows:

  • named tuples are merged by field name,
  • fields from the named tuple we merge with (the mergee) take precedence,
  • nested named tuples (that don't come from modifications) and other merged values are recursed,
  • other values get completely overwritten using the value from the mergee.

At this time, there are some limitations on what you can do with a merged value in the same .transform block that I hope to address in the future (i.e. currently it's not possible to use .put on a merged value, things like that), in the meantime users can always chain multiple .transforms to achieve whatever they were going for.

What's Changed

New Contributors

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

chanterelle 0.1.2

29 Dec 17:18
6401515

Choose a tag to compare

chanterelle 0.1.2

This release adds a new .rename modifier that allows for ad-hoc-ish field name transformations:

val tup = (anotherField = (field1 = 123, field2 = 123))

val transformed = tup.transform(_.rename(_.replace("field", "property").toUpperCase))
(ANOTHERFIELD = (PROPERTY1 = 123, PROPERTY2 = 123))

The blast radius of the renaming function can be further controlled with '.local' and '.regional':

val tup = (optField = Some((field = (lowerDown = 1))))

// '.local' renames the toplevel fields
val transformedLocal = tup.transform(_.rename(_.toUpperCase).local(_.optField.element))

// '.regional' makes it so that all the of fields underneath the path are transformed
val transformedRegional = tup.transform(_.rename(_.toUpperCase).regional(_.optField.element))
val transformedLocal = (optField = Some((FIELD = (lowerDown = 1))))
val transformedRegional = (optField = Some((FIELD = (LOWERDOWN = 1))))

There's also a number of predefined case transformations inside the FieldName companion object:

val camel = (
  repoInfo = (
    fullName = "octocat/hello-world",
    createdAt = "2011-01-26T19:01:12Z",
  )
)

val snake = (
  repo_info = (
    full_name = "octocat/hello-world",
    created_at = "2011-01-26T19:01:12Z",
  )
)

val kebab = (
  `repo-info` = (
    `full-name` = "octocat/hello-world",
    `created-at` = "2011-01-26T19:01:12Z",
  )
)

val camelToSnake = camel.transform(_.rename(FieldName.camelCase.toSnakeCase))
val camelToKebab = camel.transform(_.rename(FieldName.camelCase.toKebabCase))
val snakeToCamel = snake.transform(_.rename(FieldName.snakeCase.toCamelCase))
val kebabToCamel = kebab.transform(_.rename(FieldName.kebabCase.toCamelCase))
val camelToSnake = (repo_info = (full_name = "octocat/hello-world", created_at = "2011-01-26T19:01:12Z"))
val camelToKebab = (repo-info = (full-name = "octocat/hello-world", created-at = "2011-01-26T19:01:12Z"))
val snakeToCamel = (repoInfo = (fullName = "octocat/hello-world", createdAt = "2011-01-26T19:01:12Z"))
val kebabToCamel = (repoInfo = (fullName = "octocat/hello-world", createdAt = "2011-01-26T19:01:12Z"))

Users can also define their own bundles of transformations by combaning various operations on FieldNames in a transparent inline def:

transparent inline def renamedAndUppercased(inline fieldName: FieldName) =
   fieldName.rename("someName", "someOtherName").toUpperCase

val tup = (someName = 1)
val transformed = tup.transform(_.rename(renamedAndUppercased))
(SOMEOTHERNAME = 1)

What's Changed

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

chanterelle 0.1.1

30 Aug 17:02
be3d61b

Choose a tag to compare

chanterelle 0.1.1

This release brings support for Scala JS and Scala Native (thanks @plokhotnyuk!) along with a new feature - Either traversals:

val tup = (left = Left(1), right = Right("2"))
val transformed = tup.transform(
  _.update(_.left.leftElement)(_ + 1),
  _.update(_.right.rightElement)(_ + "-SUFFIXED")
)
// evaluates to this:
(left = Left(2), right = Right("2-SUFFIXED"))

and a bugfix for selecting tuple elements with .apply(N) rather than solely relying on ._N accessors (which only go up to 22!)

What's Changed

New Contributors

Full Changelog: v0.1.0...v0.1.1

chanterelle 0.1.0

01 Aug 18:49

Choose a tag to compare

chanterelle 0.1.0

chanterelle is a library for seamless named tuple interactions - think deep modifications, field removals, additions and lens-like ops. You know, the works.

Installation

libraryDependencies += "io.github.arainko" %% "chanterelle" % "0.1.0"

Documentation

The entry point of chanterelle is a single import:

import chanterelle.*

which brings in the .transform extension method defined on named tuples:

val input = (toplevelField = (nestedField = 1, fieldToUpdate = 2, optionalField = Some((anEvenMoreOptionalField = 3))))

val transformed = input.transform(
  _.update(_.toplevelField.fieldToUpdate)(_ + 1), // note the value of toplevelField.fieldToUpdate in the output
  _.remove(_.toplevelField.nestedField), // toplevelField.nestedField gets removed from the output value
  _.put(_.toplevelField.optionalField.element)((newField = 4)) // the element of an Option or a collection can be accessed with `.element`
)

...which, in turn, evaluates to:

(toplevelField = (fieldToUpdate = 3, optionalField = Some((anEvenMoreOptionalField = 3, newField = 4))))

Head on over to the README if you want to see more!

What's Changed

  • docs module with named tuple pretty-printing by @arainko in #3

New Contributors

Full Changelog: v0.0.1...v0.1.0

chanterelle 0.0.1

30 Jul 19:35

Choose a tag to compare

chanterelle 0.0.1

This is the very first release of chanterelle - this version has all of the MVP features that were initially planned i.e:

Support for:

✔️ named tuples
✔️ tuples
✔️ options
✔️ collections

Modifiers:

✔️ single-element .put
✔️ single-element .compute
✔️ update
✔️ remove (both named and positional tuples)

Other:

✔️ sane errors
✔️ optimized interpreter - turn non-modified branches into Leaves that just take the source value

What's Changed

New Contributors

Full Changelog: https://github.com/arainko/chanterelle/commits/v0.0.1