[new] range和size都支持固定大小或者区间段 xxx=value 或 xxx=[a,b] 的写法

main
walon 2022-07-19 12:58:02 +08:00
parent 665b9a4cea
commit 699b5a167a
4 changed files with 168 additions and 134 deletions

View File

@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.Validators
{
internal class Range
{
private readonly string _str;
private long? _min;
private long? _max;
private double? _mind;
private double? _maxd;
private bool _includeMinBound;
private bool _includeMaxBound;
public Range(string strRange)
{
_str = strRange.Trim();
}
public string RawStr => _str;
private bool TryParse(string s, ref long? x)
{
s = s.Trim();
if (string.IsNullOrEmpty(s))
{
x = null;
return true;
}
else if (long.TryParse(s, out var v))
{
x = v;
return true;
}
else
{
return false;
}
}
private bool TryParse(string s, ref double? x)
{
s = s.Trim();
if (string.IsNullOrEmpty(s))
{
x = null;
return true;
}
else if (double.TryParse(s, out var v))
{
x = v;
return true;
}
else
{
return false;
}
}
public void Compile()
{
void ThrowError()
{
throw new Exception($"range定义不合法");
}
if (long.TryParse(_str, out long value))
{
// size=xxxx
_min = _max = value;
_mind = _maxd = value;
_includeMinBound = _includeMaxBound = true;
return;
}
if (_str.Length <= 2)
{
ThrowError();
}
switch (_str[0])
{
case '[': _includeMinBound = true; break;
case '(': _includeMinBound = false; break;
default: ThrowError(); break;
}
switch (_str[^1])
{
case ']': _includeMaxBound = true; break;
case ')': _includeMaxBound = false; break;
default: ThrowError(); break;
}
var pars = _str[1..^1].Split(',');
if (pars.Length != 2)
{
ThrowError();
}
bool p1 = TryParse(pars[0], ref _min);
bool p2 = TryParse(pars[0], ref _mind);
bool p3 = TryParse(pars[1], ref _max);
bool p4 = TryParse(pars[1], ref _maxd);
if ((!p1 && !p2) || (!p3 && !p4))
{
ThrowError();
}
}
public bool CheckInLongRange(long x)
{
if (_min is long m && (_includeMinBound ? m > x : m >= x))
{
return false;
}
if (_max is long n && (_includeMaxBound ? n < x : n <= x))
{
return false;
}
return true;
}
public bool CheckInDoubleRange(double x)
{
if (_mind is double m && (_includeMinBound ? m > x : m >= x))
{
return false;
}
if (_maxd is double n && (_includeMaxBound ? n < x : n <= x))
{
return false;
}
return true;
}
}
}

View File

@ -11,128 +11,17 @@ namespace Luban.Job.Cfg.Validators
{ {
public TType Type { get; } public TType Type { get; }
private readonly string _str; private Range _range;
private long? _min;
private long? _max;
private double? _mind;
private double? _maxd;
private bool _includeMinBound;
private bool _includeMaxBound;
public RangeValidator(TType type, string strRange) public RangeValidator(TType type, string strRange)
{ {
Type = type; Type = type;
_str = strRange.Trim(); _range = new Range(strRange);
}
private bool TryParse(string s, ref long? x)
{
s = s.Trim();
if (string.IsNullOrEmpty(s))
{
x = null;
return true;
}
else if (long.TryParse(s, out var v))
{
x = v;
return true;
}
else
{
return false;
}
}
private bool TryParse(string s, ref double? x)
{
s = s.Trim();
if (string.IsNullOrEmpty(s))
{
x = null;
return true;
}
else if (double.TryParse(s, out var v))
{
x = v;
return true;
}
else
{
return false;
}
} }
public void Compile(DefFieldBase def) public void Compile(DefFieldBase def)
{ {
void ThrowError() _range.Compile();
{
throw new Exception($"结构:{ def.HostType.FullName } 字段: { def.Name} range 定义:{_str} 不合法");
}
if (_str.Length <= 2)
{
ThrowError();
}
switch (_str[0])
{
case '[': _includeMinBound = true; break;
case '(': _includeMinBound = false; break;
default: ThrowError(); break;
}
switch (_str[^1])
{
case ']': _includeMaxBound = true; break;
case ')': _includeMaxBound = false; break;
default: ThrowError(); break;
}
var pars = _str[1..^1].Split(',');
if (pars.Length != 2)
{
ThrowError();
}
bool p1 = TryParse(pars[0], ref _min);
bool p2 = TryParse(pars[0], ref _mind);
bool p3 = TryParse(pars[1], ref _max);
bool p4 = TryParse(pars[1], ref _maxd);
if ((!p1 && !p2) || (!p3 && !p4))
{
ThrowError();
}
}
private bool CheckInLongRange(long x)
{
if (_min is long m && (_includeMinBound ? m > x : m >= x))
{
return false;
}
if (_max is long n && (_includeMaxBound ? n < x : n <= x))
{
return false;
}
return true;
}
private bool CheckInDoubleRange(double x)
{
if (_mind is double m && (_includeMinBound ? m > x : m >= x))
{
return false;
}
if (_maxd is double n && (_includeMaxBound ? n < x : n <= x))
{
return false;
}
return true;
} }
public string Source => ValidatorContext.CurrentVisitor.CurrentValidateRecord.Source; public string Source => ValidatorContext.CurrentVisitor.CurrentValidateRecord.Source;
@ -142,7 +31,7 @@ namespace Luban.Job.Cfg.Validators
var assembly = ctx.Assembly; var assembly = ctx.Assembly;
void LogError() void LogError()
{ {
assembly.Agent.Error("记录 {0}:{1} (来自文件:{2}) 不在范围:{3}内", ValidatorContext.CurrentRecordPath, data, Source, _str); assembly.Agent.Error("记录 {0}:{1} (来自文件:{2}) 不在范围:{3}内", ValidatorContext.CurrentRecordPath, data, Source, _range.RawStr);
} }
if (type.IsNullable && data == null) if (type.IsNullable && data == null)
@ -154,7 +43,7 @@ namespace Luban.Job.Cfg.Validators
{ {
case DByte b: case DByte b:
{ {
if (!CheckInLongRange(b.Value)) if (!_range.CheckInLongRange(b.Value))
{ {
LogError(); LogError();
return; return;
@ -163,7 +52,7 @@ namespace Luban.Job.Cfg.Validators
} }
case DFshort s: case DFshort s:
{ {
if (!CheckInLongRange(s.Value)) if (!_range.CheckInLongRange(s.Value))
{ {
LogError(); LogError();
return; return;
@ -172,7 +61,7 @@ namespace Luban.Job.Cfg.Validators
} }
case DShort s: case DShort s:
{ {
if (!CheckInLongRange(s.Value)) if (!_range.CheckInLongRange(s.Value))
{ {
LogError(); LogError();
return; return;
@ -181,7 +70,7 @@ namespace Luban.Job.Cfg.Validators
} }
case DInt i: case DInt i:
{ {
if (!CheckInLongRange(i.Value)) if (!_range.CheckInLongRange(i.Value))
{ {
LogError(); LogError();
return; return;
@ -190,7 +79,7 @@ namespace Luban.Job.Cfg.Validators
} }
case DFint i: case DFint i:
{ {
if (!CheckInLongRange(i.Value)) if (!_range.CheckInLongRange(i.Value))
{ {
LogError(); LogError();
return; return;
@ -199,7 +88,7 @@ namespace Luban.Job.Cfg.Validators
} }
case DLong l: case DLong l:
{ {
if (!CheckInLongRange(l.Value)) if (!_range.CheckInLongRange(l.Value))
{ {
LogError(); LogError();
return; return;
@ -208,7 +97,7 @@ namespace Luban.Job.Cfg.Validators
} }
case DFlong fl: case DFlong fl:
{ {
if (!CheckInLongRange(fl.Value)) if (!_range.CheckInLongRange(fl.Value))
{ {
LogError(); LogError();
return; return;
@ -217,7 +106,7 @@ namespace Luban.Job.Cfg.Validators
} }
case DFloat ff: case DFloat ff:
{ {
if (!CheckInDoubleRange(ff.Value)) if (!_range.CheckInDoubleRange(ff.Value))
{ {
LogError(); LogError();
return; return;
@ -226,7 +115,7 @@ namespace Luban.Job.Cfg.Validators
} }
case DDouble dd: case DDouble dd:
{ {
if (!CheckInDoubleRange(dd.Value)) if (!_range.CheckInDoubleRange(dd.Value))
{ {
LogError(); LogError();
return; return;

View File

@ -12,16 +12,16 @@ namespace Luban.Job.Cfg.Validators
[Validator("size")] [Validator("size")]
internal class SizeValidator : IValidator internal class SizeValidator : IValidator
{ {
private readonly int _size; private Range _range;
public SizeValidator(TType type, string rule) public SizeValidator(TType type, string rule)
{ {
this._size = int.Parse(rule); _range = new Range(rule);
} }
public void Compile(DefFieldBase def) public void Compile(DefFieldBase def)
{ {
_range.Compile();
} }
private static string Source => ValidatorContext.CurrentVisitor.CurrentValidateRecord.Source; private static string Source => ValidatorContext.CurrentVisitor.CurrentValidateRecord.Source;
@ -31,7 +31,7 @@ namespace Luban.Job.Cfg.Validators
var assembly = ctx.Assembly; var assembly = ctx.Assembly;
void LogError(int size) void LogError(int size)
{ {
assembly.Agent.Error("记录 {0}:{1} (来自文件:{2}) size:{3},但要求为 {4} ", ValidatorContext.CurrentRecordPath, data, Source, size, _size); assembly.Agent.Error("记录 {0}:{1} (来自文件:{2}) size:{3},但要求为 {4} ", ValidatorContext.CurrentRecordPath, data, Source, size, _range.RawStr);
} }
if (type.IsNullable && data == null) if (type.IsNullable && data == null)
@ -43,7 +43,7 @@ namespace Luban.Job.Cfg.Validators
{ {
case DArray b: case DArray b:
{ {
if (b.Datas.Count != _size) if (!_range.CheckInLongRange(b.Datas.Count))
{ {
LogError(b.Datas.Count); LogError(b.Datas.Count);
return; return;
@ -52,7 +52,7 @@ namespace Luban.Job.Cfg.Validators
} }
case DList b: case DList b:
{ {
if (b.Datas.Count != _size) if (!_range.CheckInLongRange(b.Datas.Count))
{ {
LogError(b.Datas.Count); LogError(b.Datas.Count);
return; return;
@ -61,7 +61,7 @@ namespace Luban.Job.Cfg.Validators
} }
case DSet b: case DSet b:
{ {
if (b.Datas.Count != _size) if (!_range.CheckInLongRange(b.Datas.Count))
{ {
LogError(b.Datas.Count); LogError(b.Datas.Count);
return; return;
@ -70,7 +70,7 @@ namespace Luban.Job.Cfg.Validators
} }
case DMap b: case DMap b:
{ {
if (b.Datas.Count != _size) if (!_range.CheckInLongRange(b.Datas.Count))
{ {
LogError(b.Datas.Count); LogError(b.Datas.Count);
return; return;

View File

@ -81,7 +81,7 @@ namespace Luban.Job.Common.Utils
{ {
++braceDepth; ++braceDepth;
} }
else if (c == ')' || c == ')' || c == '}') else if (c == ')' || c == ']' || c == '}')
{ {
--braceDepth; --braceDepth;
} }
@ -119,7 +119,7 @@ namespace Luban.Job.Common.Utils
{ {
++braceDepth; ++braceDepth;
} }
else if (c == ')' || c == ')' || c == '}') else if (c == ')' || c == ']' || c == '}')
{ {
--braceDepth; --braceDepth;
} }