1"""INT values from :rfc:`5545`."""
2
3from typing import Any, ClassVar
4
5from icalendar.compatibility import Self
6from icalendar.error import JCalParsingError
7from icalendar.parser import Parameters
8from icalendar.parser_tools import ICAL_TYPE
9
10
11class vInt(int):
12 """Integer
13
14 Value Name:
15 INTEGER
16
17 Purpose:
18 This value type is used to identify properties that contain a
19 signed integer value.
20
21 Format Definition:
22 This value type is defined by the following notation:
23
24 .. code-block:: text
25
26 integer = (["+"] / "-") 1*DIGIT
27
28 Description:
29 If the property permits, multiple "integer" values are
30 specified by a COMMA-separated list of values. The valid range
31 for "integer" is -2147483648 to 2147483647. If the sign is not
32 specified, then the value is assumed to be positive.
33
34 The ``__new__`` method creates a vInt instance:
35
36 Parameters:
37 value: Integer value to encode. Can be positive or negative within
38 the range -2147483648 to 2147483647.
39 params: Optional parameter dictionary for the property.
40
41 Returns:
42 vInt instance
43
44 Examples:
45
46 .. code-block:: text
47
48 1234567890
49 -1234567890
50 +1234567890
51 432109876
52
53 .. code-block:: pycon
54
55 >>> from icalendar.prop import vInt
56 >>> integer = vInt.from_ical('1234567890')
57 >>> integer
58 1234567890
59 >>> integer = vInt.from_ical('-1234567890')
60 >>> integer
61 -1234567890
62 >>> integer = vInt.from_ical('+1234567890')
63 >>> integer
64 1234567890
65 >>> integer = vInt.from_ical('432109876')
66 >>> integer
67 432109876
68
69 Create a PRIORITY property (1 = highest priority):
70
71 .. code-block:: pycon
72
73 >>> priority = vInt(1)
74 >>> priority
75 1
76 >>> priority.to_ical()
77 b'1'
78
79 Create SEQUENCE property (for versioning):
80
81 .. code-block:: pycon
82
83 >>> sequence = vInt(3)
84 >>> sequence.to_ical()
85 b'3'
86 """
87
88 default_value: ClassVar[str] = "INTEGER"
89 params: Parameters
90
91 def __new__(cls, *args, params: dict[str, Any] | None = None, **kwargs):
92 self = super().__new__(cls, *args, **kwargs)
93 self.params = Parameters(params)
94 return self
95
96 def to_ical(self) -> bytes:
97 return str(self).encode("utf-8")
98
99 @property
100 def ical_value(self) -> int:
101 """INTEGER property type according to :rfc:`5545#section-3.3.8`"""
102 return int(self)
103
104 @classmethod
105 def from_ical(cls, ical: ICAL_TYPE):
106 try:
107 return cls(ical)
108 except Exception as e:
109 raise ValueError(f"Expected int, got: {ical}") from e
110
111 @classmethod
112 def examples(cls) -> list[Self]:
113 """Examples of vInt."""
114 return [vInt(1000), vInt(-42)]
115
116 from icalendar.param import VALUE
117
118 def to_jcal(self, name: str) -> list:
119 """The jCal representation of this property according to :rfc:`7265`."""
120 return [name, self.params.to_jcal(), self.VALUE.lower(), int(self)]
121
122 @classmethod
123 def from_jcal(cls, jcal_property: list) -> Self:
124 """Parse jCal from :rfc:`7265`.
125
126 Parameters:
127 jcal_property: The jCal property to parse.
128
129 Raises:
130 ~error.JCalParsingError: If the provided jCal is invalid.
131 """
132 JCalParsingError.validate_property(jcal_property, cls)
133 JCalParsingError.validate_value_type(jcal_property[3], int, cls, 3)
134 return cls(
135 jcal_property[3],
136 params=Parameters.from_jcal_property(jcal_property),
137 )
138
139 @classmethod
140 def parse_jcal_value(cls, value: Any) -> int:
141 """Parse a jCal value for vInt.
142
143 Raises:
144 ~error.JCalParsingError: If the value is not an int.
145 """
146 JCalParsingError.validate_value_type(value, int, cls)
147 return cls(value)
148
149
150__all__ = ["vInt"]