1
|
|
|
from collections import Iterable, OrderedDict |
2
|
|
|
import re |
3
|
|
|
from coalib.misc.Constants import Constants |
4
|
|
|
from coalib.parsing.StringProcessing import unescaped_split, unescape |
5
|
|
|
|
6
|
|
|
|
7
|
|
|
class StringConverter: |
8
|
|
|
""" |
9
|
|
|
Converts strings to other things as needed. If you need some kind of string |
10
|
|
|
conversion that is not implemented here, consider adding it so everyone |
11
|
|
|
gets something out of it. |
12
|
|
|
""" |
13
|
|
|
|
14
|
|
|
def __init__(self, |
15
|
|
|
value, |
16
|
|
|
strip_whitespaces=True, |
17
|
|
|
list_delimiters=None, |
18
|
|
|
dict_delimiter=":", |
19
|
|
|
remove_empty_iter_elements=True): |
20
|
|
|
if list_delimiters is None: |
21
|
|
|
list_delimiters = [",", ";"] |
22
|
|
|
|
23
|
|
|
if not isinstance(list_delimiters, Iterable): |
24
|
|
|
raise TypeError("list_delimiters has to be an Iterable.") |
25
|
|
|
if not isinstance(strip_whitespaces, bool): |
26
|
|
|
raise TypeError("strip_whitespaces has to be a bool parameter") |
27
|
|
|
|
28
|
|
|
self.__strip_whitespaces = strip_whitespaces |
29
|
|
|
self.__list_delimiters = list_delimiters |
30
|
|
|
self.__dict_delimiter = dict_delimiter |
31
|
|
|
self.__remove_empty_iter_elements = remove_empty_iter_elements |
32
|
|
|
|
33
|
|
|
self.__escaped_list = None |
34
|
|
|
self.__unescaped_list = None |
35
|
|
|
self.__dict = None |
36
|
|
|
self.value = value |
37
|
|
|
|
38
|
|
|
def __str__(self): |
39
|
|
|
return unescape(self.value) |
40
|
|
|
|
41
|
|
|
def __bool__(self): |
42
|
|
|
if str(self).lower() in Constants.TRUE_STRINGS: |
43
|
|
|
return True |
44
|
|
|
if str(self).lower() in Constants.FALSE_STRINGS: |
45
|
|
|
return False |
46
|
|
|
raise ValueError |
47
|
|
|
|
48
|
|
|
def __len__(self): |
49
|
|
|
return len(str(self)) |
50
|
|
|
|
51
|
|
|
def __int__(self): |
52
|
|
|
return int(str(self)) |
53
|
|
|
|
54
|
|
|
def __float__(self): |
55
|
|
|
return float(str(self)) |
56
|
|
|
|
57
|
|
|
def __iter__(self, remove_backslashes=True): |
58
|
|
|
""" |
59
|
|
|
Converts the value to a list using the delimiters given at construction |
60
|
|
|
time. |
61
|
|
|
|
62
|
|
|
Note that escaped values will be unescaped and escaped list delimiters |
63
|
|
|
will be allowed in values. If you need the escapes you should not |
64
|
|
|
use this routine. |
65
|
|
|
|
66
|
|
|
:param remove_backslashes: Whether or not to remove the backslashes |
67
|
|
|
after conversion. |
68
|
|
|
:return: An iterator over all values. |
69
|
|
|
""" |
70
|
|
|
if remove_backslashes: |
71
|
|
|
return iter(self.__unescaped_list) |
72
|
|
|
else: |
73
|
|
|
return iter(self.__escaped_list) |
74
|
|
|
|
75
|
|
|
def __getitem__(self, item): |
76
|
|
|
return self.__dict.__getitem__(item) |
77
|
|
|
|
78
|
|
|
def keys(self): |
79
|
|
|
return self.__dict.keys() |
80
|
|
|
|
81
|
|
|
def __get_raw_list(self): |
82
|
|
|
pattern = ("(?:" + |
83
|
|
|
"|".join(re.escape(v) for v in self.__list_delimiters) + |
84
|
|
|
")") |
85
|
|
|
|
86
|
|
|
return list(unescaped_split(pattern, |
87
|
|
|
self.value, |
88
|
|
|
use_regex=True)) |
89
|
|
|
|
90
|
|
|
def __prepare_list(self): |
91
|
|
|
self.__escaped_list = self.__get_raw_list() |
92
|
|
|
self.__unescaped_list = [unescape(elem) |
93
|
|
|
for elem in self.__escaped_list] |
94
|
|
|
if self.__strip_whitespaces: |
95
|
|
|
self.__unescaped_list = [elem.strip() |
96
|
|
|
for elem in self.__unescaped_list] |
97
|
|
|
self.__escaped_list = [elem.strip() |
98
|
|
|
for elem in self.__escaped_list] |
99
|
|
|
|
100
|
|
|
if self.__remove_empty_iter_elements: |
101
|
|
|
# Need to do after stripping, cant use builtin functionality of |
102
|
|
|
# split. |
103
|
|
|
while "" in self.__unescaped_list: |
104
|
|
|
self.__unescaped_list.remove("") |
105
|
|
|
while "" in self.__escaped_list: |
106
|
|
|
self.__escaped_list.remove("") |
107
|
|
|
|
108
|
|
|
def __prepare_dict(self): |
109
|
|
|
# We must keep order here, user can drop it later. |
110
|
|
|
self.__dict = OrderedDict() |
111
|
|
|
for elem in self.__get_raw_list(): |
112
|
|
|
key_val = [unescape(item) |
113
|
|
|
for item in unescaped_split(self.__dict_delimiter, |
114
|
|
|
elem, |
115
|
|
|
max_split=1)] |
116
|
|
|
|
117
|
|
|
if self.__strip_whitespaces: |
118
|
|
|
key_val = [item.strip() for item in key_val] |
119
|
|
|
|
120
|
|
|
if not any(item != "" for item in key_val): |
121
|
|
|
continue |
122
|
|
|
|
123
|
|
|
if len(key_val) < 2: |
124
|
|
|
self.__dict[key_val[0]] = "" |
125
|
|
|
else: |
126
|
|
|
self.__dict[key_val[0]] = key_val[1] |
127
|
|
|
|
128
|
|
|
@property |
129
|
|
|
def value(self): |
130
|
|
|
return self.__value |
131
|
|
|
|
132
|
|
|
@value.setter |
133
|
|
|
def value(self, newval): |
134
|
|
|
self.__value = str(newval) |
135
|
|
|
if self.__strip_whitespaces: |
136
|
|
|
self.__value = self.__value.strip() |
137
|
|
|
|
138
|
|
|
self.__prepare_list() |
139
|
|
|
self.__prepare_dict() |
140
|
|
|
|
141
|
|
|
def __eq__(self, other): |
142
|
|
|
return isinstance(other, StringConverter) and self.value == other.value |
143
|
|
|
|
144
|
|
|
def __ne__(self, other): |
145
|
|
|
return not self.__eq__(other) |
146
|
|
|
|