"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
const escape_regexp_1 = __importDefault(require("./escape_regexp"));
const rParam = /([:*])([\w?]*)?/g;
class Pattern {
    constructor(rule) {
        if (rule instanceof Pattern) {
            return rule;
        }
        else if (typeof rule === 'function') {
            this.match = rule;
        }
        else if (rule instanceof RegExp) {
            this.match = regexFilter(rule);
        }
        else if (typeof rule === 'string') {
            this.match = stringFilter(rule);
        }
        else {
            throw new TypeError('rule must be a function, a string or a regular expression.');
        }
    }
    test(str) {
        return Boolean(this.match(str));
    }
}
function regexFilter(rule) {
    return (str) => str.match(rule);
}
function stringFilter(rule) {
    const params = [];
    const regex = (0, escape_regexp_1.default)(rule)
        .replace(/\\([*?])/g, '$1')
        .replace(rParam, (match, operator, name) => {
        let str = '';
        if (operator === '*') {
            str = '(.*)?';
        }
        else {
            str = '([^\\/]+)';
        }
        if (name) {
            if (name[name.length - 1] === '?') {
                name = name.slice(0, name.length - 1);
                str += '?';
            }
            params.push(name);
        }
        return str;
    });
    return (str) => {
        const match = str.match(regex);
        if (!match)
            return;
        const result = {};
        for (let i = 0, len = match.length; i < len; i++) {
            const name = params[i - 1];
            result[i] = match[i];
            if (name)
                result[name] = match[i];
        }
        return result;
    };
}
module.exports = Pattern;
//# sourceMappingURL=pattern.js.map