diff --git a/hcloud/exp/__init__.py b/hcloud/exp/__init__.py new file mode 100644 index 00000000..1f470551 --- /dev/null +++ b/hcloud/exp/__init__.py @@ -0,0 +1,4 @@ +""" +The `exp` module is a namespace that holds experimental features for the `hcloud-python` +library, breaking changes may occur within minor releases. +""" diff --git a/hcloud/exp/zone.py b/hcloud/exp/zone.py new file mode 100644 index 00000000..08601286 --- /dev/null +++ b/hcloud/exp/zone.py @@ -0,0 +1,35 @@ +""" +The `exp.zone` module is a namespace that holds experimental features for the `hcloud-python` +library, breaking changes may occur within minor releases. +""" + +from __future__ import annotations + + +def is_txt_record_quoted(value: str) -> bool: + """ + Check whether a TXT record is already quoted. + + - hello world => false + - "hello world" => true + """ + return value.startswith('"') and value.endswith('"') + + +def format_txt_record(value: str) -> str: + """ + Format a TXT record by splitting it in quoted strings of 255 characters. + Existing quotes will be escaped. + + - hello world => "hello world" + - hello "world" => "hello \"world\"" + """ + value = value.replace('"', '\\"') + + parts = [] + for start in range(0, len(value), 255): + end = min(start + 255, len(value)) + parts.append('"' + value[start:end] + '"') + value = " ".join(parts) + + return value diff --git a/tests/unit/exp/__init__.py b/tests/unit/exp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/exp/test_zone.py b/tests/unit/exp/test_zone.py new file mode 100644 index 00000000..b595111d --- /dev/null +++ b/tests/unit/exp/test_zone.py @@ -0,0 +1,37 @@ +from __future__ import annotations + +import pytest + +from hcloud.exp.zone import format_txt_record, is_txt_record_quoted + + +@pytest.mark.parametrize( + ("value", "expected"), + [ + ("hello world", False), + ('"hello world', False), + ('"hello world"', True), + ], +) +def test_is_txt_record_quoted(value: str, expected: bool): + assert is_txt_record_quoted(value) == expected + + +manyA = "a" * 255 +someB = "b" * 10 + + +@pytest.mark.parametrize( + ("value", "expected"), + [ + ("", ""), + ('""', '"\\"\\""'), + ("hello world", '"hello world"'), + ("hello\nworld", '"hello\nworld"'), + ('hello "world"', '"hello \\"world\\""'), + ('hello "world', '"hello \\"world"'), + (manyA + someB, f'"{manyA}" "{someB}"'), + ], +) +def test_format_txt_record(value: str, expected: str): + assert format_txt_record(value) == expected