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 @classmethod
100 def from_ical(cls, ical: ICAL_TYPE):
101 try:
102 return cls(ical)
103 except Exception as e:
104 raise ValueError(f"Expected int, got: {ical}") from e
105
106 @classmethod
107 def examples(cls) -> list[Self]:
108 """Examples of vInt."""
109 return [vInt(1000), vInt(-42)]
110
111 from icalendar.param import VALUE
112
113 def to_jcal(self, name: str) -> list:
114 """The jCal representation of this property according to :rfc:`7265`."""
115 return [name, self.params.to_jcal(), self.VALUE.lower(), int(self)]
116
117 @classmethod
118 def from_jcal(cls, jcal_property: list) -> Self:
119 """Parse jCal from :rfc:`7265`.
120
121 Parameters:
122 jcal_property: The jCal property to parse.
123
124 Raises:
125 ~error.JCalParsingError: If the provided jCal is invalid.
126 """
127 JCalParsingError.validate_property(jcal_property, cls)
128 JCalParsingError.validate_value_type(jcal_property[3], int, cls, 3)
129 return cls(
130 jcal_property[3],
131 params=Parameters.from_jcal_property(jcal_property),
132 )
133
134 @classmethod
135 def parse_jcal_value(cls, value: Any) -> int:
136 """Parse a jCal value for vInt.
137
138 Raises:
139 ~error.JCalParsingError: If the value is not an int.
140 """
141 JCalParsingError.validate_value_type(value, int, cls)
142 return cls(value)
143
144
145__all__ = ["vInt"]