mapcomplete/Logic/RegexTag.ts

85 lines
2.6 KiB
TypeScript
Raw Normal View History

2021-03-22 03:05:08 +01:00
import {Tag} from "./Tag";
import {TagsFilter} from "./TagsFilter";
export class RegexTag extends TagsFilter {
private readonly key: RegExp | string;
private readonly value: RegExp | string;
private readonly invert: boolean;
private readonly matchesEmpty: boolean
constructor(key: string | RegExp, value: RegExp | string, invert: boolean = false) {
super();
this.key = key;
this.value = value;
this.invert = invert;
this.matchesEmpty = RegexTag.doesMatch("", this.value);
}
private static doesMatch(fromTag: string, possibleRegex: string | RegExp): boolean {
if (typeof possibleRegex === "string") {
return fromTag === possibleRegex;
}
return fromTag.match(possibleRegex) !== null;
}
private static source(r: string | RegExp) {
if (typeof (r) === "string") {
return r;
}
return r.source;
}
asOverpass(): string[] {
if (typeof this.key === "string") {
return [`['${this.key}'${this.invert ? "!" : ""}~'${RegexTag.source(this.value)}']`];
}
return [`[~'${this.key.source}'${this.invert ? "!" : ""}~'${RegexTag.source(this.value)}']`];
}
isUsableAsAnswer(): boolean {
return false;
}
matchesProperties(tags: any): boolean {
for (const key in tags) {
if (RegexTag.doesMatch(key, this.key)) {
const value = tags[key]
return RegexTag.doesMatch(value, this.value) != this.invert;
}
}
if (this.matchesEmpty) {
// The value is 'empty'
return !this.invert;
}
// The matching key was not found
return this.invert;
}
substituteValues(tags: any): TagsFilter {
return this;
}
asHumanString() {
if (typeof this.key === "string") {
return `${this.key}${this.invert ? "!" : ""}~${RegexTag.source(this.value)}`;
}
return `${this.key.source}${this.invert ? "!" : ""}~~${RegexTag.source(this.value)}`
}
isEquivalent(other: TagsFilter): boolean {
if (other instanceof RegexTag) {
return other.asHumanString() == this.asHumanString();
}
if (other instanceof Tag) {
return RegexTag.doesMatch(other.key, this.key) && RegexTag.doesMatch(other.value, this.value);
}
return false;
}
usedKeys(): string[] {
if (typeof this.key === "string") {
return [this.key];
}
throw "Key cannot be determined as it is a regex"
}
}