Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow option to wrap something thats repeatable and keep it repeatable #19

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions mainargs/src/TokensReader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -153,24 +153,35 @@ object TokensReader {
def shortName = wrapped.shortName
}

implicit def OptionRead[T: TokensReader.Simple]: TokensReader[Option[T]] = new OptionRead[T]
implicit def OptionRead[T: TokensReader.Simple]: TokensReader.Simple[Option[T]] = new OptionRead[T]
class OptionRead[T: TokensReader.Simple] extends Simple[Option[T]] {
def shortName = implicitly[TokensReader.Simple[T]].shortName
def read(strs: Seq[String]) = {
strs.lastOption match {
case None => Right(None)
case Some(s) => implicitly[TokensReader.Simple[T]].read(Seq(s)) match {
if (implicitly[TokensReader.Simple[T]].alwaysRepeatable) {
Option(strs).filter(_.nonEmpty) match{
case None => Right(None)
case Some(strs) => implicitly[TokensReader.Simple[T]].read(strs) match{
case Left(s) => Left(s)
case Right(s) => Right(Some(s))
}
}
} else {
strs.lastOption match{
case None => Right(None)
case Some(s) => implicitly[TokensReader.Simple[T]].read(Seq(s)) match{
case Left(s) => Left(s)
case Right(s) => Right(Some(s))
}
}
}
}
override def alwaysRepeatable = implicitly[TokensReader.Simple[T]].alwaysRepeatable
override def allowEmpty = true
}

implicit def SeqRead[C[_] <: Iterable[_], T: TokensReader.Simple](implicit
factory: Factory[T, C[T]]
): TokensReader[C[T]] =
): TokensReader.Simple[C[T]] =
new SeqRead[C, T]

class SeqRead[C[_] <: Iterable[_], T: TokensReader.Simple](implicit factory: Factory[T, C[T]])
Expand All @@ -194,7 +205,7 @@ object TokensReader {
override def allowEmpty = true
}

implicit def MapRead[K: TokensReader.Simple, V: TokensReader.Simple]: TokensReader[Map[K, V]] =
implicit def MapRead[K: TokensReader.Simple, V: TokensReader.Simple]: TokensReader.Simple[Map[K, V]] =
new MapRead[K, V]
class MapRead[K: TokensReader.Simple, V: TokensReader.Simple] extends Simple[Map[K, V]] {
def shortName = "k=v"
Expand Down
21 changes: 21 additions & 0 deletions mainargs/test/src/OptionSeqTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ object OptionSeqTests extends TestSuite {

@main
def runInt(int: Int) = int

@main
def runOptionSeq(os: Option[Seq[Int]]) = os
}

val tests = Tests {
Expand All @@ -41,6 +44,24 @@ object OptionSeqTests extends TestSuite {
Seq(123)
}
}

test("option seq") {
test {
ParserForMethods(Main).runOrThrow(Array("runOptionSeq", "--os", "123")) ==>
Some(Seq(123))
}

test {
ParserForMethods(Main).runOrThrow(Array("runOptionSeq", "--os", "123", "--os", "456")) ==>
Some(Seq(123, 456))
}

test {
ParserForMethods(Main).runOrThrow(Array("runOptionSeq")) ==>
None
}
}

test("vec") {
ParserForMethods(Main).runOrThrow(Array("runVec", "--seq", "123", "--seq", "456")) ==>
Vector(123, 456)
Expand Down