Skip to content

Instantly share code, notes, and snippets.

@deyindra
Last active December 3, 2017 22:06
Show Gist options
  • Save deyindra/3ba5a2fb1329f17038974e32f3633bcd to your computer and use it in GitHub Desktop.
Save deyindra/3ba5a2fb1329f17038974e32f3633bcd to your computer and use it in GitHub Desktop.
Scala Implicit
import language.implicitConversions
import language.reflectiveCalls
/**
* This Objects provide safe conversion of [[String]] value to [[Any]] specific type, and return [[Option]]
* of the same type after conversion. In case of any exception it will return `None`
* Current conversion for following types are supported
* `Int`, `Float`, `Double`, `Boolean`, `Short`, `Byte`, `Long`. For any custom type one need to create an
* `implicit object` extending `StringConverter` trait
* For example
* {{{
* import StringImplicits._
* val x:Option[Int] = "1".toT[Int] //return Some(1)
* val x:Option[Int] = "a".toT[Int] //return None
* }}}
*/
object StringImplicits{
/**
* Trait which is conver any `String` to a specific type, e.g. `Int`, `Double`, `Float`, `Boolean`, `Short` or
* any custom type
* @tparam A `Any` type
*/
trait StringConverter[A] {
/**
* @param x `String` value
* @return `A` where `A` extends to `Any`
*/
def convert(x: String): A
}
/**
* Convert `String` to `Int`
* throws [[Exception]] in case of conversion is not possible
*/
implicit object StringToInt extends StringConverter[Int] {
def convert(x: String): Int = x.toInt
}
/**
* Convert `String` to `Double`
* throws [[Exception]] in case of conversion is not possible
*/
implicit object StringToDouble extends StringConverter[Double] {
def convert(x: String): Double = x.toDouble
}
/**
* Convert `String` to `Float`
* throws [[Exception]] in case of conversion is not possible
*/
implicit object StringtoFloat extends StringConverter[Float] {
override def convert(x: String): Float = x.toFloat
}
/**
* Convert `String` to `Short`
* throws [[Exception]] in case of conversion is not possible
*/
implicit object StringtoShort extends StringConverter[Short] {
override def convert(x: String): Short = x.toShort
}
/**
* Convert `String` to `Byte`
* throws [[Exception]] in case of conversion is not possible
*/
implicit object StringtoByte extends StringConverter[Byte] {
override def convert(x: String): Byte = x.toByte
}
/**
* Convert `String` to `Long`
* throws [[Exception]] in case of conversion is not possible
*/
implicit object StringtoLong extends StringConverter[Long] {
override def convert(x: String): Long = x.toLong
}
/**
* Convert `String` to `Boolean`.
* This will convert `yes` or `true` to `Boolean` `true` and
* `no` or `false` to `Boolean` `false` else throw [[IllegalArgumentException]]
*/
implicit object StringToBoolean extends StringConverter[Boolean] {
override def convert(x: String): Boolean = x.trim.toLowerCase match {
case "yes" | "true" => true
case "no" | "false" => false
case _ => throw new IllegalArgumentException
}
}
/**
* `SafeStringConversion` is an implicit class with one `String` argument
* @param x `String` which needs to be converted to a specific type
*/
implicit class SafeStringConversion(x: String) {
/**
*
* @param ev implicit [[StringConverter]] object which will convert `String` to a specific type extends `Any`
* @tparam A a type extends `Any`
* @return [[Option]] in case of successfull conversion it will return `Some(value)` else `None`
*/
def toT[A](implicit ev: StringConverter[A]):Option[A] = try{
Option(ev.convert(x))
} catch {
case e:Exception =>
log.warn("Exception thrown", e)
None
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment