Conversions
From Something
Record.from creates a record from a Product, typically a case class instance.
import com.github.tarao.record4s.Record
case class Person(name: String, age: Int)
Record.from(Person("tarao", 3))
// res0: % {
// val name: String
// val age: Int
// } = %(name = tarao, age = 3)
Anything other than Product can be converted to a record if RecordLike instance is given.
To Something
You can use to method to convert a record to a Product.
%(name = "ikura", age = 1).to[Person]
// res1: Person = Person(name = "ikura", age = 1)
A record can be converted to anything other than Product if Converter instance is given.
From / To JSON
Records can be converted from/to JSON using circe. See Integration with circe for the detail.
In Scala.js, fromJSON and toJSON methods are available. See Converting a Record from
/ to a JSON string for the detail.
From / To JavaScript Objects
In Scala.js, fromJS and toJS methods are available. See Converting a Record from / to
a Native JavaScript Object for the detail.
Upcast
Records can implicitly be upcast since their types are represented as structural types in Scala 3.
val person = %(name = "tarao", age = 3)
// person: % {
// val name: String
// val age: Int
// } = %(name = tarao, age = 3)
val named: % { val name: String } = person
// named: % {
// val name: String
// } = %(name = tarao, age = 3)
Note that the runtime value still has statically hidden fields ⸺ age of named in the
above example. This is because named points to the same object as person, where it
has person.age.
To drop the hidden fields, use as method.
val named2 = person.as[% { val name: String }]
// named2: % {
// val name: String
// } = %(name = tarao)
In this case, as makes a copy of person only with the visible fields.
Selecting / Unselecting / Reordering / Renaming
It is also possible to shrink a record to have selected fields.
import com.github.tarao.record4s.select
val person = %(name = "tarao", age = 3, email = "tarao@example.com")
// person: % {
// val name: String
// val age: Int
// val email: String
// } = %(name = tarao, age = 3, email = tarao@example.com)
val contact = person(select.name.email)
// contact: % {
// val name: String
// val email: String
// } = %(name = tarao, email = tarao@example.com)
Or to unselect some fields.
import com.github.tarao.record4s.unselect
val contact = person(unselect.age)
// contact: % {
// val name: String
// val email: String
// } = %(name = tarao, email = tarao@example.com)
Field selection also supports reordering and renaming.
val account = person(
select
.email(rename = "login")
.name(rename = "displayName"),
)
// account: % {
// val login: String
// val displayName: String
// } = %(login = tarao@example.com, displayName = tarao)
Note that the field order is semantically insignificant. You can always reorder the static type of the fields.
person
// res3: % {
// val name: String
// val age: Int
// val email: String
// } = %(name = tarao, age = 3, email = tarao@example.com)
val person2: % {
val email: String
val age: Int
val name: String
} = person
// person2: % {
// val email: String
// val age: Int
// val name: String
// } = %(name = tarao, age = 3, email = tarao@example.com)