
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:
usernameshould be copied as is,emailshould be converted to/fromStringin theEmailclass,registrationDateshould be converted to/fromStringin ISO format. You can useparseandtoStringfronLocalDateTimefor that,heightshould be converted to/fromIntinCentimetersclass.
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) } }