You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
3.2 KiB
117 lines
3.2 KiB
// Copyright (c) MudBlazor 2021
|
|
// MudBlazor licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Connected;
|
|
|
|
public record struct Block(char MaskChar, int Min = 1, int Max = 1);
|
|
|
|
public class BlockMask : RegexMask
|
|
{
|
|
public BlockMask(params Block[] blocks) : base(null)
|
|
{
|
|
if (blocks.Length == 0)
|
|
throw new ArgumentException("supply at least one block", nameof(blocks));
|
|
Blocks = blocks;
|
|
Delimiters = "";
|
|
}
|
|
|
|
public BlockMask(string delimiters, params Block[] blocks) : this(blocks)
|
|
{
|
|
Delimiters = delimiters ?? "";
|
|
}
|
|
|
|
public Block[] Blocks { get; protected set; }
|
|
|
|
protected override void InitInternals()
|
|
{
|
|
base.InitInternals();
|
|
Blocks ??= new Block[0];
|
|
Mask = BuildRegex(Blocks);
|
|
_regex = new Regex(Mask);
|
|
}
|
|
|
|
protected override void InitRegex()
|
|
{
|
|
// BlockMask inits regex itself (but after base init), no need to do it twice
|
|
// so don't call base init here
|
|
//base.InitRegex();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Build the progressive working regex from the block and delimiter definitions
|
|
/// Note: a progressive regex must match partial input!!!!
|
|
/// </summary>
|
|
/// <param name="blocks"></param>
|
|
/// <returns></returns>
|
|
protected virtual string BuildRegex(Block[] blocks)
|
|
{
|
|
var s = new StringBuilder();
|
|
int i = 0;
|
|
int blockIndex = 0;
|
|
s.Append("^");
|
|
foreach (var b in blocks)
|
|
{
|
|
for (int j = 0; j < b.Min; j++)
|
|
{
|
|
if (i > 0)
|
|
s.Append("(");
|
|
if (_maskDict.TryGetValue(b.MaskChar, out var maskDef))
|
|
s.Append(maskDef.Regex);
|
|
else
|
|
s.Append(Regex.Escape(b.MaskChar.ToString()));
|
|
}
|
|
|
|
i += b.Min;
|
|
if (b.Max > b.Min)
|
|
{
|
|
for (int j = b.Min; j < b.Max; j++)
|
|
{
|
|
s.Append("(");
|
|
if (_maskDict.TryGetValue(b.MaskChar, out var maskDef))
|
|
s.Append(maskDef.Regex);
|
|
else
|
|
s.Append(Regex.Escape(b.MaskChar.ToString()));
|
|
}
|
|
|
|
for (int j = b.Min; j < b.Max; j++)
|
|
s.Append(")?");
|
|
}
|
|
|
|
if (_delimiters.Count > 0 && blockIndex < blocks.Length - 1)
|
|
{
|
|
s.Append("([");
|
|
foreach (var d in _delimiters)
|
|
s.Append(Regex.Escape(d.ToString()));
|
|
s.Append("]");
|
|
i++;
|
|
}
|
|
|
|
blockIndex++;
|
|
}
|
|
|
|
for (int j = 0; j < i - 1; j++)
|
|
s.Append(")?");
|
|
s.Append("$");
|
|
return s.ToString();
|
|
}
|
|
|
|
public override void UpdateFrom(IMask other)
|
|
{
|
|
base.UpdateFrom(other);
|
|
var o = other as BlockMask;
|
|
if (o == null)
|
|
return;
|
|
Blocks = o.Blocks ?? new Block[0];
|
|
Delimiters = o.Delimiters;
|
|
_initialized = false;
|
|
Refresh();
|
|
}
|
|
}
|