/// <summary> /// Parses the version expression. /// </summary> public static bool TryParse(string value, out ComposerVersionExpression expression) => TryParse(value.AsSpan(), out expression);
/// <summary> /// Parses the version expression. /// </summary> public static bool TryParse(ReadOnlySpan <char> value, out ComposerVersionExpression expression) { expression = default; value = value.Trim(); // ranges var range = value.IndexOf(Tokens.Range); // regexp if (range > 0) { // A - B if (ComposerVersion.TryParse(value.Slice(0, range), out var fromversion) && ComposerVersion.TryParse(value.Slice(range + Tokens.Range.Length), out var toversion)) { expression = new RangeExpression { From = fromversion, To = toversion, }; return(true); } else { return(false); } } else if (range == 0) { // - B return(false); } // AND, highest precedence var and = Tokens.AndRegex.Match(value.ToString()); if (and.Success) { var cap = and.Groups[1]; if (TryParse(value.Slice(0, cap.Index), out var leftexpr) && TryParse(value.Slice(cap.Index + cap.Length), out var rightexpr)) { expression = new AndExpression { Left = leftexpr, Right = rightexpr, }; return(true); } } // OR var or = value.IndexOf(Tokens.Or); if (or > 0) { // A || B if (TryParse(value.Slice(0, or), out var left) && TryParse(value.Slice(or + Tokens.Or.Length), out var right)) { expression = new OrExpression { Left = left, Right = right, }; return(true); } else { return(false); } } else if (or == 0) { // invalid return(false); } // if (value.IsEmpty) { return(false); } // unary version ranges Operation op; if (value[0] == Tokens.CaretVersion) { op = Operation.CaretVersionRange; value = value.Slice(1); } else if (value[0] == Tokens.TildeVersion) { op = Operation.TildeVersionRange; value = value.Slice(1); } else if (value.StartsWith(Tokens.Lte)) { op = Operation.LessThanOrEqual; value = value.Slice(Tokens.Lte.Length); } else if (value.StartsWith(Tokens.Gte)) { op = Operation.GreaterThanOrEqual; value = value.Slice(Tokens.Gte.Length); } else if (value.StartsWith(Tokens.Ne)) { op = Operation.NotEqual; value = value.Slice(Tokens.Ne.Length); } else if (value[0] == Tokens.Lt) { op = Operation.LessThan; value = value.Slice(1); } else if (value[0] == Tokens.Gt) { op = Operation.GreaterThan; value = value.Slice(1); } else { op = Operation.Exact; } if (ComposerVersion.TryParse(value, out var version)) { if (op == Operation.Exact) { expression = new ExactVersionExpression { Version = version }; } else { expression = new UnaryExpression(op) { Version = version, }; } return(true); } // return(false); }