Skip to content

Cheat Sheet

This section is short summary of all Chimney features (described in more detail in other sections).

Tip

We're strongly recommend using the search bar (above) to quickly find the relevant piece of documentation.

Material for MkDocs' search implementation is really good!

Type classes

  • Transformer[From, To] - transforms From value into To value. The transformation should succeed for all From values, every To field/constructor argument should be populated and every From case matched
  • PartialTransformer[From, To] - transforms From value into partial.Result[To] value. By default, the transformation should succeed for all From values and every To field/constructor argument should be populated and every From case matched (just like Transformer) unless:
    • the user explicitly provided a constant or a mapping that might fail
    • the user defined/imported implicit PartialTransformer for whole/part of the transformation that could fail However, even though that provided mappings/values can fail, for derivation to succeed no field can be without a source and no pattern match case can be unhandled - partial refers to handling: null, Exceptions, smart constructors and PartialFunctions, not to magically handling the transformation in runtime with no checks.
  • Patcher[A, Patch] - updates the A value using as a source the Patch value.

Imports

DSL, all in one (recommended!)

// Summoning:
// source.transformInto[Target]        summons Transformer.AutoDerived
// source.transformIntoPartial[Target] summons PartialTransformer.AutoDerived
// obj.patchUsing(patch)               summons Patcher.AutoDerived
//
// Inlined code:
// source.into[Target].customization.transform        generates inlined Transformer code
// source.intoPartial[Target].customization.transform generates inlined PartialTransformer code
// obj.using(patch).customization.patch               generates inlined Patcher code
import io.scalaland.chimney.dsl._

DSL, selective (use with care!)

// Summoning:
// source.transformInto[Target]        summons Transformer
// source.transformIntoPartial[Target] summons PartialTransformer
// obj.patchUsing(patch)               summons Patcher
import io.scalaland.chimney.syntax._

// Inlined code:
// source.into[Target].customization.transform        generates inlined Transformer code
// source.intoPartial[Target].customization.transform generates inlined PartialTransformer code
// obj.using(patch).customization.patch               generates inlined Patcher code
import io.scalaland.chimney.inline._

// Automatic derivation returns Transformer/PartialTransformer/Patcher
// instead of Transformer.AutoDerived/PartialTransformer.AutoDerived/Patcher.AutoDerived
// (see below).
import io.scalaland.chimney.auto._

Warning

Chimney uses sanely-automatic derivation - it tries to derive instance recursively with a single macro expansion, with is both less taking on typer (faster compilation) as well as allows avoiding unnecessary boxing with partial.Result.

By importing io.scalaland.chimney.auto._ we're forcng Chimney to create intermediate instances which breaks these improvements (but it might be more familiar behavior for people coming from e.g. Circe).

Partial Results

// To use partial.Result, partial.Path, partial.Errors, etc without polluting namespace with common names.
import io.scalaland.chimney.partial

// Provides .asResult syntax.
import io.scalaland.chimney.partial.syntax._

Partial Results are desctibed more in partial.Result utilities section.

Derivation

Out of the box, Chimney is able to generate transformations between: case classes, sealed hierarchies/Scala 3 enums/Java enums, Options, Eithers, collections, unwrapping/wrapping/rewrapping AnyVals, etc.

If it misses some information, derivation would report an informative error to the users, to help them fix it with a customization.

This is the most common way users would use Chimney.

Note

We're assuming that you imported the recommended io.scalaland.chimney.dsl._ (and Transformer, PartialTransformer and Patcher for .derive/.define).

Total Transformers' derivation

Syntax What it does
source.transformInto[Target] summons a user-defined Transformer[Source, Target], if there is none, falls back on a Transformer.AutoDerived[Source, Target], then uses it to convert the source: Source into the Target
source.into[Target].transform summons a user-defined Transformer[Source, Target] and uses it to convert the source: Source into the Target, if there is none, generates the inlined conversion (without a new Transformer!) - see: inlined
source.into[Target] .customization.transform uses provided overrides/flags to generate an inlined conversion from the source: Source into the Target (without a new Transformer!) - see: inlined
Transformer.derive[Source,Target] generates a new instance of Transformer[Source, Target] - see: semi
Transformer.define[Source,Target] .customization.buildTransformer uses provided overrides/flags to generate a new instance of Transformer[Source, Target] - see: semi

Partial Transformers' derivation

Syntex What it does
source .transformIntoPartial[Target] summons a user-defined PartialTransformer[Source, Target], if there is none, falls back on user-defined Transformer[Source, Target], if there is none, falls back on a PartialTransformer.AutoDerived[Source, Target], then uses it to convert the source: Source into the partial.Result[Target]
source.intoPartial[Target] .transform summons a user-defined PartialTransformer[Source, Target] and uses it to convert the source: Source into the partial.Result[Target], if there is none, falls back on user-defined Transformer[Source, Target],if there is none, generates the inlined conversion (without a new PartialTransformer!) - see: inlined
source.intoPartial[Target] .customization.transform uses provided overrides/flags to generate an inlined conversion from the source: Source into the partial.Result[Target] (without a new PartialTransformer!) - see: inlined
PartialTransformer .derive[Source,Target] generates a new instance of PartialTransformer[Source, Target] - see: semi
PartialTransformer .define[Source,Target] .customization.buildTransformer uses provided overrides/flags to generate a new instance of PartialTransformer[Source, Target] - see: semi

Patchers' derivation

Syntax What it does
obj.patchUsing(patch) summons a user-defined Patcher[A, Patch], if there is none, falls back on a Patcher.AutoDerived[A, Patch], then uses it to patch the obj: A with the patch: Patch
obj.using(patch).patch summons a user-defined Patcher[A, Patch] and uses it to patch the obj: A with the patch: Patch, if there is none, generates the inlined conversion (without a new Patcher!) - see: inlined
obj.using(patch) .customization.patch uses provided overrides/flags to generate a patching of the obj: A with the patch: Patch (without a new Patcher!) - see: inlined
Patcher.derive[A,Patch] generates a new instance of Patcher[A, Patch] - see: semi
Patcher.define[A,Patch] .customization.buildPatcher uses provided overrides/flags to generate a new instance of Patcher[A, Patch] - see: semi

Customizations

When out of the box derivation doesn't fit ones needs, they can provide overrides and flags to adjust it.

For types supported out of the box, these are usually enough to allow Chimney generate the transformation.

Total and Partial Transformers' customizations

All flags and overrides are described in more detail in the Supported Transformations page.

Note

Examples below assume:

  • transformation From into To
  • fromField: FromField
  • toField: ToField
  • FromSubtype <: From
  • ToSubtype <: To

for convention.

While they show only path selectors like .toField/.fromField/.matchingSome/.everyItem, you can also use .matching[Subtype]/.matchingLeft/.matchingRight/.everyMapKey/.everyMapValue, combine them together, etc. These examples aren't an exhaustive list but just show what is possible.

You can chain multiple overrides together.

How to remember which override to use

Override names are constructed in the following way:

  • they start with the target of on override:
    • withConstructor - instead of using the primary contructor, provided constructor should be used
    • withFallback - when the source value is missing a field, this value would be used next
    • withField - instead of using the source field matched by name/position (in case of tuples), this value/function should be used
    • withSealedSubtype/withEnumCase - instead of using the target subtype matched by name, this function should be used
  • then, some of them reflect how override is provided:
    • Const - value is provided as it is
    • Computed - value would be computed from the source or its part
    • Handled - only a subtype will be handled, with the provided function
  • then, if the override can result in a failed value, name contain Partial
  • finally, if the override does not target a whole Source/Target type, it describes the path to value:
    • From - when only some part of Source type would be used
    • To - when only part of the Target type would be created
Override example What it does
.withConstructor { (args) => ... } use the provided function to construct To (wiring arguments)
.withConstructorTo(_.toField) { (args) => ... } use the provided function to construct ToField (wiring arguments)
.withConstructorTo(_.matchingSome.toField) { (args) => ... } the same as above (but field is in Option)
.withConstructorTo(_.everyItem.toField) { (args) => ... } the same as above (but field is in collection)
.withConstructorPartial { (args) => ... } use the provided function to construct partial.Result[To]
.withConstructorPartialTo(_.toField) { (args) => ... } use the provided function to construct partial.Result[ToField]
.withConstructorPartialTo(_.matchingSome.toField) { (args) => ... } the same as above (but field is in Option)
.withConstructorPartialTo(_.matchingSome.toField) { (args) => ... } the same as above (but field is in collection)
.withConstructorEither { (args) => ... } use the provided function to construct Either[String, To]
.withConstructorEitherTo(_.toField) { (args) => ... } use the provided function to construct Either[String, ToField]
.withConstructorEitherTo(_.matchingSome.toField) { (args) => ... } the same as above (but a field is in Option)
.withConstructorEitherTo(_.everyItem.toField) { (args) => ... } the same as above (but a field is in collection)
.withFallback(fallback) when From is missing values, they will be taken from fallback
.withFallbackFrom(_.fromField)(fallback) when FromField is missing values, they will be taken from fallback
.withFallbackFrom(_.matchingSome)(fallback) the same as above (but a field is in Option)
.withFallbackFrom(_.everyItem)(fallback) the same as above (but a field is in collection)
.withFieldConst(_.toField, value) use the provided value to construct toField
.withFieldConst(_.matchingSome.toField, value) the same as above (but a field is in Option)
.withFieldConst(_.everyItem.toField, value) the same as above (but a field is in collection)
.withFieldConstPartial(_.toField, value) use the provided partial.Result to construct toField
.withFieldConstPartial(_.matchingSome.toField, value) the same as above (but a field is in Option)
.withFieldConstPartial(_.everyItem.toField, value) the same as above (but a field is in collection)
.withFieldComputed(_.toField, from => ...) use the provided function to construct toField from From
.withFieldComputed(_.matchingSome.toField, from => ...) the same as above (but a field is in Option)
.withFieldComputed(_.everyItem.toField, from => ...) the same as above (but a field is in collection)
.withFieldComputedFrom(_.fromField)(_.toField, fromField => ...) use the provided function to construct toField from fromField
.withFieldComputedFrom(_.matchingSome.fromField)(_.matchingSome.toField, fromField => ...) the same as above (but fields are in Option)
.withFieldComputedFrom(_.everyItem.fromField)(_.everyItem.toField, fromField => ...) the same as above (but fields are in collection)
.withFieldComputedPartial(_.toField, from => ...) use the provided function to construct toField from From
.withFieldComputedPartial(_.matchingSome.toField, from => ...) the same as above (but fields are in Options)
.withFieldComputedPartial(_.everyItem.toField, from => ...) the same as above (but fields are in collections)
.withFieldComputedPartialFrom(_.fromField)(_.toField, fromField => ...) use the provided function to construct toField from fromField
.withFieldComputedPartialFrom(_.matchingSome.fromField)(_.matchingSome.toField, fromField => ...) the same as above (but fields are in Options)
.withFieldComputedPartialFrom(_.everyItem.fromField)(_.everyItem.toField, fromField => ...) the same as above (but fields are in collections)
.withSealedSubtypeHandled { (subtype: FromSubtype) => ... } when pattern matching on From, use the provided function to handle FromSubtype
.withEnumCaseHandled { (subtype: FromSubtype) => ... } the same as above
.withFieldComputedFrom(_.matching[FromSubtype]) { subtype => ... } the same as above
.withSealedSubtypeHandledPartial { (subtype: FromSubtype) => ... } when pattern matching on From, use the provided function to handle FromSubtype
.withEnumCaseHandledPartial { (subtype: FromSubtype) => ... } the same as above
.withFieldComputedPartialFrom(_.matching[FromSubtype]) { subtype => ... } the same as above
.withFieldRenamed(_.fromField, _.toField) use the fromField value to construct toField
.withFieldRenamed(_.matchingSome.fromField, _.matchingSome.toField) the same as above (but fields are in Options)
.withFieldRenamed(_.everyItem.fromField, _.everyItem.toField) the same as above (but fields are in collections)
.withSealedSubtypeRenamed[FromSubtype, ToSubtype] use the FromSubtype value to construct ToSubtype
.withEnumCaseRenamed[FromSubtype, ToSubtype] the same as above
.withFieldRenamed(_.matching[FromSubtype], _.matching[ToSubtype]) the same as above
.withFieldUnused(_.fromField) fromField should not be used, UnusedFieldPolicy error should be suppressed
.withSealedSubtypeUnmatched[ToSubtype] ToSubtype should not be matched, UnmatchedSubtypePolicy error should be suppressed
.withEnumCaseUnmatched[ToSubtype] the same as above should be suppressed

Providing Transformer flags

import io.scalaland.chimney.dsl._
import io.scalaland.chimney.{Transformer, PartialTransformer}

// Flags can be added per derivation
source.into[Target].disableMacrosLogging.transform
source.intoPartial[Target].disableMacrosLogging.transform
Transformer.define[Source, Target].disableMacrosLogging.buildTransformer
PartialTransformer.define[Source, Target].disableMacrosLogging.buildTransformer

// Or for whole scope:
locally {
  // All transformations derived in this scope will see these new flags (Scala 2-only syntax, see cookbook for Scala 3!).
  implicit val cfg = TransformerConfiguration.default.disableMacrosLogging

  source.transformInto[Target]
  source.transformIntoPartial[Target]
  Transformer.derive[Source, Target]
  PartialTransformer.derive[Source, Target]
}
Flag example What it does
.enableMethodAccessors turn on Reading from methods
.disableMethodAccessors turn off Reading from methods (default)
.enableInheritedAccessors turn on Reading from inherited values/methods
.disableInheritedAccessors turn off Reading from inherited values/methods (default)
.enableBeanGetters turn on Reading from Bean getters
.disableBeanGetters turn off Reading from Bean getters (default)
.enableBeanSetters turn on Writing to Bean setters
.disableBeanSetters turn off Writing to Bean setters (default)
.enableBeanSettersIgnoreUnmatched turn on Ignoring unmatched Bean setters
.disableBeanSettersIgnoreUnmatched turn off Ignoring unmatched Bean setters (default)
.enableNonUnitBeanSetters turn on Writing to non-Unit Bean setters
.disableNonUnitBeanSetters turn off Writing to non-Unit Bean setters (default)
.enableDefaultValues turn on Allowing fallback to the constructor's default values
.disableDefaultValues turn off Allowing fallback to the constructor's default values (default)
.enableOptionDefaultsToNone turn on Allowing fallback to None as the constructor's argument
.disableOptionDefaultsToNone turn off Allowing fallback to None as the constructor's argument (default)
.enableNonAnyValWrappers turn on Transformation from/into a wrapper type
.disableNonAnyValWrappers turn off Transformation from/into a wrapper type (default)
.enablePartialUnwrapsOption turn on Controlling automatic Option unwrapping (default)
.disablePartialUnwrapsOption turn off Controlling automatic Option unwrapping
.enableOptionFallbackMerge(SourceOrElseFallback) turn on merging Options with orElse taking source before fallback
.enableOptionFallbackMerge(FallbackOrElseSource) turn on merging Options with orElse taking fallback before source
.disableOptionFallbackMerge turn off merging Options with orElse (default)
.enableEitherFallbackMerge(SourceOrElseFallback) turn on merging Eithers with orElse taking source before fallback
.enableEitherFallbackMerge(FallbackOrElseSource) turn on merging Eithers with orElse taking fallback before source
.disableEitherFallbackMerge turn off merging Eithers with orElse (default)
.enableCollectionFallbackMerge(SourceAppendFallback) turn on merging collections with ++ taking source before fallback
.enableCollectionFallbackMerge(FallbackAppendSource) turn on merging collections with ++ taking fallback before source
.disableCollectionFallbackMerge turn off merging collections with++` (default)
.enableUnusedFieldPolicyCheck(FailOnIgnoredSourceVal) turn on Checking for unused fields to fail on unused
.disableUnusedFieldPolicyCheck turn off Checking for unused fields (default)
.enableUnmatchedSubtypePolicy(FailOnUnmatchedTargetSubtype) turn on Checking for unmatched subtypes to fail on unmatched
.disableUnmatchedSubtypePolicy turn off Checking for unmatched subtypes (default)
.enableImplicitConflictResolution(PreferTotalTransformer) turn on Resolving priority of implicit Total vs Partial Transformers to Total Transformers
.enableImplicitConflictResolution(PreferPartialTransformer) turn on Resolving priority of implicit Total vs Partial Transformers to Partial Transformers
.disableImplicitConflictResolution turn off Resolving priority of implicit Total vs Partial Transformers (default)
.enableMacrosLogging turn on Debugging macros
.disableMacrosLogging turn off Debugging macros (default)

Patchers' customization

All flags and overrides are described in more detail in the Supported Patching page.

Note

Examples below assume:

  • patching A using Patch
  • aField: AField
  • patchField: PatchField

for convention.

While they show only path selectors like .aField/.patchField/.matchingSome/.everyItem, you can also use .matchingLeft/.matchingRight/.everyMapKey/.everyMapValue, combine them together, etc. These examples aren't an exhaustive list but just show what is possible.

You can chain multiple overrides together.

Override example What it does
.withFieldConst(_.aField, value) use the provided value to update aField
.withFieldConst(_.matchingSome.aField, value) the same as above (but a field is in Option)
.withFieldConst(_.everyItem.aField, value) the same as above (but a field is in collection)
.withFieldComputed(_.aField, patch => ...) use the provided function to update toField from patch
.withFieldComputed(_.matchingSome.aField, patch => ...) the same as above (but a field is in Option)
.withFieldComputed(_.everyItem.aField, patch => ...) the same as above (but a field is in collection)
.withFieldComputedFrom(_.patchField)(_.aField, patchField => ...) use the provided function to update toField from patchField
.withFieldComputedFrom(_.matchingSome.patchField)(_.matchingSome.aField, patchField => ...) the same as above (but fields are in Options)
.withFieldComputedFrom(_.everyItem.patchField)(_.everyItem.aField, patchField => ...) the same as above (but a field is in collection)
.withFieldIgnored(_.patchField) patchField should not be used, derivation should not complain that it isn't
.withFieldIgnored(_.matchingSome.patchField) the same as above (but fields are in Options)
.withFieldIgnored(_.everyItem.patchField) the same as above (but a field is in collection)

Providing Patcher flags

import io.scalaland.chimney.dsl._
import io.scalaland.chimney.Patcher

// Flags can be added per derivation
obj.using(patch).disableMacrosLogging.patch
Patcher.define[A, Patch].disableMacrosLogging.buildPatcher

// Or for whole scope:
locally {
  // All transformations derived in this scope will see these new flags (Scala 2-only syntax, see cookbook for Scala 3!).
  implicit val cfg = PatcherConfiguration.default.disableMacrosLogging

  obj.patchUsing(patch)
  Patcher.derive[A, Patch]
}
Flag example What it does
.ignoreRedundantPatcherFields turn on Ignoring fields in patches
.failRedundantPatcherFields turn off Ignoring fields in patches (default)
.ignoreNoneInPatch turn on Treating None as no-update instead of "set to None"
.clearOnNoneInPatch turn off Treating None as no-update instead of "set to None" (default)
.ignoreLeftInPatch turn on Treating Left as no-update instead of "set to Left"
.useLeftOnLeftInPatch turn off Treating Left as no-update instead of "set to Left" (default)
.appendCollectionInPatch turn on Appending to collection instead of replacing it
.overrideCollectionInPatch turn off Appending to collection instead of replacing it (default)
.enableMacrosLogging turn on Debugging macros
.disableMacrosLogging turn off Debugging macros (default)

Integrations

Only some types would require writing some implicits to handle them. This might include: new type libraries, custom collections (that don't implement Scala's collections interfaces), custom optional types, etc.

Integrations are described in more detail in Integrations section.

Before writing one, it's worth knowing that:

Tip

All integrations for Transformers work with PartialTransformers and Patchers as well!

Total Transformers' integrations

Providing and using implicit Transformers
import io.scalaland.chimney.Transformer

// Such implicit Transformer would be used if there are no overrides, it cannot cooperate
// with selectors in DSL (.matching[Type], .matchingSome, .matchingLeft, .matchingRight,
// .everyItem, .everyMapKey, .everyMapValue, field name selection...), so it works best
// for types that we either don't intend to customize OR we want to define Transformer only
// once and then reuse everywhere.
implicit val transformerWithHardcodedType: Transformer[A, B] = ...

// Here, we're using Transformer in another implicit, when Transformer could be either
// derived or provided - use only when the derivation could not be customized
// nor can be provided by integrations.
implicit def transformerWithHardcodedTypes2(
  implicit transformer: Transformer.AutoDerived[C, D] // make sure it's .AutoDerived!
): Transformer[E, F] = ...
Providing integrations, more flexible than hardcoded Transformer
import io.scalaland.chimney.integrations
import io.scalaland.chimney.partial

// Here, we're providing Transformers with the ability to .map F[_]/.traverse F[_] into partial.Result,
// such impliclit allows us to use .everyItem in customizations of F[value] transformation.
implicit def outerTransformer[A, B]: integration.TotalOuterTransformer[F[A], F[B], A, B] =
  new integrations.TotalOuterTransformer[F[A], F[B], A, B] {
    /** Converts the outer type when the conversion of inner types turn out to be total. */
    def transformWithTotalInner(inner: F[A], f: A => B): F[B] = ...
    /** Converts the outer type when the conversion of inner types turn out to be partial. */
    def transformWithPartialInner(inner: F[A], failFast: Boolean, f: A => partial.Result[B]): partia.Result[F[B]] = ...
  }

// Here', we're providing Transformer with the ability to convert into MyOwnCollection[A]
// from any other collection (whose items can be converted to A), convert from MyOwnCollection[A]
// (when every item can be converted to the target collection's type), and customize the
// transformation between the collections using .everyItem.
implicit def buildIterable[A]: integration.TotallyBuildIterable[MyOwnCollection[A], A] =
  new integration.TotallyBuildIterable[MyOwnCollection[A], A] {
    /** Factory of the `Collection` */
    def totalFactory: Factory[A, MyOwnCollection[A]] = ...
    /** Creates [[Iterator]] for the `Collection`. */
    def iterator(collection: MyOwnCollection[A]): Iterator[A] = ...
  }

// Like above, but additionally allows working with .everyMapKey/.everyMapValue.
implicit def buildMap[K, V]: integration.TotallyBuildMap[MyOwnMap[K, V], K, V] =
  new integration.TotallyBuildMap[MyOwnMap[K, V], K, V] {
    /** Factory of the `Collection` */
    def totalFactory: Factory[(K, V), MyOwnMap[K, V]] = ...
    /** Creates [[Iterator]] for the `Collection`. */
    def iterator(collection: MyOwnMap[K, V]): Iterator[(K, V)] = ...
  }

// Here, we're handling some type representing Option, which is not scala.Option,
// such implicit allows automatic unwrapping in PartialTransformer/wrapping in every case,
// and usage of .matchingSome in customization of MyOwnOptional[B] transformation.
implicit def nonStandardOptional[B]: integrations.OptionalValue[MyOwnOptional[B], B] =
  new integrations.OptionalValue[MyOwnOptional[B], B] {
    /** Creates an empty optional value. */
    def empty: MyOwnOptional[B] = ...
    /** Creates non-empty optional value (should handle nulls as empty). */
    def of(value: B): MyOwnOptional[B] = ...
    /** Folds optional value just like [[Option.fold]]. */
    def fold[A](oa: MyOwnOptional[B], onNone: => A, onSome: B => A): A = ...
  }

// Here, we're handling the case when we would like to use .enableDefaultValues,
// or .enableDefaultValueOfType[DefaultValueSet] but the DefaultValueSet type is used
// by some class that we're transformaing, which does not have default values defined.
// With such implicit we can pretend it does.
implicit val providedMissingDefault: integrations.DefaultValue[Value] =
  new integrations.DefaultValue[Value] {
    /** Provide the default value. */
    def provide(): Value = ...
  }

Partial Transformations' integrations

Providing and using implicit PartialTransformers
import io.scalaland.chimney.PartialTransformer

// Such implicit Transformer would be used if there are no overrides, it cannot cooperate
// with selectors in DSL (.matching[Type], .matchingSome, .matchingLeft, .matchingRight,
// .everyItem, .everyMapKey, .everyMapValue, field name selection...), so it works best
// for types that we either don't intend to customize OR we want to define Transformer only
// once and then reuse everywhere.
implicit val transformerWithHardcodedType: PartialTransformer[A, B] = ...

// Here, we're using Transformer in another implicit, when Transformer could be either
// derived or provided - use only when the derivation could not be customized
// nor can be provided by integrations.
implicit def transformerWithHardcodedTypes2(
  implicit transformer: PartialTransformer.AutoDerived[C, D] // make sure it's .AutoDerived!
): PartialTransformer[E, F] = ...
Providing integrations, more flexible than hardcoded Transformer
import io.scalaland.chimney.integrations
import io.scalaland.chimney.partial

// Here, we're providing Transformers with the ability to .map F[_]/.traverse F[_] into partial.Result,
// such implicit allows us to use .everyItem in customizations of F[value] transformation.
implicit def outerTransformer[A, B]: integration.PartialOuterTransformer[F[A], F[B], A, B] =
  new integrations.PartialOuterTransformer[F[A], F[B], A, B] {
    /** Converts the outer type when the conversion of inner types turn out to be total. */
    def transformWithTotalInner(inner: F[A], failFast: Boolean,f: A => B): partia.Result[F[B]] = ...
    /** Converts the outer type when the conversion of inner types turn out to be partial. */
    def transformWithPartialInner(inner: F[A], failFast: Boolean, f: A => partial.Result[B]): partia.Result[F[B]] = ...
  }

// Here', we're providing Transformer with the ability to convert into MyOwnCollection[A]
// from any other collection (whose items can be converted to A), convert from MyOwnCollection[A]
// (when every item can be converted to the target collection's type), and customize the
// transformation between the collections using .everyItem.
implicit def buildIterable[A]: integration.TotallyBuildIterable[MyOwnCollection[A], A] =
  new integration.TotallyBuildIterable[MyOwnCollection[A], A] {
    /** Factory of the `Collection`, validated with [[partial.Result]]. */
    def partialFactory: Factory[A, partial.Result[MyOwnCollection[A]]] = ...
    /** Creates [[Iterator]] for the `Collection`. */
    def iterator(collection: MyOwnCollection[A]): Iterator[A] = ...
  }

// Like above, but additionally allows working with .everyMapKey/.everyMapValue.
implicit def buildMap[K, V]: integration.PartiallyBuildMap[MyOwnMap[K, V], K, V] =
  new integration.PartiallyBuildMap[MyOwnMap[K, V], K, V] {
    /** Factory of the `Collection`, validated with [[partial.Result]]. */
    def partialFactory: Factory[(K, V), partial.Result[MyOwnMap[K, V]]] = ...
    /** Creates [[Iterator]] for the `Collection`. */
    def iterator(collection: MyOwnMap[K, V]): Iterator[(K, V)] = ...
  }

Patchers' integrations

Providing and using implicit Patcher
import io.scalaland.chimney.Patcher

// Such implicit Patcher would be used if there are no overrides, it cannot cooperate
// with selectors in DSL (.matching[Type], .matchingSome, .matchingLeft, .matchingRight,
// .everyItem, .everyMapKey, .everyMapValue, field name selection...), so it works best
// for types that we either don't intend to customize OR we want to define Patcher only
// once and then reuse everywhere.
implicit val patcherWithHardcodedType: Patcher[A, B] = ...

// Here, we're using Patcher in another implicit, when Patcher could be either
// derived or provided - use only when the derivation could not be customized
// nor can be provided by integrations.
implicit def patcherWithHardcodedTypes2(
  implicit patcher: Patcher.AutoDerived[C, D] // make sure it's .AutoDerived!
): Patcher[E, F] = ...