Skip to main content

Field

Field represents a class field (constructor parameter) in the IR. Combine a name with a type reference, optionally adding default values and modifiers.

Use Cases

  • Defining constructor parameters for case classes
  • Specifying fields in abstract classes
  • Modeling data structure fields with optional defaults

Construction

Build a field with a name and type:

import zio.blocks.codegen.ir._

val id = Field("id", TypeRef.Long)
val name = Field("name", TypeRef.String)
val email = Field("email", TypeRef.optional(TypeRef.String))

With default value:

import zio.blocks.codegen.ir._

val timeout = Field("timeout", TypeRef.Long, defaultValue = Some("5000L"))
val retries = Field("retries", TypeRef.Int, defaultValue = Some("3"))

With annotations:

import zio.blocks.codegen.ir._

val annotated = Field(
"id",
TypeRef.Long,
annotations = List(Annotation("id"))
)

Key Operations

All Field instances support these operations:

Accessing Components

Extract parts of a field:

import zio.blocks.codegen.ir._

val field = Field("age", TypeRef.Int, defaultValue = Some("0"))

View field properties:

import zio.blocks.codegen.ir._

field.name // "age"
// res4: String = "age"
field.typeRef // TypeRef.Int
// res5: TypeRef = TypeRef(name = "Int", typeArgs = List())
field.defaultValue // Some("0")
// res6: Option[String] = Some("0")
field.annotations // List[Annotation]
// res7: List[Annotation] = List()

Building with Copy

Modify a field using copy:

import zio.blocks.codegen.ir._

val field = Field("age", TypeRef.Int, defaultValue = Some("0"))

Apply modifications:

import zio.blocks.codegen.ir._

val updated = field.copy(
defaultValue = Some("18"),
annotations = List(Annotation("min"))
)
// updated: Field = Field(
// name = "age",
// typeRef = TypeRef(name = "Int", typeArgs = List()),
// defaultValue = Some("18"),
// annotations = List(Annotation(name = "min", args = List())),
// doc = None
// )

Examples

These examples show practical usage patterns for Field:

Example 1: Simple Fields

Create fields for a case class:

import zio.blocks.codegen.ir._
import zio.blocks.codegen.emit._

val order = CaseClass(
name = "Order",
fields = List(
Field("id", TypeRef.Long),
Field("customerId", TypeRef.String),
Field("total", TypeRef("BigDecimal")),
Field("status", TypeRef.String)
)
)

val file = ScalaFile(
packageDecl = PackageDecl("com.shop"),
types = List(order)
)

Emits:

import zio.blocks.codegen.emit._

ScalaEmitter.emit(file, EmitterConfig())
// res10: String = """package com.shop
//
// case class Order(
// id: Long,
// customerId: String,
// total: BigDecimal,
// status: String,
// )
// """

Example 2: Fields with Defaults

Case class fields with default values:

import zio.blocks.codegen.ir._
import zio.blocks.codegen.emit._

val config = CaseClass(
name = "DatabaseConfig",
fields = List(
Field("host", TypeRef.String, defaultValue = Some("\"localhost\"")),
Field("port", TypeRef.Int, defaultValue = Some("5432")),
Field("timeout", TypeRef.Long, defaultValue = Some("30000L"))
)
)

val file = ScalaFile(
packageDecl = PackageDecl("com.example"),
types = List(config)
)

Emits:

import zio.blocks.codegen.emit._

ScalaEmitter.emit(file, EmitterConfig())
// res12: String = """package com.example
//
// case class DatabaseConfig(
// host: String = "localhost",
// port: Int = 5432,
// timeout: Long = 30000L,
// )
// """

Example 3: Optional and Collection Fields

Fields with generic types:

import zio.blocks.codegen.ir._
import zio.blocks.codegen.emit._

val article = CaseClass(
name = "Article",
fields = List(
Field("title", TypeRef.String),
Field("content", TypeRef.String),
Field("author", TypeRef.optional(TypeRef.String)),
Field("tags", TypeRef.list(TypeRef.String)),
Field("metadata", TypeRef.map(TypeRef.String, TypeRef.String))
)
)

val file = ScalaFile(
packageDecl = PackageDecl("com.example"),
types = List(article)
)

Emits:

import zio.blocks.codegen.emit._

ScalaEmitter.emit(file, EmitterConfig())
// res14: String = """package com.example
//
// case class Article(
// title: String,
// content: String,
// author: Option[String],
// tags: List[String],
// metadata: Map[String, String],
// )
// """

Example 4: Nested Generic Types

Complex field types:

import zio.blocks.codegen.ir._
import zio.blocks.codegen.emit._

val response = CaseClass(
name = "Response",
fields = List(
Field(
"data",
TypeRef("Option", List(
TypeRef("List", List(TypeRef.String))
))
),
Field(
"errors",
TypeRef("List", List(
TypeRef("Map", List(TypeRef.String, TypeRef.String))
))
)
)
)

val file = ScalaFile(
packageDecl = PackageDecl("com.example"),
types = List(response)
)

Emits:

import zio.blocks.codegen.emit._

ScalaEmitter.emit(file, EmitterConfig())
// res16: String = """package com.example
//
// case class Response(
// data: Option[List[String]],
// errors: List[Map[String, String]],
// )
// """

Example 5: Fields with Type Parameters

Fields using generic type variables:

import zio.blocks.codegen.ir._
import zio.blocks.codegen.emit._

val page = CaseClass(
name = "Page",
fields = List(
Field("items", TypeRef("List", List(TypeRef("T")))),
Field("total", TypeRef.Long),
Field("pageSize", TypeRef.Int)
),
typeParams = List(TypeParam("T"))
)

val file = ScalaFile(
packageDecl = PackageDecl("com.example"),
types = List(page)
)

Emits:

import zio.blocks.codegen.emit._

ScalaEmitter.emit(file, EmitterConfig())
// res18: String = """package com.example
//
// case class Page[T](
// items: List[T],
// total: Long,
// pageSize: Int,
// )
// """