aboutsummaryrefslogtreecommitdiff
path: root/resources/assets/javascripts/lib/parse_options.js
blob: 1001d8aebdee51f03a53b61becdf09b6f261dada (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/**
 * Parses a given string "option1;option2=value;option3=42;option4=false"
 * into the following structure:
 *
 * {option1: true, option2: "value", option3: 42, option4: false}
 */
function parseOptions(string) {
    const options = {};
    let index = '';
    let value = '';
    let inval = false;
    let escaped = 0;
    let inquotes = false;
    const l = string.length;
    let token;
    let write;
    let skip;
    for (let i = 0; i < l; i += 1) {
        token = string[i];
        write = false;
        skip = false;
        if (inval && token === '\\' && escaped <= 0) {
            escaped = 2;
        } else if (!inval && token === '=') {
            inval = true;
            skip = true;
        } else if (inval && value.length === 0 && (token === '"' || token === "'")) {
            inquotes = token;
        } else if (inval && inquotes && escaped <= 0 && token === inquotes) {
            inquotes = false;
        } else if (!inquotes && token === ';') {
            write = true;
            skip = true;
        }
        if (!skip && escaped <= 0) {
            if (inval) {
                value += token;
            } else {
                index += token;
            }
        }
        escaped -= 1;

        if (write || i === string.length - 1) {
            if (i === string.length - 1 && inquotes) {
                throw 'Invalid data, missing closing quote';
            }
            if (index.trim().length > 0) {
                options[index.trim()] = inval ? parseValue(value) : true;
            }
            inval = false;
            inquotes = false;
            index = '';
            value = '';
        }
    }

    return options;
}

/**
 * Tries to parse a given string into it's appropriate type.
 * Supports boolean, int and float.
 */
function parseValue(value) {
    if (value.toLowerCase() === 'true') {
        return true;
    }
    if (value.toLowerCase() === 'false') {
        return false;
    }
    if (/^[+-]\d+$/.test(value)) {
        return parseInt(value, 10);
    }
    if (/^[+-]\d+\.\d+$/.test(value)) {
        return parseFloat(value, 10);
    }
    return value.replace(/^(["'])(.*)\1$/, '$2');
}

export default parseOptions;