internal static Route MatchAndBindParameters(this Route inner, IReadOnlyList <PathMatcher> pathMatchers) { return(context => { if (pathMatchers.Count > context.Unmatched.Count) { return context.Reject(); } var matches = new List <MatchResult>(); // Use a for loop so we can return a rejection early if there is no match for (var i = 0; i < pathMatchers.Count; i++) { var matchResult = pathMatchers[i](context.Unmatched[i]); if (!matchResult.IsMatched) { return context.Reject(); } matches.Add(matchResult); } var unmatched = new FalcorPath(context.Unmatched.Skip(pathMatchers.Count)); var parameters = new DynamicDictionary(); matches.Where(m => m.HasValue && m.HasValue).ToList().ForEach(m => parameters.Add(m.Name, m.Value)); return inner(context.WithUnmatched(unmatched, parameters)) // Only allow partial matches if we have a ref in the results .Select( result => result.IsComplete && result.UnmatchedPath.Any() && !result.Values.Any(pv => pv.Value is Ref) ? RouteResult.Reject($"Unhandled key segments: {result.UnmatchedPath}") : result); }); }
public IObservable <RouteResult> Complete(FalcorPath unmatched, params PathValue[] values) => Observable.Return(RouteResult.Complete(unmatched, values));
public IObservable <RouteResult> Reject(string error = null) => Observable.Return(RouteResult.Reject(error));