85 lines
No EOL
2.6 KiB
TypeScript
85 lines
No EOL
2.6 KiB
TypeScript
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"
|
|
}
|
|
} |