1"""
2    pyexcel.formatters
3    ~~~~~~~~~~~~~~~~~~~
4
5    These utilities help format the content
6
7    :copyright: (c) 2014-2019 by Onni Software Ltd.
8    :license: New BSD License, see LICENSE for more details
9"""
10import json
11import datetime
12from decimal import Decimal
13
14from pyexcel import constants as constants
15from pyexcel._compact import PY2
16
17
18def string_to_format(value, target_format):
19    """Convert string to specified format"""
20    if target_format == float:
21        try:
22            ret = float(value)
23        except ValueError:
24            ret = value
25    elif target_format == int:
26        try:
27            ret = float(value)
28            ret = int(ret)
29        except ValueError:
30            ret = value
31    else:
32        ret = value
33
34    return ret
35
36
37def float_to_format(value, target_format):
38    """Convert float to specified format"""
39    if target_format == int:
40        ret = int(value)
41    elif target_format == str:
42        ret = str(value)
43    else:
44        ret = value
45
46    return ret
47
48
49def int_to_format(value, target_format):
50    """Convert int to specified format"""
51    if target_format == float:
52        ret = float(value)
53    elif target_format == str:
54        ret = str(value)
55    else:
56        ret = value
57    return ret
58
59
60def date_to_format(value, target_format):
61    """Convert date to specified format"""
62    if target_format == str:
63        if isinstance(value, datetime.date):
64            ret = value.strftime("%d/%m/%y")
65        elif isinstance(value, datetime.datetime):
66            ret = value.strftime("%d/%m/%y")
67        elif isinstance(value, datetime.time):
68            ret = value.strftime("%H:%M:%S")
69    else:
70        ret = value
71    return ret
72
73
74def boolean_to_format(value, target_format):
75    """Convert bool to specified format"""
76    if target_format == float:
77        ret = float(value)
78    elif target_format == str:
79        if value == 1:
80            ret = "true"
81        else:
82            ret = "false"
83    else:
84        ret = value
85    return ret
86
87
88def empty_to_format(_, target_format):
89    """Convert empty value to specified format"""
90    if target_format == float:
91        ret = 0.0
92    elif target_format == int:
93        ret = 0
94    else:
95        ret = constants.DEFAULT_NA
96    return ret
97
98
99CONVERSION_FUNCTIONS = {
100    str: string_to_format,
101    float: float_to_format,
102    int: int_to_format,
103    datetime.datetime: date_to_format,
104    datetime.time: date_to_format,
105    datetime.date: date_to_format,
106    bool: boolean_to_format,
107    None: empty_to_format,
108    Decimal: float_to_format,
109}
110
111if PY2:
112    CONVERSION_FUNCTIONS[unicode] = string_to_format
113    CONVERSION_FUNCTIONS[long] = float_to_format
114
115
116def default_formatter(value, to_type):
117    return json.dumps(value)
118
119
120def to_format(to_type, value):
121    """Wrapper utility function for format different formats
122
123    :param type from_type: a python type
124    :param type to_type: a python type
125    :param value value: a python value
126    """
127    if value is not None:
128        if value == "":
129            from_type = None
130        else:
131            from_type = type(value)
132    else:
133        from_type = None
134    func = CONVERSION_FUNCTIONS.get(from_type, default_formatter)
135    return func(value, to_type)
136