-
Notifications
You must be signed in to change notification settings - Fork 4
/
RuleParser.scala
45 lines (40 loc) · 2.16 KB
/
RuleParser.scala
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
41
42
43
44
45
package com.gilt.thehand
import com.gilt.thehand.rules.logical._
import com.gilt.thehand.rules.typed._
import com.gilt.thehand.exceptions.CannotDeserializeException
/**
* Implement this trait when defining a new RuleParser. The parser should take the serialized string version of the
* rule and deserialize it into the rule itself.
*/
trait AbstractRuleParser {
/**
* Implement this to provide an extractor that pulls the Rule out of the String.
* @param deserializeFrom The String that should be parsed into a Rule.
* @return None if the string cannot be parsed; Some(rule) if the string can be parsed.
*/
def unapply(deserializeFrom: String): Option[Rule]
/**
* A convenience method for times when using the extractor is too heavy.
* @param deserializeFrom The String that should be parsed into a Rule.
* @return The Rule that had been serialized; this method will throw a CannotDeserializeException if it is unable
* to deserialize the string into a rule based on the current parser.
*/
def fromString(deserializeFrom: String): Rule = unapply(deserializeFrom).getOrElse(throw CannotDeserializeException("Unable to deserialize [%s]".format(deserializeFrom)))
}
/**
* Use this to create a parsing object that incorporates the specific parsers that your application uses. It also
* includes parsers for the "default" list of parsers (True, False, And, Or, etc); simply instantiating an object
* without any arguments will give you a parser that can parse only those defaults.
*
* @param ruleParsers: A list of parsing objects that will be used to parse strings.
*/
case class RuleParser(ruleParsers: AbstractRuleParser*) extends AbstractRuleParser {
lazy val defaultParsers = Seq(
True, False, NotParser(this), AndParser(this), OrParser(this),
StringEqParser, StringInParser, StringLtParser, StringGtParser, StringLteParser, StringGteParser,
LongEqParser, LongInParser, LongLtParser, LongGtParser, LongLteParser, LongGteParser
)
def unapply(deserializeFrom: String): Option[Rule] = (ruleParsers ++ defaultParsers).foldLeft(Option.empty[Rule])((result, currentParser) =>
result orElse currentParser.unapply(deserializeFrom)
)
}