value-object-pattern 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- value_object_pattern/__init__.py +10 -0
- value_object_pattern/decorators/__init__.py +7 -0
- value_object_pattern/decorators/value_object_process.py +83 -0
- value_object_pattern/decorators/value_object_validation.py +78 -0
- value_object_pattern/models/__init__.py +3 -0
- value_object_pattern/models/value_object.py +383 -0
- value_object_pattern/py.typed +0 -0
- value_object_pattern/usables/__init__.py +54 -0
- value_object_pattern/usables/dates/__init__.py +9 -0
- value_object_pattern/usables/dates/date/__init__.py +7 -0
- value_object_pattern/usables/dates/date/date_value_object.py +162 -0
- value_object_pattern/usables/dates/date/string_date_value_object.py +201 -0
- value_object_pattern/usables/dates/datetime/__init__.py +7 -0
- value_object_pattern/usables/dates/datetime/datetime_value_object.py +193 -0
- value_object_pattern/usables/dates/datetime/string_datetime_value_object.py +237 -0
- value_object_pattern/usables/identifiers/__init__.py +7 -0
- value_object_pattern/usables/identifiers/country_ids/__init__.py +3 -0
- value_object_pattern/usables/identifiers/country_ids/spain/__init__.py +3 -0
- value_object_pattern/usables/identifiers/country_ids/spain/dni_value_object.py +63 -0
- value_object_pattern/usables/identifiers/string_uuid_value_object.py +56 -0
- value_object_pattern/usables/identifiers/uuid_value_object.py +40 -0
- value_object_pattern/usables/internet/__init__.py +38 -0
- value_object_pattern/usables/internet/api_keys/__init__.py +13 -0
- value_object_pattern/usables/internet/api_keys/aws_access_key_id_value_object.py +40 -0
- value_object_pattern/usables/internet/api_keys/aws_secret_access_key_value_object.py +40 -0
- value_object_pattern/usables/internet/api_keys/github_personal_access_token_value_object.py +41 -0
- value_object_pattern/usables/internet/api_keys/openai_api_key_value_object.py +40 -0
- value_object_pattern/usables/internet/api_keys/resend_api_key_value_object.py +40 -0
- value_object_pattern/usables/internet/aws_cloud_region_value_object.py +77 -0
- value_object_pattern/usables/internet/domain_value_object.py +149 -0
- value_object_pattern/usables/internet/host_value_object.py +143 -0
- value_object_pattern/usables/internet/ipv4_address_value_object.py +305 -0
- value_object_pattern/usables/internet/ipv4_network_value_object.py +165 -0
- value_object_pattern/usables/internet/ipv6_address_value_object.py +288 -0
- value_object_pattern/usables/internet/ipv6_network_value_object.py +145 -0
- value_object_pattern/usables/internet/mac_address_value_object.py +390 -0
- value_object_pattern/usables/internet/port_value_object.py +682 -0
- value_object_pattern/usables/internet/uri/__init__.py +11 -0
- value_object_pattern/usables/internet/uri/http_https_url_value_object.py +39 -0
- value_object_pattern/usables/internet/uri/http_url_value_object.py +39 -0
- value_object_pattern/usables/internet/uri/https_url_value_object.py +39 -0
- value_object_pattern/usables/internet/uri/url_value_object.py +396 -0
- value_object_pattern/usables/primitives/__init__.py +45 -0
- value_object_pattern/usables/primitives/boolean/__init__.py +9 -0
- value_object_pattern/usables/primitives/boolean/boolean_value_object.py +36 -0
- value_object_pattern/usables/primitives/boolean/false_value_object.py +37 -0
- value_object_pattern/usables/primitives/boolean/true_value_object.py +37 -0
- value_object_pattern/usables/primitives/bytes/__init__.py +3 -0
- value_object_pattern/usables/primitives/bytes/bytes_value_object.py +36 -0
- value_object_pattern/usables/primitives/float/__init__.py +9 -0
- value_object_pattern/usables/primitives/float/float_value_object.py +36 -0
- value_object_pattern/usables/primitives/float/negative_float_value_object.py +37 -0
- value_object_pattern/usables/primitives/float/positive_float_value_object.py +37 -0
- value_object_pattern/usables/primitives/integer/__init__.py +13 -0
- value_object_pattern/usables/primitives/integer/even_integer_value_object.py +37 -0
- value_object_pattern/usables/primitives/integer/integer_value_object.py +36 -0
- value_object_pattern/usables/primitives/integer/negative_integer_value_object.py +37 -0
- value_object_pattern/usables/primitives/integer/odd_integer_value_object.py +37 -0
- value_object_pattern/usables/primitives/integer/positive_integer_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/__init__.py +21 -0
- value_object_pattern/usables/primitives/string/alpha_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/alphanumeric_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/digit_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/lowercase_string_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/non_empty_string_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/printable_string_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/string_value_object.py +36 -0
- value_object_pattern/usables/primitives/string/trimmed_string_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/uppercase_string_value_object.py +37 -0
- value_object_pattern-0.1.0.dist-info/METADATA +95 -0
- value_object_pattern-0.1.0.dist-info/RECORD +73 -0
- value_object_pattern-0.1.0.dist-info/WHEEL +4 -0
- value_object_pattern-0.1.0.dist-info/licenses/LICENSE.md +21 -0
@@ -0,0 +1,165 @@
|
|
1
|
+
# ruff: noqa: N802
|
2
|
+
"""
|
3
|
+
Ipv4NetworkValueObject value object.
|
4
|
+
"""
|
5
|
+
|
6
|
+
from ipaddress import AddressValueError, IPv4Network, NetmaskValueError
|
7
|
+
|
8
|
+
from value_object_pattern.decorators import process, validation
|
9
|
+
from value_object_pattern.usables import NotEmptyStringValueObject, TrimmedStringValueObject
|
10
|
+
|
11
|
+
from .ipv4_address_value_object import Ipv4AddressValueObject
|
12
|
+
|
13
|
+
|
14
|
+
class Ipv4NetworkValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
|
15
|
+
"""
|
16
|
+
Ipv4NetworkValueObject value object ensures the provided value is a valid IPv4 network.
|
17
|
+
|
18
|
+
Example:
|
19
|
+
```python
|
20
|
+
from value_object_pattern.usables.internet import Ipv4NetworkValueObject
|
21
|
+
|
22
|
+
network = Ipv4NetworkValueObject(value='66.162.207.81')
|
23
|
+
|
24
|
+
print(repr(network))
|
25
|
+
# >>> Ipv4NetworkValueObject(value=66.162.207.81/32)
|
26
|
+
```
|
27
|
+
"""
|
28
|
+
|
29
|
+
@process(order=0)
|
30
|
+
def _ensure_value_is_normalized(self, value: str) -> str:
|
31
|
+
"""
|
32
|
+
Ensures the value object value is normalized IPv4 network.
|
33
|
+
|
34
|
+
Args:
|
35
|
+
value (str): Value.
|
36
|
+
|
37
|
+
Returns:
|
38
|
+
str: Value with the normalized IPv4 network.
|
39
|
+
"""
|
40
|
+
return str(object=IPv4Network(address=value))
|
41
|
+
|
42
|
+
@validation(order=0)
|
43
|
+
def _ensure_value_is_valid_ipv4_network(self, value: str) -> None:
|
44
|
+
"""
|
45
|
+
Ensures the value object value is a valid IPv4 network.
|
46
|
+
|
47
|
+
Args:
|
48
|
+
value (str): Value.
|
49
|
+
|
50
|
+
Raises:
|
51
|
+
ValueError: If the value is not a valid IPv4 network.
|
52
|
+
"""
|
53
|
+
self._ipv4_network_validate(value=value)
|
54
|
+
|
55
|
+
@classmethod
|
56
|
+
def _ipv4_network_validate(cls, value: str) -> IPv4Network:
|
57
|
+
"""
|
58
|
+
Validates the given IPv4 network.
|
59
|
+
|
60
|
+
Args:
|
61
|
+
value (str): IPv4 network.
|
62
|
+
|
63
|
+
Raises:
|
64
|
+
ValueError: If the value is not a valid IPv4 network.
|
65
|
+
ValueError: If the value has an invalid netmask.
|
66
|
+
|
67
|
+
Returns:
|
68
|
+
IPv4Network: IPv4 network.
|
69
|
+
"""
|
70
|
+
try:
|
71
|
+
return IPv4Network(address=value)
|
72
|
+
|
73
|
+
except NetmaskValueError as error:
|
74
|
+
raise ValueError(f'Ipv4NetworkValueObject value <<<{value}>>> has an invalid netmask.') from error
|
75
|
+
|
76
|
+
except (AddressValueError, ValueError) as error:
|
77
|
+
raise ValueError(f'Ipv4NetworkValueObject value <<<{value}>>> is not a valid IPv4 network.') from error
|
78
|
+
|
79
|
+
def get_network(self) -> Ipv4AddressValueObject:
|
80
|
+
"""
|
81
|
+
Returns the network of the given IPv4 network.
|
82
|
+
|
83
|
+
Args:
|
84
|
+
value (str): IPv4 network.
|
85
|
+
|
86
|
+
Returns:
|
87
|
+
Ipv4AddressValueObject: The network IPv4 address.
|
88
|
+
|
89
|
+
Example:
|
90
|
+
```python
|
91
|
+
from value_object_pattern.usables.internet import Ipv4NetworkValueObject
|
92
|
+
|
93
|
+
ip = Ipv4NetworkValueObject(value='192.168.10.0/24').get_network()
|
94
|
+
|
95
|
+
print(repr(ip))
|
96
|
+
# >>> Ipv4AddressValueObject(value=192.168.10.0)
|
97
|
+
```
|
98
|
+
"""
|
99
|
+
return Ipv4AddressValueObject(value=str(object=self._ipv4_network_validate(value=self.value).network_address))
|
100
|
+
|
101
|
+
def get_broadcast(self) -> Ipv4AddressValueObject:
|
102
|
+
"""
|
103
|
+
Returns the broadcast of the given IPv4 network.
|
104
|
+
|
105
|
+
Args:
|
106
|
+
value (str): IPv4 network.
|
107
|
+
|
108
|
+
Returns:
|
109
|
+
Ipv4AddressValueObject: The broadcast IPv4 address.
|
110
|
+
|
111
|
+
Example:
|
112
|
+
```python
|
113
|
+
from value_object_pattern.usables.internet import Ipv4NetworkValueObject
|
114
|
+
|
115
|
+
ip = Ipv4NetworkValueObject(value='192.168.10.0/24').get_broadcast()
|
116
|
+
|
117
|
+
print(repr(ip))
|
118
|
+
# >>> Ipv4AddressValueObject(value=192.168.10.255)
|
119
|
+
```
|
120
|
+
"""
|
121
|
+
return Ipv4AddressValueObject(value=str(object=self._ipv4_network_validate(value=self.value).broadcast_address))
|
122
|
+
|
123
|
+
def get_mask(self) -> int:
|
124
|
+
"""
|
125
|
+
Returns the mask of the given IPv4 network.
|
126
|
+
|
127
|
+
Args:
|
128
|
+
value (str): IPv4 network.
|
129
|
+
|
130
|
+
Returns:
|
131
|
+
int: The network mask.
|
132
|
+
|
133
|
+
Example:
|
134
|
+
```python
|
135
|
+
from value_object_pattern.usables.internet import Ipv4NetworkValueObject
|
136
|
+
|
137
|
+
mask = Ipv4NetworkValueObject(value='192.168.10.0/24').get_mask()
|
138
|
+
|
139
|
+
print(mask)
|
140
|
+
# >>> 24
|
141
|
+
```
|
142
|
+
"""
|
143
|
+
return self._ipv4_network_validate(value=self.value).prefixlen
|
144
|
+
|
145
|
+
def get_number_addresses(self) -> int:
|
146
|
+
"""
|
147
|
+
Returns the number of addresses of the given IPv4 network.
|
148
|
+
|
149
|
+
Args:
|
150
|
+
value (str): IPv4 network.
|
151
|
+
|
152
|
+
Returns:
|
153
|
+
int: The number of addresses.
|
154
|
+
|
155
|
+
Example:
|
156
|
+
```python
|
157
|
+
from value_object_pattern.usables.internet import Ipv4NetworkValueObject
|
158
|
+
|
159
|
+
addresses = Ipv4NetworkValueObject(value='192.168.10.0/24').get_number_addresses()
|
160
|
+
|
161
|
+
print(addresses)
|
162
|
+
# >>> 256
|
163
|
+
```
|
164
|
+
"""
|
165
|
+
return self._ipv4_network_validate(value=self.value).num_addresses
|
@@ -0,0 +1,288 @@
|
|
1
|
+
# ruff: noqa: N802
|
2
|
+
"""
|
3
|
+
Ipv6AddressValueObject value object.
|
4
|
+
"""
|
5
|
+
|
6
|
+
from __future__ import annotations
|
7
|
+
|
8
|
+
from ipaddress import AddressValueError, IPv6Address
|
9
|
+
|
10
|
+
from value_object_pattern.decorators import process, validation
|
11
|
+
from value_object_pattern.usables import NotEmptyStringValueObject, TrimmedStringValueObject
|
12
|
+
|
13
|
+
|
14
|
+
class Ipv6AddressValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
|
15
|
+
"""
|
16
|
+
Ipv6AddressValueObject value object ensures the provided value is a valid IPv6 address.
|
17
|
+
|
18
|
+
Example:
|
19
|
+
```python
|
20
|
+
from value_object_pattern.usables.internet import Ipv6AddressValueObject
|
21
|
+
|
22
|
+
ip = Ipv6AddressValueObject(value='e8f5:bbcf:f16d:8fc1:ab49:a3ae:36eb:b254')
|
23
|
+
|
24
|
+
print(repr(ip))
|
25
|
+
# >>> Ipv6AddressValueObject(value=e8f5:bbcf:f16d:8fc1:ab49:a3ae:36eb:b254)
|
26
|
+
```
|
27
|
+
"""
|
28
|
+
|
29
|
+
@process(order=0)
|
30
|
+
def _ensure_value_is_normalized(self, value: str) -> str:
|
31
|
+
"""
|
32
|
+
Ensures the value object value is normalized IPv6 address.
|
33
|
+
|
34
|
+
Args:
|
35
|
+
value (str): Value.
|
36
|
+
|
37
|
+
Returns:
|
38
|
+
str: Value with the normalized IPv6 address.
|
39
|
+
"""
|
40
|
+
value = self._ipv6_address_normalize(value=value)
|
41
|
+
return str(object=self._ipv6_address_validate(value=value))
|
42
|
+
|
43
|
+
@validation(order=0)
|
44
|
+
def _ensure_value_is_valid_ipv6_address(self, value: str) -> None:
|
45
|
+
"""
|
46
|
+
Ensures the value object value is a valid IPv6 address.
|
47
|
+
|
48
|
+
Args:
|
49
|
+
value (str): Value.
|
50
|
+
|
51
|
+
Raises:
|
52
|
+
ValueError: If the value is not a valid IPv6 address.
|
53
|
+
"""
|
54
|
+
value = self._ipv6_address_normalize(value=value)
|
55
|
+
self._ipv6_address_validate(value=value)
|
56
|
+
|
57
|
+
@classmethod
|
58
|
+
def _ipv6_address_normalize(cls, value: str) -> str:
|
59
|
+
"""
|
60
|
+
Normalizes the given IPv6 address.
|
61
|
+
|
62
|
+
Args:
|
63
|
+
value (str): IPv6 address.
|
64
|
+
|
65
|
+
Returns:
|
66
|
+
str: Normalized IPv6 address.
|
67
|
+
"""
|
68
|
+
if '/' in value and value.endswith('/128'):
|
69
|
+
value = value[:-4]
|
70
|
+
|
71
|
+
if value.startswith('[') and value.endswith(']'):
|
72
|
+
value = value[1:-1]
|
73
|
+
|
74
|
+
return value
|
75
|
+
|
76
|
+
@classmethod
|
77
|
+
def _ipv6_address_validate(cls, value: str) -> IPv6Address:
|
78
|
+
"""
|
79
|
+
Validates the given IPv6 address.
|
80
|
+
|
81
|
+
Args:
|
82
|
+
value (str): IPv6 address.
|
83
|
+
|
84
|
+
Raises:
|
85
|
+
ValueError: If the value is not a valid IPv6 address.
|
86
|
+
|
87
|
+
Returns:
|
88
|
+
IPv6Address: IPv6 address.
|
89
|
+
"""
|
90
|
+
try:
|
91
|
+
return IPv6Address(address=value)
|
92
|
+
|
93
|
+
except AddressValueError as error:
|
94
|
+
raise ValueError(f'Ipv6AddressValueObject value <<<{value}>>> is not a valid IPv6 address.') from error
|
95
|
+
|
96
|
+
def is_reserved(self) -> bool:
|
97
|
+
"""
|
98
|
+
Checks if the given IPv6 address is reserved.
|
99
|
+
|
100
|
+
Args:
|
101
|
+
value (str): IPv6 address.
|
102
|
+
|
103
|
+
Returns:
|
104
|
+
bool: True if the given IPv6 address is reserved, False otherwise.
|
105
|
+
|
106
|
+
Example:
|
107
|
+
```python
|
108
|
+
from value_object_pattern.usables.internet import Ipv6AddressValueObject
|
109
|
+
|
110
|
+
is_reserved = Ipv6AddressValueObject(value='800::').is_reserved()
|
111
|
+
|
112
|
+
print(is_reserved)
|
113
|
+
# >>> True
|
114
|
+
```
|
115
|
+
"""
|
116
|
+
return self._ipv6_address_validate(value=self.value).is_reserved
|
117
|
+
|
118
|
+
def is_private(self) -> bool:
|
119
|
+
"""
|
120
|
+
Checks if the given IPv6 address is private.
|
121
|
+
|
122
|
+
Args:
|
123
|
+
value (str): IPv6 address.
|
124
|
+
|
125
|
+
Returns:
|
126
|
+
bool: True if the given IPv6 address is private, False otherwise.
|
127
|
+
|
128
|
+
Example:
|
129
|
+
```python
|
130
|
+
from value_object_pattern.usables.internet import Ipv6AddressValueObject
|
131
|
+
|
132
|
+
is_private = Ipv6AddressValueObject(value='fd00::1').is_private()
|
133
|
+
|
134
|
+
print(is_private)
|
135
|
+
# >>> True
|
136
|
+
```
|
137
|
+
"""
|
138
|
+
return self._ipv6_address_validate(value=self.value).is_private
|
139
|
+
|
140
|
+
def is_global(self) -> bool:
|
141
|
+
"""
|
142
|
+
Checks if the given IPv6 address is global.
|
143
|
+
|
144
|
+
Args:
|
145
|
+
value (str): IPv6 address.
|
146
|
+
|
147
|
+
Returns:
|
148
|
+
bool: True if the given IPv6 address is global, False otherwise.
|
149
|
+
|
150
|
+
Example:
|
151
|
+
```python
|
152
|
+
from value_object_pattern.usables.internet import Ipv6AddressValueObject
|
153
|
+
|
154
|
+
is_global = Ipv6AddressValueObject(value='e8f5:bbcf:f16d:8fc1:ab49:a3ae:36eb:b254').is_global()
|
155
|
+
|
156
|
+
print(is_global)
|
157
|
+
# >>> True
|
158
|
+
```
|
159
|
+
"""
|
160
|
+
return self._ipv6_address_validate(value=self.value).is_global
|
161
|
+
|
162
|
+
def is_multicast(self) -> bool:
|
163
|
+
"""
|
164
|
+
Checks if the given IPv6 address is multicast.
|
165
|
+
|
166
|
+
Args:
|
167
|
+
value (str): IPv6 address.
|
168
|
+
|
169
|
+
Returns:
|
170
|
+
bool: True if the given IPv6 address is multicast, False otherwise.
|
171
|
+
|
172
|
+
Example:
|
173
|
+
```python
|
174
|
+
from value_object_pattern.usables.internet import Ipv6AddressValueObject
|
175
|
+
|
176
|
+
is_multicast = Ipv6AddressValueObject(value='ff02::1').is_multicast()
|
177
|
+
|
178
|
+
print(is_multicast)
|
179
|
+
# >>> True
|
180
|
+
```
|
181
|
+
"""
|
182
|
+
return self._ipv6_address_validate(value=self.value).is_multicast
|
183
|
+
|
184
|
+
def is_unspecified(self) -> bool:
|
185
|
+
"""
|
186
|
+
Checks if the given IPv6 address is unspecified.
|
187
|
+
|
188
|
+
Args:
|
189
|
+
value (str): IPv6 address.
|
190
|
+
|
191
|
+
Returns:
|
192
|
+
bool: True if the given IPv6 address is unspecified, False otherwise.
|
193
|
+
|
194
|
+
Example:
|
195
|
+
```python
|
196
|
+
from value_object_pattern.usables.internet import Ipv6AddressValueObject
|
197
|
+
|
198
|
+
is_unspecified = Ipv6AddressValueObject(value='::').is_unspecified()
|
199
|
+
|
200
|
+
print(is_unspecified)
|
201
|
+
# >>> True
|
202
|
+
```
|
203
|
+
"""
|
204
|
+
return self._ipv6_address_validate(value=self.value).is_unspecified
|
205
|
+
|
206
|
+
def is_loopback(self) -> bool:
|
207
|
+
"""
|
208
|
+
Checks if the given IPv6 address is loopback.
|
209
|
+
|
210
|
+
Args:
|
211
|
+
value (str): IPv6 address.
|
212
|
+
|
213
|
+
Returns:
|
214
|
+
bool: True if the given IPv6 address is loopback, False otherwise.
|
215
|
+
|
216
|
+
Example:
|
217
|
+
```python
|
218
|
+
from value_object_pattern.usables.internet import Ipv6AddressValueObject
|
219
|
+
|
220
|
+
is_loopback = Ipv6AddressValueObject(value='::1').is_loopback()
|
221
|
+
|
222
|
+
print(is_loopback)
|
223
|
+
# >>> True
|
224
|
+
```
|
225
|
+
"""
|
226
|
+
return self._ipv6_address_validate(value=self.value).is_loopback
|
227
|
+
|
228
|
+
def is_link_local(self) -> bool:
|
229
|
+
"""
|
230
|
+
Checks if the given IPv6 address is link-local.
|
231
|
+
|
232
|
+
Args:
|
233
|
+
value (str): IPv6 address.
|
234
|
+
|
235
|
+
Returns:
|
236
|
+
bool: True if the given IPv6 address is link-local, False otherwise.
|
237
|
+
|
238
|
+
Example:
|
239
|
+
```python
|
240
|
+
from value_object_pattern.usables.internet import Ipv6AddressValueObject
|
241
|
+
|
242
|
+
is_link_local = Ipv6AddressValueObject(value='fe80::1').is_link_local()
|
243
|
+
|
244
|
+
print(is_link_local)
|
245
|
+
# >>> True
|
246
|
+
```
|
247
|
+
"""
|
248
|
+
return self._ipv6_address_validate(value=self.value).is_link_local
|
249
|
+
|
250
|
+
@classmethod
|
251
|
+
def UNSPECIFIED(cls) -> Ipv6AddressValueObject:
|
252
|
+
"""
|
253
|
+
Returns the unspecified IPv6 address (::).
|
254
|
+
|
255
|
+
Returns:
|
256
|
+
Ipv6AddressValueObject: Unspecified IPv6 address.
|
257
|
+
|
258
|
+
Example:
|
259
|
+
```python
|
260
|
+
from value_object_pattern.usables.internet import Ipv6AddressValueObject
|
261
|
+
|
262
|
+
ip = Ipv6AddressValueObject.UNSPECIFIED()
|
263
|
+
|
264
|
+
print(repr(ip))
|
265
|
+
# >>> Ipv6AddressValueObject(value=::)
|
266
|
+
```
|
267
|
+
"""
|
268
|
+
return cls(value='::')
|
269
|
+
|
270
|
+
@classmethod
|
271
|
+
def LOOPBACK(cls) -> Ipv6AddressValueObject:
|
272
|
+
"""
|
273
|
+
Returns the loopback IPv6 address (::1).
|
274
|
+
|
275
|
+
Returns:
|
276
|
+
Ipv6AddressValueObject: Loopback IPv6 address.
|
277
|
+
|
278
|
+
Example:
|
279
|
+
```python
|
280
|
+
from value_object_pattern.usables.internet import Ipv6AddressValueObject
|
281
|
+
|
282
|
+
ip = Ipv6AddressValueObject.LOOPBACK()
|
283
|
+
|
284
|
+
print(repr(ip))
|
285
|
+
# >>> Ipv6AddressValueObject(value=::1)
|
286
|
+
```
|
287
|
+
"""
|
288
|
+
return cls(value='::1')
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# ruff: noqa: N802
|
2
|
+
"""
|
3
|
+
Ipv6NetworkValueObject value object.
|
4
|
+
"""
|
5
|
+
|
6
|
+
from ipaddress import AddressValueError, IPv6Network, NetmaskValueError
|
7
|
+
|
8
|
+
from value_object_pattern.decorators import process, validation
|
9
|
+
from value_object_pattern.usables import NotEmptyStringValueObject, TrimmedStringValueObject
|
10
|
+
|
11
|
+
from .ipv6_address_value_object import Ipv6AddressValueObject
|
12
|
+
|
13
|
+
|
14
|
+
class Ipv6NetworkValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
|
15
|
+
"""
|
16
|
+
Ipv6NetworkValueObject value object ensures the provided value is a valid IPv6 network.
|
17
|
+
|
18
|
+
Example:
|
19
|
+
```python
|
20
|
+
from value_object_pattern.usables.internet import Ipv6NetworkValueObject
|
21
|
+
|
22
|
+
network = Ipv6NetworkValueObject(value='e8f5:bbcf:f16d:8fc1:ab49:a3ae:36eb:b254')
|
23
|
+
|
24
|
+
print(repr(network))
|
25
|
+
# >>> Ipv6NetworkValueObject(value=e8f5:bbcf:f16d:8fc1:ab49:a3ae:36eb:b254/128)
|
26
|
+
```
|
27
|
+
"""
|
28
|
+
|
29
|
+
@process(order=0)
|
30
|
+
def _ensure_value_is_normalized(self, value: str) -> str:
|
31
|
+
"""
|
32
|
+
Ensures the value object value is normalized IPv6 network.
|
33
|
+
|
34
|
+
Args:
|
35
|
+
value (str): Value.
|
36
|
+
|
37
|
+
Returns:
|
38
|
+
str: Value with the normalized IPv6 network.
|
39
|
+
"""
|
40
|
+
return str(object=IPv6Network(address=value))
|
41
|
+
|
42
|
+
@validation(order=0)
|
43
|
+
def _ensure_value_is_valid_ipv6_network(self, value: str) -> None:
|
44
|
+
"""
|
45
|
+
Ensures the value object value is a valid IPv6 network.
|
46
|
+
|
47
|
+
Args:
|
48
|
+
value (str): Value.
|
49
|
+
|
50
|
+
Raises:
|
51
|
+
ValueError: If the value is not a valid IPv6 network.
|
52
|
+
"""
|
53
|
+
self._ipv6_network_validate(value=value)
|
54
|
+
|
55
|
+
@classmethod
|
56
|
+
def _ipv6_network_validate(cls, value: str) -> IPv6Network:
|
57
|
+
"""
|
58
|
+
Validates the given IPv6 network.
|
59
|
+
|
60
|
+
Args:
|
61
|
+
value (str): IPv6 network.
|
62
|
+
|
63
|
+
Raises:
|
64
|
+
ValueError: If the value is not a valid IPv6 network.
|
65
|
+
ValueError: If the value has an invalid netmask.
|
66
|
+
|
67
|
+
Returns:
|
68
|
+
IPv6Network: IPv6 network.
|
69
|
+
"""
|
70
|
+
try:
|
71
|
+
return IPv6Network(address=value)
|
72
|
+
|
73
|
+
except NetmaskValueError as error:
|
74
|
+
raise ValueError(f'Ipv6NetworkValueObject value <<<{value}>>> has an invalid netmask.') from error
|
75
|
+
|
76
|
+
except (AddressValueError, ValueError) as error:
|
77
|
+
raise ValueError(f'Ipv6NetworkValueObject value <<<{value}>>> is not a valid IPv6 network.') from error
|
78
|
+
|
79
|
+
def get_network(self) -> Ipv6AddressValueObject:
|
80
|
+
"""
|
81
|
+
Returns the network of the given IPv6 network.
|
82
|
+
|
83
|
+
Args:
|
84
|
+
value (str): IPv6 network.
|
85
|
+
|
86
|
+
Returns:
|
87
|
+
Ipv6AddressValueObject: The network IPv6 address.
|
88
|
+
|
89
|
+
Example:
|
90
|
+
```python
|
91
|
+
from value_object_pattern.usables.internet import Ipv6NetworkValueObject
|
92
|
+
|
93
|
+
ip = Ipv6NetworkValueObject(value='fd5b:207::/48').get_network()
|
94
|
+
|
95
|
+
print(repr(ip))
|
96
|
+
# >>> Ipv6AddressValueObject(value=fd5b:207::)
|
97
|
+
```
|
98
|
+
"""
|
99
|
+
return Ipv6AddressValueObject(value=str(object=self._ipv6_network_validate(value=self.value).network_address))
|
100
|
+
|
101
|
+
def get_mask(self) -> int:
|
102
|
+
"""
|
103
|
+
Returns the mask of the given IPv6 network.
|
104
|
+
|
105
|
+
Args:
|
106
|
+
value (str): IPv6 network.
|
107
|
+
|
108
|
+
Returns:
|
109
|
+
int: The network mask.
|
110
|
+
|
111
|
+
Example:
|
112
|
+
```python
|
113
|
+
from value_object_pattern.usables.internet import Ipv6NetworkValueObject
|
114
|
+
|
115
|
+
mask = Ipv6NetworkValueObject(value='fd5b:207::/48').get_mask()
|
116
|
+
|
117
|
+
print(mask)
|
118
|
+
# >>> 48
|
119
|
+
```
|
120
|
+
"""
|
121
|
+
return self._ipv6_network_validate(value=self.value).prefixlen
|
122
|
+
|
123
|
+
def get_number_addresses(self) -> int:
|
124
|
+
"""
|
125
|
+
Returns the number of addresses of the given IPv6 network.
|
126
|
+
|
127
|
+
Args:
|
128
|
+
value (str): IPv6 network.
|
129
|
+
|
130
|
+
Returns:
|
131
|
+
int: The number of addresses.
|
132
|
+
|
133
|
+
Example:
|
134
|
+
```python
|
135
|
+
from value_object_pattern.usables.internet import Ipv6NetworkValueObject
|
136
|
+
|
137
|
+
addresses = Ipv6NetworkValueObject(value='fd5b:207::/48').get_number_addresses()
|
138
|
+
|
139
|
+
print(addresses)
|
140
|
+
# >>> 1208925819614629174706176
|
141
|
+
```
|
142
|
+
"""
|
143
|
+
return self._ipv6_network_validate(value=self.value).num_addresses
|
144
|
+
|
145
|
+
# TODO: def get_addresses(self) -> list[Ipv6AddressValueObject]:
|