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 return b"TRUE" if self else b"FALSE"
64
65 @classmethod
66 def from_ical(cls, ical: str) -> bool:
67 try:
68 return cls.BOOL_MAP[ical]
69 except Exception as e:
70 raise ValueError(f"Expected 'TRUE' or 'FALSE'. Got {ical}") from e
71
72 @classmethod
73 def examples(cls) -> list[Self]:
74 """Examples of vBoolean."""
75 return [
76 cls(True),
77 cls(False),
78 ]
79
80 from icalendar.param import VALUE
81
82 def to_jcal(self, name: str) -> list:
83 """The jCal representation of this property according to :rfc:`7265`."""
84 return [name, self.params.to_jcal(), self.VALUE.lower(), bool(self)]
85
86 @classmethod
87 def from_jcal(cls, jcal_property: list) -> Self:
88 """Parse jCal from :rfc:`7265` to a vBoolean.
89
90 Parameters:
91 jcal_property: The jCal property to parse.
92
93 Raises:
94 ~error.JCalParsingError: If the provided jCal is invalid.
95 """
96 JCalParsingError.validate_property(jcal_property, cls)
97 JCalParsingError.validate_value_type(jcal_property[3], bool, cls, 3)
98 return cls(
99 jcal_property[3],
100 params=Parameters.from_jcal_property(jcal_property),
101 )
102
103
104__all__ = ["vBoolean"]