'use strict' var utils = require('./utils') var noop = utils.noop var assign = utils.assign var isString = utils.isString function RouteNode (options) { options = options || {} this._children = Object.create(null) this._regExs = Object.create(null) } assign(RouteNode.prototype, { handler: null, add: function add(parts, handler, context) { parts = parts || [] handler = handler || noop context = context || null if (parts.length === 0) { this.handler = handler this.context = context return this } var part = parts.shift() var node = null if (isString(part)) { node = this._children[part] } else { this._regExs[part] = part } if (node == null) { node = new RouteNode() this._children[part] = node } return node.add(parts, handler, context) }, get: function get(parts, args, done) { parts = parts || [] args = args || [] if (parts.length === 0) { return done(null, this.handler, this.context, args) } var part = parts.shift() var childNode = this._children[part] if (childNode) { return childNode.get(parts, args, done) } else { var results = this._getRegexChild(part) if (results && results.node) { return results.node.get(parts, args.concat(results.args), done) } else { return done(new Error('not found')) } } }, _getRegexChild: function _getRegexChild(part) { var childKey = null var args = [] var self = this Object.keys(this._regExs).forEach(function checkRegex(key) { if (childKey) { return } var regex = self._regExs[key] var results = regex.exec(part) var lastIndex = null if (results) { childKey = key } while (results && results.index !== lastIndex) { args = args.concat(results[0]) lastIndex = results.index results = regex.exec(part) } }) if (childKey) { return { args: args, key: childKey, node: this._children[childKey] } } else { return null } } }) module.exports = RouteNode