article banner

Exercise: Conversion and measurement unit creation

Your task is to implement two kinds of extension functions. First, you need functions to transform between User and UserJson classes. User represents our domain object, while UserJson represents the structure that is sent to the client. The conversion should be done according to the following rules:

  • username should be copied as is,
  • email should be converted to/from String in the Email class,
  • registrationDate should be converted to/from String in ISO format. You can use parse and toString fron LocalDateTime for that,
  • height should be converted to/from Int in Centimeters class.

Then implement cm extension property for Int that will create a Centimeters object.

data class User( val username: String, val email: Email, val registrationDate: LocalDateTime, val height: Centimeters, ) data class Email(val value: String) data class Centimeters(val value: Int) data class UserJson( val username: String, val email: String, val registrationDate: String, val heightCm: Int, )

Once your solution is ready, the following code should work:

val user = User( username = "alex", email = Email("alex@example.com"), registrationDate = LocalDateTime .of(1410, 7, 15, 10, 13), height = 170.cm, ) val userJson = user.toUserJson() println(userJson) // UserJson(username=alex, email=alex@example.com, // registrationDate=1410-07-15T10:13, heightCm=170) val user2 = userJson.toUser() println(user2) // User(username=alex, // email=Email(value=alex@example.com), // registrationDate=1410-07-15T10:13, // height=Centimeters(value=170))

This problem can either be solved in the below playground or you can clone kotlin-exercises project and solve it locally. In the project, you can find code template for this exercise in essentials/extensions/User.kt. You can find there example usage and unit tests.

Once you are done with the exercise, you can check your solution here.

Playground

import org.junit.Test import java.time.LocalDateTime import kotlin.test.assertEquals // TODO data class User( val username: String, val email: Email, val registrationDate: LocalDateTime, val height: Centimeters, ) data class Email(val value: String) data class Centimeters(val value: Int) data class UserJson( val username: String, val email: String, val registrationDate: String, val heightCm: Int, ) // TODO: Implement extensions to convert User to UserJson and vice versa, // and to create Centimeters from Int fun main() { val user = User( username = "alex", email = Email("alex@example.com"), registrationDate = LocalDateTime .of(1410, 7, 15, 10, 13), height = 170.cm, ) val userJson = user.toUserJson() println(userJson) // UserJson(username=alex, email=alex@example.com, // registrationDate=1410-07-15T10:13, heightCm=170) val user2 = userJson.toUser() println(user2) // User(username=alex, // email=Email(value=alex@example.com), // registrationDate=1410-07-15T10:13, // height=Centimeters(value=170)) } class DataConversionTest { @Test fun `test User to UserJson conversion`() { val user = User( username = "alex", email = Email("alex@example.com"), registrationDate = LocalDateTime.now(), height = 170.cm ) val userJson = user.toUserJson() assertEquals("alex", userJson.username) assertEquals("alex@example.com", userJson.email) assertEquals(user.registrationDate.toString(), userJson.registrationDate) assertEquals(user.height.value, userJson.heightCm) } @Test fun `test UserJson to User conversion`() { val userJson = UserJson( username = "alex", email = "alex@example.com", registrationDate = LocalDateTime.now().toString(), heightCm = 170 ) val user = userJson.toUser() assertEquals("alex", user.username) assertEquals("alex@example.com", user.email.value) assertEquals(userJson.registrationDate, user.registrationDate.toString()) assertEquals(userJson.heightCm.cm, user.height) } @Test fun `test cm extension property`() { val value = 150 val cm = value.cm assertEquals(value, cm.value) } }