blob: 1377cb63f8747035e9d0d3ef9967e8347c8b840c [file] [log] [blame]
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Casbin.Util
{
internal static class StringUtil
{
private static readonly Regex s_evalRegex = new(@"\beval\((?<rule>[^)]*)\)");
private static readonly Regex s_inOperatorRegex = new(@"([a-zA-Z0-9_.()""]+) in ([a-zA-Z0-9_.()""]+)");
/// <summary>
/// Removes the comments starting with # in the text.
/// </summary>
/// <param name="line">a line in the model.</param>
/// <returns>The line without comments.</returns>
internal static string RemoveComments(this string line)
{
int pos = line.IndexOf("#", StringComparison.Ordinal);
if (pos is -1)
{
return line;
}
return line.Substring(0, pos).Trim();
}
/// <summary>
/// Determines whether matcher contains eval function
/// </summary>
/// <param name="expressString"></param>
/// <returns></returns>
internal static bool HasEval(string expressString)
{
return s_evalRegex.IsMatch(expressString);
}
/// <summary>
/// Tries get rule names of eval function
/// </summary>
/// <param name="expressString"></param>
/// <param name="evalRuleNames"></param>
/// <returns></returns>
internal static bool TryGetEvalRuleNames(string expressString, out IEnumerable<string> evalRuleNames)
{
MatchCollection matches = s_evalRegex.Matches(expressString);
int matchCount = matches.Count;
if (matchCount is 0)
{
evalRuleNames = null;
return false;
}
string[] rules = new string[matchCount];
for (int i = 0; i < matchCount; i++)
{
GroupCollection group = matches[i].Groups;
if (group.Count < 2)
{
evalRuleNames = null;
return false;
}
rules[i] = group[1].Value;
}
evalRuleNames = rules;
return true;
}
/// <summary>
/// Replace eval function with the value of its eval rule
/// </summary>
/// <param name="expressStringWithEvalRule"></param>
/// <param name="rules"></param>
/// <returns></returns>
internal static string ReplaceEval(string expressStringWithEvalRule, IDictionary<string, string> rules)
{
if (rules is null)
{
return expressStringWithEvalRule;
}
return s_evalRegex.Replace(expressStringWithEvalRule, match =>
{
GroupCollection matchGroups = match.Groups;
int subMatchCount = matchGroups.Count - 1;
if (subMatchCount is 0 || rules.TryGetValue(
matchGroups[1].Value, out string rule) is false)
{
return match.Value;
}
return rule;
});
}
/// <summary>
/// Replace in operator with function "Contains".
/// </summary>
/// <param name="expressString"></param>
/// <returns></returns>
internal static string ReplaceInOperator(string expressString)
{
var res = s_inOperatorRegex.Replace(expressString, match =>
{
GroupCollection matchGroups = match.Groups;
int subMatchCount = matchGroups.Count - 1;
if(subMatchCount == 2)
{
return matchGroups[2].Value + ".Contains(" + matchGroups[1].Value + ")";
}
return matchGroups[0].Value;
});
return res;
}
}
}