Package groovy.transform

# Annotation Interface RecordOptions

@Documented @Retention(SOURCE) @Target(TYPE) public @interface RecordOptions
Class annotation used to assist in the creation of record-like classes.

Since:
  4.0.0
See Also:
  - `ImmutableOptions`
  - `MapConstructor`
  - `TupleConstructor`
  - `PropertyOptions`
  - `RecordBase`

- ## Optional Element Summary

  Optional Elements
  Modifier and Type
  Optional Element
  Description
  `boolean`
  `components`
  If `true`, this adds a method `components()` to the record which returns its components as a typed tuple `Tuple0`, `Tuple1`...
  `boolean`
  `copyWith`
  If `true`, this adds a method `copyWith` which takes a Map of new property values and returns a new instance of the record class with these values set.
  `boolean`
  `getAt`
  If `true`, this adds a method `getAt(int)` which given an integer n, returns the n'th component in the record.
  `RecordTypeMode`
  `mode`
  Mode to use when creating record type classes.
  `boolean`
  `size`
  If `true`, this adds a method `size()` to the record which returns the number of components.
  `boolean`
  `toList`
  If `true`, this adds a method `toList()` to the record which returns the record's components as a list.
  `boolean`
  `toMap`
  If `true`, this adds a method `toMap()` to the record.

- ## Element Details

  - ### mode

    RecordTypeMode mode
    Mode to use when creating record type classes.
    Default:
      AUTO

  - ### getAt

    boolean getAt
    If `true`, this adds a method `getAt(int)` which given an integer n, returns the n'th component in the record. Example:

         import static groovy.test.GroovyAssert.shouldFail

         record Point(int x, int y, String color) {}

         def p = new Point(100, 200, 'green')
         assert p[0] == 100
         assert p[1] == 200
         assert p[2] == 'green'
         shouldFail(IllegalArgumentException) {
             p[-1]
         }

         // getAt also enables destructuring
         def (x, y, c) = p
         assert x == 100
         assert y == 200
         assert c == 'green'

    If a method `getAt(int)` already exists in the class, then this setting is ignored, and no additional method is generated.
    Default:
      true

  - ### toList

    boolean toList
    If `true`, this adds a method `toList()` to the record which returns the record's components as a list. Example:

         record Point(int x, int y, String color) {}
         def p = new Point(100, 200, 'green')
         assert p.toList() == [100, 200, 'green']

    If a method `toList()` already exists in the class, then this setting is ignored, and no additional method is generated.
    Default:
      true

  - ### toMap

    boolean toMap
    If `true`, this adds a method `toMap()` to the record. Example:

         record Point(int x, int y, String color) {}
         def p = new Point(100, 200, 'green')
         assert p.toMap() == [x:100, y:200, color:'green']

    If a method `toMap()` already exists in the class, then this setting is ignored, and no additional method is generated.
    Default:
      true

  - ### size

    boolean size
    If `true`, this adds a method `size()` to the record which returns the number of components. Example:

         record Point(int x, int y, String color) {}
         def p = new Point(100, 200, 'green')
         assert p.size() == 3

    If a method `size()` already exists in the class, then this setting is ignored, and no additional method is generated.
    Default:
      true

  - ### copyWith

    boolean copyWith
    If `true`, this adds a method `copyWith` which takes a Map of new property values and returns a new instance of the record class with these values set. Example:

         @groovy.transform.RecordType(copyWith = true)
         class Person {
             String first, last
         }

         def tim   = new Person('tim', 'yates')
         def alice = tim.copyWith(first:'alice')

         assert tim.toString() == 'Person[first=tim, last=yates]'
         assert alice.toString() == 'Person[first=alice, last=yates]'

    Unknown keys in the map are ignored, and if the values would not change the object, then the original object is returned.

    A key may also be a dotted nested path (e.g. `copyWith('address.city': 'NYC')`); every node on the path must itself provide `copyWith(Map)`. A transactional block form is also generated, in which `old` is the original object and `prop.modify { }` is a single-field shorthand: `copyWith { name = old.name.toUpperCase(); address.city = 'y' }`. Use the `old` form to reach a real same-named `modify` method on a value type, or simply for clarity. If a method called `copyWith` that takes a single parameter already exists in the class, then this setting is ignored, and no method is generated.

    Default:
      false

  - ### components

    boolean components
    If `true`, this adds a method `components()` to the record which returns its components as a typed tuple `Tuple0`, `Tuple1`... Example:

         import groovy.transform.*

         @RecordOptions(components=true)
         record Point(int x, int y, String color) {}

         def (x, y, c) = new Point(100, 200, 'green').components()
         assert x == 100
         assert y.intdiv(2) == 100
         assert c.toUpperCase() == 'GREEN'

    The signature of the components method for this example is:

         Tuple3<Integer, Integer, String> components()

    This is suitable for destructuring in `TypeChecked` scenarios. If a method `components()` already exists in the class, then this setting is ignored, and no additional method is generated. It is a compile-time error if there are more components in the record than the largest TupleN class in the Groovy codebase.
    Default:
      false