Skip to content

Instantly share code, notes, and snippets.

@MiguelCastillo
Last active August 29, 2015 14:23
Show Gist options
  • Select an option

  • Save MiguelCastillo/9932574f4c9340a3e38e to your computer and use it in GitHub Desktop.

Select an option

Save MiguelCastillo/9932574f4c9340a3e38e to your computer and use it in GitHub Desktop.
/**
* RuleMatcher is a helper class to define groups of rules. It provides methods
* to execute a particular criteria against one rule, a set of rules, or all
* rules.
*
* @class
*/
function RuleMatcher(config) {
if (!(this instanceof RuleMatcher)) {
return new RuleMatcher(config);
}
this._rules = {};
if (config) {
this.add(config);
}
}
/**
* Helper method to configure rules. This method normalizes the different
* types of inputs allowed to create and configure rules.
*
* @param {object|string|Array} ruleConfig - Option settings used for creating
* and configuring rules.
*
* @rerturns {object} Rule configuration
*/
RuleMatcher.configureRule = function(ruleConfig) {
if (typeof ruleConfig === "string") {
ruleConfig = {
name: ruleConfig
};
}
else if (ruleConfig instanceof Array) {
ruleConfig = {
match: ruleConfig
};
}
return ruleConfig;
};
/**
* Adds a new rule or ammends an already existing rule with the new settings.
*
* @param {object|string|Array} ruleConfig - Option settings used for creating
* and configuring rules.
*
* @returns {Rule} Rule created or ammended
*/
RuleMatcher.prototype.add = function(ruleConfig) {
ruleConfig = RuleMatcher.configureRule(ruleConfig);
var rule = this.find(ruleConfig.name);
if (rule) {
rule.addMatch(ruleConfig.match);
}
else {
rule = new Rule(ruleConfig);
this._rules[rule.getName()] = rule;
}
return rule;
};
/**
* Method to get all available rules
*
* @returns {object} Map of all configured rules
*/
RuleMatcher.prototype.all = function() {
return this._rules;
};
/**
* Method to find and return a rule with the particular name.
*
* @param {string} ruleName - Name of the rule to get.
*
* @returns {Rule} Instance of the rule with the given name. Or undefined if
* no rule exists with the particular name.
*/
RuleMatcher.prototype.find = function(ruleName) {
return this._rules[ruleName];
};
/**
* Method to get a list of rules with the given names.
*
* @param {Array.<string>} ruleNames - Array rules names to get from the list
* of all rules.
*
* @returns {object} Map of all rules with the given names.
*/
RuleMatcher.prototype.filter = function(ruleNames) {
var rules = {};
var i, length;
for (i = 0, length = ruleNames.length; i < length; i++) {
if (this.hasRule(ruleNames[name])) {
rules[name] = this.find(name);
}
}
return rules;
};
/**
* Gets the current number of rules.
*
* @returns {number}
*/
RuleMatcher.prototype.getLength = function() {
return Object.keys(this._rules).length;
};
RuleMatcher.prototype.match = function(criteria, ruleNames) {
return typeof ruleNames === "string" ?
this.matchOne(criteria, ruleNames) :
this.matchAny(criteria, ruleNames);
};
RuleMatcher.prototype.matchOne = function(criteria, ruleName) {
// Make sure the rule exists
if (!this.hasRule(ruleName)) {
return false;
}
var rule = this.find(ruleName);
return rule && rule.matchOne(criteria);
};
RuleMatcher.prototype.matchAny = function(criteria, ruleNames) {
var rules = ruleNames ? this.filter(ruleNames) : this._rules;
for (var ruleName in rules) {
if (rules[ruleName] && rules[ruleName].matchOne(criteria)) {
return true;
}
}
return false;
};
RuleMatcher.prototype.matchAll = function(criteria, ruleNames) {
var rules = ruleNames ? this.filter(ruleNames) : this._rules;
for (var ruleName in rules) {
if (rules[ruleName] && !rules[ruleName].matchOne(criteria)) {
return false;
}
}
return true;
};
RuleMatcher.prototype.hasRule = function(ruleName) {
return this._rules.hasOwnProperty(ruleName);
};
RuleMatcher.Rule = Rule;
RuleMatcher.matcher = matcher;
module.exports = RuleMatcher;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment