Skip to content

Commit 9f3e282

Browse files
authored
feat(exp): add zone format txt record helper (#578)
Add a helper function to format a TXT record before sending it to the API.
1 parent d7c9ff7 commit 9f3e282

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

hcloud/exp/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"""
2+
The `exp` module is a namespace that holds experimental features for the `hcloud-python`
3+
library, breaking changes may occur within minor releases.
4+
"""

hcloud/exp/zone.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""
2+
The `exp.zone` module is a namespace that holds experimental features for the `hcloud-python`
3+
library, breaking changes may occur within minor releases.
4+
"""
5+
6+
from __future__ import annotations
7+
8+
9+
def is_txt_record_quoted(value: str) -> bool:
10+
"""
11+
Check whether a TXT record is already quoted.
12+
13+
- hello world => false
14+
- "hello world" => true
15+
"""
16+
return value.startswith('"') and value.endswith('"')
17+
18+
19+
def format_txt_record(value: str) -> str:
20+
"""
21+
Format a TXT record by splitting it in quoted strings of 255 characters.
22+
Existing quotes will be escaped.
23+
24+
- hello world => "hello world"
25+
- hello "world" => "hello \"world\""
26+
"""
27+
value = value.replace('"', '\\"')
28+
29+
parts = []
30+
for start in range(0, len(value), 255):
31+
end = min(start + 255, len(value))
32+
parts.append('"' + value[start:end] + '"')
33+
value = " ".join(parts)
34+
35+
return value

tests/unit/exp/__init__.py

Whitespace-only changes.

tests/unit/exp/test_zone.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from __future__ import annotations
2+
3+
import pytest
4+
5+
from hcloud.exp.zone import format_txt_record, is_txt_record_quoted
6+
7+
8+
@pytest.mark.parametrize(
9+
("value", "expected"),
10+
[
11+
("hello world", False),
12+
('"hello world', False),
13+
('"hello world"', True),
14+
],
15+
)
16+
def test_is_txt_record_quoted(value: str, expected: bool):
17+
assert is_txt_record_quoted(value) == expected
18+
19+
20+
manyA = "a" * 255
21+
someB = "b" * 10
22+
23+
24+
@pytest.mark.parametrize(
25+
("value", "expected"),
26+
[
27+
("", ""),
28+
('""', '"\\"\\""'),
29+
("hello world", '"hello world"'),
30+
("hello\nworld", '"hello\nworld"'),
31+
('hello "world"', '"hello \\"world\\""'),
32+
('hello "world', '"hello \\"world"'),
33+
(manyA + someB, f'"{manyA}" "{someB}"'),
34+
],
35+
)
36+
def test_format_txt_record(value: str, expected: str):
37+
assert format_txt_record(value) == expected

0 commit comments

Comments
 (0)