forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			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"
 | 
						|
    }
 | 
						|
} |