1"""BOOLEAN values from :rfc:`5545`."""
2
3from typing import Any, ClassVar
4
5from icalendar.caselessdict import CaselessDict
6from icalendar.compatibility import Self
7from icalendar.error import JCalParsingError
8from icalendar.parser import Parameters
9
10
11class vBoolean(int):
12 """Boolean
13
14 Value Name: BOOLEAN
15
16 Purpose: This value type is used to identify properties that contain
17 either a "TRUE" or "FALSE" Boolean value.
18
19 Format Definition: This value type is defined by the following
20 notation:
21
22 .. code-block:: text
23
24 boolean = "TRUE" / "FALSE"
25
26 Description: These values are case-insensitive text. No additional
27 content value encoding is defined for this value type.
28
29 Example: The following is an example of a hypothetical property that
30 has a BOOLEAN value type:
31
32 .. code-block:: python
33
34 TRUE
35
36 .. code-block:: pycon
37
38 >>> from icalendar.prop import vBoolean
39 >>> boolean = vBoolean.from_ical('TRUE')
40 >>> boolean
41 True
42 >>> boolean = vBoolean.from_ical('FALSE')
43 >>> boolean
44 False
45 >>> boolean = vBoolean.from_ical('True')
46 >>> boolean
47 True
48 """
49
50 default_value: ClassVar[str] = "BOOLEAN"
51 params: Parameters
52
53 BOOL_MAP = CaselessDict({"true": True, "false": False})
54
55 def __new__(
56 cls, *args: Any, params: dict[str, Any] | None = None, **kwargs: Any
57 ) -> Self:
58 self = super().__new__(cls, *args, **kwargs)
59 self.params = Parameters(params)
60 return self
61
62 def to_ical(self) -> bytes:
63 """Converts a :class:`~icalendar.prop.boolean.vBoolean` to a BOOLEAN property type.
64
65 This class method takes a ``vBoolean``—a Python boolean value—and converts it to an iCalendar BOOLEAN property type, in compliance with :rfc:`5545#section-3.3.2`.
66
67 Returns:
68 Either "TRUE" or "FALSE" as bytes, depending on the value of the ``vBoolean``.
69 """
70 return b"TRUE" if self else b"FALSE"
71
72 @property
73 def ical_value(self) -> bool:
74 """BOOLEAN property type according to :rfc:`5545#section-3.3.2`"""
75 return bool(self)
76
77 @classmethod
78 def from_ical(cls, ical: str) -> bool:
79 try:
80 return cls.BOOL_MAP[ical]
81 except Exception as e:
82 raise ValueError(f"Expected 'TRUE' or 'FALSE'. Got {ical}") from e
83
84 @classmethod
85 def examples(cls) -> list[Self]:
86 """Examples of vBoolean."""
87 return [
88 cls(True),
89 cls(False),
90 ]
91
92 from icalendar.param import VALUE
93
94 def to_jcal(self, name: str) -> list:
95 """The jCal representation of this property according to :rfc:`7265`."""
96 return [name, self.params.to_jcal(), self.VALUE.lower(), bool(self)]
97
98 @classmethod
99 def from_jcal(cls, jcal_property: list) -> Self:
100 """Parse jCal from :rfc:`7265` to a vBoolean.
101
102 Parameters:
103 jcal_property: The jCal property to parse.
104
105 Raises:
106 ~error.JCalParsingError: If the provided jCal is invalid.
107 """
108 JCalParsingError.validate_property(jcal_property, cls)
109 JCalParsingError.validate_value_type(jcal_property[3], bool, cls, 3)
110 return cls(
111 jcal_property[3],
112 params=Parameters.from_jcal_property(jcal_property),
113 )
114
115
116__all__ = ["vBoolean"]