Skip to content

Commit

Permalink
add support for base notation literals and implement hex notation
Browse files Browse the repository at this point in the history
  • Loading branch information
brendon- committed Oct 9, 2016
1 parent b26b2d2 commit 0283eae
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 4 deletions.
21 changes: 18 additions & 3 deletions src/main/scala/scopt/options.scala
Expand Up @@ -25,7 +25,6 @@ object Read {
val arity = 1
val reads = f
}
implicit val intRead: Read[Int] = reads { _.toInt }
implicit val stringRead: Read[String] = reads { identity }
implicit val doubleRead: Read[Double] = reads { _.toDouble }
implicit val booleanRead: Read[Boolean] =
Expand All @@ -39,8 +38,24 @@ object Read {
case s =>
throw new IllegalArgumentException("'" + s + "' is not a boolean.")
}}
implicit val longRead: Read[Long] = reads { _.toLong }
implicit val bigIntRead: Read[BigInt] = reads { BigInt(_) }

private def fixedPointWithRadix(str: String): (String, Int) = str.toLowerCase match {
case s if s.startsWith("0x") => (s.stripPrefix("0x"), 16)
case s => (s, 10)
}
implicit val intRead: Read[Int] = reads { str =>
val (s, radix) = fixedPointWithRadix(str)
Integer.parseInt(s, radix)
}
implicit val longRead: Read[Long] = reads { str =>
val (s, radix) = fixedPointWithRadix(str)
java.lang.Long.parseLong(s, radix)
}
implicit val bigIntRead: Read[BigInt] = reads { str =>
val (s, radix) = fixedPointWithRadix(str)
BigInt(s, radix)
}

implicit val bigDecimalRead: Read[BigDecimal] = reads { BigDecimal(_) }
implicit val yyyymmdddRead: Read[Calendar] = calendarRead("yyyy-MM-dd")
def calendarRead(pattern: String): Read[Calendar] = calendarRead(pattern, Locale.getDefault)
Expand Down
31 changes: 30 additions & 1 deletion src/test/scala/scopt/ImmutableParserSpec.scala
Expand Up @@ -26,10 +26,28 @@ class ImmutableParserSpec extends Specification { def is = args(sequential = tru
parse 1 out of -f 1 ${intParser("-f", "1")}
parse 1 out of -f:1 ${intParser("-f:1")}
parse 1 out of -f=1 ${intParser("-f=1")}
parse 1 out of --foo 0x01 ${intParser("--foo", "0x01")}
parse 1 out of --foo:0x01 ${intParser("--foo:0x01")}
parse 1 out of --foo=0x01 ${intParser("--foo=0x01")}
parse 1 out of -f 0x1 ${intParser("-f", "0x1")}
parse 1 out of -f:0x1 ${intParser("-f:0x1")}
fail to parse --foo ${intParserFail{"--foo"}}
fail to parse --foo bar ${intParserFail("--foo", "bar")}
fail to parse --foo=bar ${intParserFail("--foo=bar")}

opt[Long]('f', "foo") action { x => x } should
parse 1 out of --foo 1 ${longParser("--foo", "1")}
parse 1 out of --foo:1 ${longParser("--foo:1")}
parse 1 out of --foo=1 ${longParser("--foo=1")}
parse 1 out of -f 1 ${longParser("-f", "1")}
parse 1 out of -f:1 ${longParser("-f:1")}
parse 1 out of -f=1 ${longParser("-f=1")}
parse 1 out of --foo 0x01 ${longParser("--foo", "0x01")}
parse 1 out of --foo:0x01 ${longParser("--foo:0x01")}
parse 1 out of --foo=0x01 ${longParser("--foo=0x01")}
parse 1 out of -f 0x1 ${longParser("-f", "0x1")}
parse 1 out of -f:0x1 ${longParser("-f:0x1")}

opt[String]("foo") action { x => x } should
parse "bar" out of --foo bar ${stringParser("--foo", "bar")}
parse "bar" out of --foo:bar ${stringParser("--foo:bar")}
Expand Down Expand Up @@ -211,6 +229,17 @@ class ImmutableParserSpec extends Specification { def is = args(sequential = tru
result === None
}

val longParser1 = new scopt.OptionParser[Config]("scopt") {
override def showUsageOnError = true
head("scopt", "3.x")
opt[Long]('f', "foo").action( (x, c) => c.copy(longValue = x))
help("help")
}
def longParser(args: String*) = {
val result = intParser1.parse(args.toSeq, Config())
result.get.intValue === 1
}

val stringParser1 = new scopt.OptionParser[Config]("scopt") {
head("scopt", "3.x")
opt[String]("foo").action( (x, c) => c.copy(stringValue = x) )
Expand Down Expand Up @@ -733,7 +762,7 @@ Usage: scopt [options]
"""
}

case class Config(flag: Boolean = false, intValue: Int = 0, stringValue: String = "",
case class Config(flag: Boolean = false, intValue: Int = 0, longValue: Long = 0L, stringValue: String = "",
doubleValue: Double = 0.0, boolValue: Boolean = false, debug: Boolean = false,
bigDecimalValue: BigDecimal = BigDecimal("0.0"),
calendarValue: Calendar = new GregorianCalendar(1900, Calendar.JANUARY, 1),
Expand Down
28 changes: 28 additions & 0 deletions src/test/scala/scopt/MutableParserSpec.scala
Expand Up @@ -14,10 +14,27 @@ class MutableParserSpec extends Specification { def is = args(sequential = true)
parse 1 out of --foo=1 ${intParser("--foo=1")}
parse 1 out of -f 1 ${intParser("-f", "1")}
parse 1 out of -f:1 ${intParser("-f:1")}
parse 1 out of --foo 0x01 ${intParser("--foo","0x01")}
parse 1 out of --foo:0x01 ${intParser("--foo:0x01")}
parse 1 out of --foo=0x01 ${intParser("--foo=0x01")}
parse 1 out of -f 0x1 ${intParser("-f", "0x1")}
parse 1 out of -f:0x1 ${intParser("-f:0x1")}
fail to parse --foo ${intParserFail{"--foo"}}
fail to parse --foo bar ${intParserFail("--foo", "bar")}
fail to parse --foo=bar ${intParserFail("--foo=bar")}

opt[Long]('f', "foo") foreach { x => x } should
parse 1 out of --foo 1 ${longParser("--foo", "1")}
parse 1 out of --foo:1 ${longParser("--foo:1")}
parse 1 out of --foo=1 ${longParser("--foo=1")}
parse 1 out of -f 1 ${longParser("-f", "1")}
parse 1 out of -f:1 ${longParser("-f:1")}
parse 1 out of --foo 0x01 ${longParser("--foo","0x01")}
parse 1 out of --foo:0x01 ${longParser("--foo:0x01")}
parse 1 out of --foo=0x01 ${longParser("--foo=0x01")}
parse 1 out of -f 0x1 ${longParser("-f", "0x1")}
parse 1 out of -f:0x1 ${longParser("-f:0x1")}

opt[String]("foo") foreach { x => x } should
parse "bar" out of --foo bar ${stringParser("--foo", "bar")}
parse "bar" out of --foo:bar ${stringParser("--foo:bar")}
Expand Down Expand Up @@ -130,6 +147,17 @@ class MutableParserSpec extends Specification { def is = args(sequential = true)
foo === 1
}

def longParser(args: String*) = {
var foo = 0L
val parser = new scopt.OptionParser[Unit]("scopt") {
head("scopt", "3.x")
opt[Long]('f', "foo").foreach( x => foo = x )
help("help")
}
parser.parse(args.toSeq)
foo === 1L
}

def intParserFail(args: String*) = {
var foo = 0
val parser = new scopt.OptionParser[Unit]("scopt") {
Expand Down

0 comments on commit 0283eae

Please sign in to comment.