1# coding: utf-8
2
3from __future__ import print_function, absolute_import, division, unicode_literals
4
5from .compat import no_limit_int  # NOQA
6from ruamel.yaml.anchor import Anchor
7
8if False:  # MYPY
9    from typing import Text, Any, Dict, List  # NOQA
10
11__all__ = ['ScalarInt', 'BinaryInt', 'OctalInt', 'HexInt', 'HexCapsInt', 'DecimalInt']
12
13
14class ScalarInt(no_limit_int):
15    def __new__(cls, *args, **kw):
16        # type: (Any, Any, Any) -> Any
17        width = kw.pop('width', None)  # type: ignore
18        underscore = kw.pop('underscore', None)  # type: ignore
19        anchor = kw.pop('anchor', None)  # type: ignore
20        v = no_limit_int.__new__(cls, *args, **kw)  # type: ignore
21        v._width = width
22        v._underscore = underscore
23        if anchor is not None:
24            v.yaml_set_anchor(anchor, always_dump=True)
25        return v
26
27    def __iadd__(self, a):  # type: ignore
28        # type: (Any) -> Any
29        x = type(self)(self + a)
30        x._width = self._width  # type: ignore
31        x._underscore = (  # type: ignore
32            self._underscore[:] if self._underscore is not None else None  # type: ignore
33        )  # NOQA
34        return x
35
36    def __ifloordiv__(self, a):  # type: ignore
37        # type: (Any) -> Any
38        x = type(self)(self // a)
39        x._width = self._width  # type: ignore
40        x._underscore = (  # type: ignore
41            self._underscore[:] if self._underscore is not None else None  # type: ignore
42        )  # NOQA
43        return x
44
45    def __imul__(self, a):  # type: ignore
46        # type: (Any) -> Any
47        x = type(self)(self * a)
48        x._width = self._width  # type: ignore
49        x._underscore = (  # type: ignore
50            self._underscore[:] if self._underscore is not None else None  # type: ignore
51        )  # NOQA
52        return x
53
54    def __ipow__(self, a):  # type: ignore
55        # type: (Any) -> Any
56        x = type(self)(self ** a)
57        x._width = self._width  # type: ignore
58        x._underscore = (  # type: ignore
59            self._underscore[:] if self._underscore is not None else None  # type: ignore
60        )  # NOQA
61        return x
62
63    def __isub__(self, a):  # type: ignore
64        # type: (Any) -> Any
65        x = type(self)(self - a)
66        x._width = self._width  # type: ignore
67        x._underscore = (  # type: ignore
68            self._underscore[:] if self._underscore is not None else None  # type: ignore
69        )  # NOQA
70        return x
71
72    @property
73    def anchor(self):
74        # type: () -> Any
75        if not hasattr(self, Anchor.attrib):
76            setattr(self, Anchor.attrib, Anchor())
77        return getattr(self, Anchor.attrib)
78
79    def yaml_anchor(self, any=False):
80        # type: (bool) -> Any
81        if not hasattr(self, Anchor.attrib):
82            return None
83        if any or self.anchor.always_dump:
84            return self.anchor
85        return None
86
87    def yaml_set_anchor(self, value, always_dump=False):
88        # type: (Any, bool) -> None
89        self.anchor.value = value
90        self.anchor.always_dump = always_dump
91
92
93class BinaryInt(ScalarInt):
94    def __new__(cls, value, width=None, underscore=None, anchor=None):
95        # type: (Any, Any, Any, Any) -> Any
96        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
97
98
99class OctalInt(ScalarInt):
100    def __new__(cls, value, width=None, underscore=None, anchor=None):
101        # type: (Any, Any, Any, Any) -> Any
102        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
103
104
105# mixed casing of A-F is not supported, when loading the first non digit
106# determines the case
107
108
109class HexInt(ScalarInt):
110    """uses lower case (a-f)"""
111
112    def __new__(cls, value, width=None, underscore=None, anchor=None):
113        # type: (Any, Any, Any, Any) -> Any
114        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
115
116
117class HexCapsInt(ScalarInt):
118    """uses upper case (A-F)"""
119
120    def __new__(cls, value, width=None, underscore=None, anchor=None):
121        # type: (Any, Any, Any, Any) -> Any
122        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
123
124
125class DecimalInt(ScalarInt):
126    """needed if anchor"""
127
128    def __new__(cls, value, width=None, underscore=None, anchor=None):
129        # type: (Any, Any, Any, Any) -> Any
130        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
131