Skip to content

Commit

Permalink
Fix #138: Interpret scopes as rules
Browse files Browse the repository at this point in the history
The rule compilation code has been refactored to be reused for both
scopes and rules.
  • Loading branch information
arteymix committed Jan 9, 2016
1 parent 301e805 commit dd760bb
Showing 1 changed file with 43 additions and 23 deletions.
66 changes: 43 additions & 23 deletions src/valum-router.vala
Original file line number Diff line number Diff line change
Expand Up @@ -171,34 +171,23 @@ namespace Valum {
}

/**
* Create a Route for a given callback from a rule.
*
* Rule are scoped from the {@link Router.scope} fragment stack and
* compiled down to {@link GLib.Regex}.
*
* Rule start matching after the first '/' character of the request URI
* path.
* Compile a rule into a regular expression.
*
* @since 0.3
* Parameters are compiled down to named captures and any other
* character goes through {@link Regex.escape_string}.
*
* @param method method matching this rule
* @param rule rule or 'null' to capture all possible paths
* @param cb handling callback
* The compilation process is contextualized for this {@link Valum.Router}
* to honor its defined types.
*
* @throws RegexError if the rule is incorrectly formed or a type is
* undefined in the 'types' mapping
* @since 0.3
*
* @return a builder upon the created {@link Route} object
* @param rule the rule to compile down to regular expression
* @return a regular expression pattern
*/
public Builder rule (string method, string? rule, owned HandlerCallback cb) throws RegexError {
var params = /(<(?:\w+:)?\w+>)/.split_full (rule == null ? "" : rule);
public string compile_rule (string rule) throws RegexError {
var @params = /(<(?:\w+:)?\w+>)/.split_full (rule);
var pattern = new StringBuilder ();

// catch-all null rule
if (rule == null) {
pattern.append ("(?<path>.*)");
}

foreach (var p in @params) {
if (p[0] != '<') {
// regular piece of route
Expand All @@ -216,7 +205,38 @@ namespace Valum {
}
}

return this.regex (method, new Regex (pattern.str), (owned) cb);
return pattern.str;
}

/**
* Create a Route for a given callback from a rule.
*
* Rule are scoped from the {@link Router.scope} fragment stack and
* compiled down to {@link GLib.Regex}.
*
* The 'null' rule is a special rule that captures anything '.*'.
*
* Rule start matching after the first '/' character of the request URI
* path.
*
* @since 0.3
*
* @param method method matching this rule
* @param rule rule or 'null' to capture all possible paths
* @param cb handling callback
*
* @throws RegexError if the rule is incorrectly formed or a type is
* undefined in the 'types' mapping
*
* @return a builder upon the created {@link Route} object
*/
public Builder rule (string method, string? rule, owned HandlerCallback cb) throws RegexError {
// catch-all null rule
if (rule == null) {
return this.regex (method, /(?<path>.*)/, (owned) cb);
} else {
return this.regex (method, new Regex (compile_rule (rule)), (owned) cb);
}
}

/**
Expand Down Expand Up @@ -246,7 +266,7 @@ namespace Valum {

// scope the route
foreach (var scope in this.scopes.head) {
pattern.append (Regex.escape_string ("%s/".printf (scope)));
pattern.append_printf ("%s/", compile_rule (scope));
}

pattern.append (regex.get_pattern ());
Expand Down

0 comments on commit dd760bb

Please sign in to comment.