Wednesday, July 24, 2019

Kotlin in Action: Answers to Chapter 6 Exercises

And here's the answer to the chapter 6 exercise.

Exercise 1: Promo Emails

import java.lang.Exception
import java.lang.RuntimeException

fun main() {
  val jsmith432 = User(
    "jsmith432",
    "John",
    "Smith",
    "john.smith@yahoo.com"
  )
  val jdoe = User(
    username = "jdoe",
    emailAddress = "jdoe@gmail.com"
  )
  val unknown = User(emailAddress = "abc123@hotmail.com")
  val bob = User(
    username = "bob",
    firstName = "Bob"
  )
  val users = listOf(jsmith432, jdoe, unknown, bob)
  val usersWithNull = listOf(jsmith432, null, jdoe)

  try {
    sendSalesPromotion(null)
  } catch (e: Exception) {
    println("${e.message}\n")
  }

  sendSalesPromotion(jsmith432)
  sendSalesPromotion(jdoe)
  sendSalesPromotion(unknown)
  sendSalesPromotion(bob)

  try {
    sendSalesPromotions(null)
  } catch (e: Exception) {
    println("${e.message}\n")
  }

  try {
    sendSalesPromotions(usersWithNull)
  } catch (e: Exception) {
    println("${e.message}\n")
  }

  sendSalesPromotions(users)
}

fun sendSalesPromotions(users: List<User?>?) {
  users ?: nullParameterException("users")
  users.forEach { it ?: nullParameterException("user") }
  users.forEach(::sendSalesPromotion)
}

fun sendSalesPromotion(user: User?) {
  user ?: nullParameterException("user")
  user.emailAddress?.let {
    val subject = "Blowout XYZ Widget Sale!"
    val message =
      """Dear ${user.firstName ?: user.username ?: "Valued Customer"}
        |
        |We're having a massive sale on XYZ Widgets!
        |95% Off! Get yours today!""".trimMargin()
    sendEmail(Email(it, subject, message))
  }
}

fun nullParameterException(paramName: String): Nothing {
  throw RuntimeException("Param $paramName is null")
}

fun sendEmail(email: Email) {
  println("""Email sent:
            |  emailAddress: ${email.emailAddress}
            |  subject: ${email.subject}
            |  message: ${email.message}
            |""".trimMargin()
  )
}

data class User(
  val username: String? = null,
  val firstName: String? = null,
  val lastName: String? = null,
  val emailAddress: String? = null
)

data class Email(
  val emailAddress: String,
  val subject: String,
  val message: String
)