private static Criterium fromPathTuples(IEnumerable<Tuple<string, string>> path, string value)
{
var first = path.First();
var name = first.Item1;
var modifier = first.Item2;
var type = Operator.EQ;
Expression operand = null;
// If this is a chained search, unfold the chain first
if (path.Count() > 1)
{
type = Operator.CHAIN;
operand = fromPathTuples(path.Skip(1), value);
}
// :missing modifier is actually not a real modifier and is turned into
// either a ISNULL or NOTNULL operator
else if (modifier == MISSINGMODIF)
{
modifier = null;
if (value == MISSINGTRUE)
type = Operator.ISNULL;
else if (value == MISSINGFALSE)
type = Operator.NOTNULL;
else
throw Error.Argument("value", "For the :missing modifier, only values 'true' and 'false' are allowed");
operand = null;
}
// else see if the value starts with a comparator
else
{
var compVal = findComparator(value);
type = compVal.Item1;
value = compVal.Item2;
if (value == null) throw new FormatException("Value is empty");
// Parse the value. If there's > 1, we are using the IN operator, unless
// the input already specifies another comparison, which would be illegal
var values = ChoiceValue.Parse(value);
if (values.Choices.Length > 1)
{
if (type != Operator.EQ)
throw new InvalidOperationException("Multiple values cannot be used in combination with a comparison operator");
type = Operator.IN;
operand = values;
}
else
{
// Not really a multi value, just a single ValueExpression
operand = values.Choices[0];
}
}
// Construct the new criterium based on the parsed values
return new Criterium()
{
ParamName = name,
Type = type,
Modifier = modifier,
Operand = operand
};
}