81 lines
1.8 KiB
Python
81 lines
1.8 KiB
Python
# vim:fileencoding=utf-8:noet
|
|
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
|
|
|
import json
|
|
|
|
from powerline.lib.dict import REMOVE_THIS_KEY
|
|
|
|
|
|
def parse_value(s):
|
|
'''Convert string to Python object
|
|
|
|
Rules:
|
|
|
|
* Empty string means that corresponding key should be removed from the
|
|
dictionary.
|
|
* Strings that start with a minus, digit or with some character that starts
|
|
JSON collection or string object are parsed as JSON.
|
|
* JSON special values ``null``, ``true``, ``false`` (case matters) are
|
|
parsed as JSON.
|
|
* All other values are considered to be raw strings.
|
|
|
|
:param str s: Parsed string.
|
|
|
|
:return: Python object.
|
|
'''
|
|
if not s:
|
|
return REMOVE_THIS_KEY
|
|
elif s[0] in '"{[0123456789-' or s in ('null', 'true', 'false'):
|
|
return json.loads(s)
|
|
else:
|
|
return s
|
|
|
|
|
|
def keyvaluesplit(s):
|
|
'''Split K1.K2=VAL into K1.K2 and parsed VAL
|
|
'''
|
|
if '=' not in s:
|
|
raise TypeError('Option must look like option=json_value')
|
|
if s[0] == '_':
|
|
raise ValueError('Option names must not start with `_\'')
|
|
idx = s.index('=')
|
|
o = s[:idx]
|
|
val = parse_value(s[idx + 1:])
|
|
return (o, val)
|
|
|
|
|
|
def parsedotval(s):
|
|
'''Parse K1.K2=VAL into {"K1":{"K2":VAL}}
|
|
|
|
``VAL`` is processed according to rules defined in :py:func:`parse_value`.
|
|
'''
|
|
if type(s) is tuple:
|
|
o, val = s
|
|
val = parse_value(val)
|
|
else:
|
|
o, val = keyvaluesplit(s)
|
|
|
|
keys = o.split('.')
|
|
if len(keys) > 1:
|
|
r = (keys[0], {})
|
|
rcur = r[1]
|
|
for key in keys[1:-1]:
|
|
rcur[key] = {}
|
|
rcur = rcur[key]
|
|
rcur[keys[-1]] = val
|
|
return r
|
|
else:
|
|
return (o, val)
|
|
|
|
|
|
def parse_override_var(s):
|
|
'''Parse a semicolon-separated list of strings into a sequence of values
|
|
|
|
Emits the same items in sequence as :py:func:`parsedotval` does.
|
|
'''
|
|
return (
|
|
parsedotval(item)
|
|
for item in s.split(';')
|
|
if item
|
|
)
|