summaryrefslogtreecommitdiff
path: root/cli/source/core/scala/com/rockymadden/stringmetric/cli/OptionMap.scala
blob: ede8a5c4993228ed7def870603ccad1ea4524901 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.rockymadden.stringmetric.cli

import scala.annotation.tailrec

object OptionMap {
	def apply(args: Array[String]): OptionMap = apply(args: _*)

	def apply(varargs: String*): OptionMap = {
		@tailrec
		def next(om: OptionMap, a: List[String]): OptionMap = {
			val double = """^(--[a-zA-Z0-9]+)(\=[a-zA-Z0-9\.\-\_]+)?""".r
			val single = """^(-[a-zA-Z0-9]+)(\=[a-zA-Z0-9\.\-\_]+)?""".r
			val less = """([a-zA-Z0-9\/\-\_\$\.]+)""".r

			a match {
				// Empty, return.
				case Nil => om
				// Double dash options, without value.
				case double(k, null) :: t => next(om + (Symbol(k.tail.tail) -> ""), t)
				// Double dash options, with value.
				case double(k, v) :: t => next(om + (Symbol(k.tail.tail) -> v.tail), t)
				// Single dash options, without value.
				case single(k, null) :: t => next(om + (Symbol(k.tail) -> ""), t)
				// Single dash options, with value. Value is discarded.
				case single(k, v) :: t => next(om + (Symbol(k.tail) -> ""), t)
				// Dashless options.
				case less(v) :: t if v.head != '-' =>
					if (om.contains('dashless)) {
						val dashless = om('dashless) + " " + v.trim

						next((om - 'dashless) + ('dashless -> dashless), t)
					} else next(om + ('dashless -> v.trim), t)
				// Invalid option, ignore.
				case _ :: t => next(om, t)
			}
		}

		next(Map.empty[Symbol, String], varargs.toList)
	}
}