Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: format specific (de)serialize #25

Merged
merged 1 commit into from
Oct 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions serializable/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def default(self, o: Any) -> Any:

if prop_info.custom_type:
if prop_info.is_helper_type():
v = prop_info.custom_type.serialize(v)
v = prop_info.custom_type.json_serialize(v)
else:
v = prop_info.custom_type(v)
elif prop_info.is_array:
Expand Down Expand Up @@ -286,7 +286,7 @@ def _from_json(cls: Type[_T], data: Dict[str, Any]) -> object:
try:
if prop_info.custom_type:
if prop_info.is_helper_type():
_data[k] = prop_info.custom_type.deserialize(v)
_data[k] = prop_info.custom_type.json_deserialize(v)
else:
_data[k] = prop_info.custom_type(v)
elif prop_info.is_array:
Expand Down Expand Up @@ -349,7 +349,7 @@ def _as_xml(self: _T, view_: Optional[Type[_T]] = None, as_string: bool = True,
new_key = CurrentFormatter.formatter.encode(property_name=new_key)

if prop_info.custom_type and prop_info.is_helper_type():
v = prop_info.custom_type.serialize(v)
v = prop_info.custom_type.xml_serialize(v)
elif prop_info.is_enum:
v = v.value

Expand Down Expand Up @@ -413,7 +413,7 @@ def _as_xml(self: _T, view_: Optional[Type[_T]] = None, as_string: bool = True,
SubElement(nested_e, nested_key).text = str(j)
elif prop_info.custom_type:
if prop_info.is_helper_type():
SubElement(this_e, new_key).text = str(prop_info.custom_type.serialize(v))
SubElement(this_e, new_key).text = str(prop_info.custom_type.xml_serialize(v))
else:
SubElement(this_e, new_key).text = str(prop_info.custom_type(v))
elif prop_info.is_enum:
Expand Down Expand Up @@ -485,7 +485,7 @@ def _from_xml(cls: Type[_T], data: Union[TextIOWrapper, Element],
f'{cls.__module__}.{cls.__qualname__} which has Prop Metadata: {prop_info}')

if prop_info.custom_type and prop_info.is_helper_type():
_data[decoded_k] = prop_info.custom_type.deserialize(v)
_data[decoded_k] = prop_info.custom_type.xml_deserialize(v)
elif prop_info.is_enum:
_data[decoded_k] = prop_info.concrete_type(v)
elif prop_info.is_primitive_type():
Expand Down Expand Up @@ -552,14 +552,14 @@ def _from_xml(cls: Type[_T], data: Union[TextIOWrapper, Element],
)
elif prop_info.custom_type:
if prop_info.is_helper_type():
_data[decoded_k] = prop_info.custom_type.deserialize(child_e)
_data[decoded_k] = prop_info.custom_type.xml_deserialize(child_e)
else:
_data[decoded_k] = prop_info.custom_type(child_e.text)
else:
_data[decoded_k].append(prop_info.concrete_type(child_e.text))
elif prop_info.custom_type:
if prop_info.is_helper_type():
_data[decoded_k] = prop_info.custom_type.deserialize(child_e.text)
_data[decoded_k] = prop_info.custom_type.xml_deserialize(child_e.text)
else:
_data[decoded_k] = prop_info.custom_type(child_e.text)
elif prop_info.is_enum:
Expand Down
55 changes: 45 additions & 10 deletions serializable/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,60 @@
# Copyright (c) Paul Horton. All Rights Reserved.
import re
import warnings
from abc import ABC, abstractmethod
from datetime import date, datetime
from typing import Any


class BaseHelper(ABC):
class BaseHelper:
"""Base Helper.

def __init__(self, *args: Any, **kwargs: Any) -> None:
pass
Inherit from this class and implement the needed functions!

This class does not provide any functionality,
it is more like a Protocol with some fallback implementations.
"""

# region general/fallback

@classmethod
def serialize(cls, o: Any) -> Any:
"""general purpose serializer"""
raise NotImplementedError()

@classmethod
def deserialize(cls, o: Any) -> Any:
"""general purpose deserializer"""
raise NotImplementedError()

# endregion general/fallback

# region json specific

@classmethod
@abstractmethod
def serialize(cls, o: object) -> Any:
raise NotImplementedError
def json_serialize(cls, o: Any) -> Any:
"""json specific serializer"""
return cls.serialize(o)

@classmethod
@abstractmethod
def deserialize(cls, o: str) -> Any:
raise NotImplementedError
def json_deserialize(cls, o: Any) -> Any:
"""json specific deserializer"""
return cls.deserialize(o)

# endregion json specific

# endregion xml specific

@classmethod
def xml_serialize(cls, o: Any) -> Any:
"""xml specific serializer"""
return cls.serialize(o)

@classmethod
def xml_deserialize(cls, o: Any) -> Any:
"""xml specific deserializer"""
return cls.deserialize(o)

# endregion xml specific


class Iso8601Date(BaseHelper):
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-camel-case-1-v1.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<book isbnNumber="978-1942788294">
<id>f3758bf0-0ff7-4366-a5e5-c209d4352b2d</id>
<title>The Phoenix Project</title>
<title>{X} The Phoenix Project</title>
<edition number="5">5th Anniversary Limited Edition</edition>
<publishDate>2018-04-16</publishDate>
<author>Kevin Behr</author>
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-camel-case-1-v2.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<book isbnNumber="978-1942788294">
<id>f3758bf0-0ff7-4366-a5e5-c209d4352b2d</id>
<title>The Phoenix Project</title>
<title>{X} The Phoenix Project</title>
<edition number="5">5th Anniversary Limited Edition</edition>
<publishDate>2018-04-16</publishDate>
<author>Kevin Behr</author>
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-camel-case-1-v3.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<book isbnNumber="978-1942788294">
<id>f3758bf0-0ff7-4366-a5e5-c209d4352b2d</id>
<title>The Phoenix Project</title>
<title>{X} The Phoenix Project</title>
<edition number="5">5th Anniversary Limited Edition</edition>
<publishDate>2018-04-16</publishDate>
<author>Kevin Behr</author>
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-camel-case-1-v4.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<book isbnNumber="978-1942788294">
<id>f3758bf0-0ff7-4366-a5e5-c209d4352b2d</id>
<title>The Phoenix Project</title>
<title>{X} The Phoenix Project</title>
<edition number="5">5th Anniversary Limited Edition</edition>
<publishDate>2018-04-16</publishDate>
<author>Kevin Behr</author>
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-camel-case-1.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<book isbnNumber="978-1942788294">
<id>f3758bf0-0ff7-4366-a5e5-c209d4352b2d</id>
<title>The Phoenix Project</title>
<title>{X} The Phoenix Project</title>
<edition number="5">5th Anniversary Limited Edition</edition>
<publishDate>2018-04-16</publishDate>
<author>Kevin Behr</author>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "f3758bf0-0ff7-4366-a5e5-c209d4352b2d",
"title": "The Phoenix Project",
"title": "{J} The Phoenix Project",
"isbnNumber": "978-1942788294",
"edition": {
"number": 5,
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-camel-case-v2.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "f3758bf0-0ff7-4366-a5e5-c209d4352b2d",
"title": "The Phoenix Project",
"title": "{J} The Phoenix Project",
"isbnNumber": "978-1942788294",
"edition": {
"number": 5,
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-camel-case-v3.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "f3758bf0-0ff7-4366-a5e5-c209d4352b2d",
"title": "The Phoenix Project",
"title": "{J} The Phoenix Project",
"isbnNumber": "978-1942788294",
"edition": {
"number": 5,
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-camel-case-v4.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "f3758bf0-0ff7-4366-a5e5-c209d4352b2d",
"title": "The Phoenix Project",
"title": "{J} The Phoenix Project",
"isbnNumber": "978-1942788294",
"edition": {
"number": 5,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"something_to_be_ignored": "some_value",
"title": "The Phoenix Project",
"title": "{J} The Phoenix Project",
"isbnNumber": "978-1942788294",
"edition": {
"number": 5,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<book isbnNumber="978-1942788294" ignoreMe="something">
<ignored>thing</ignored>
<title>The Phoenix Project</title>
<title>{X} The Phoenix Project</title>
<edition number="5">5th Anniversary Limited Edition</edition>
<publishDate>2018-04-16</publishDate>
<author>Kevin Behr</author>
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-camel-case.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "f3758bf0-0ff7-4366-a5e5-c209d4352b2d",
"title": "The Phoenix Project",
"title": "{J} The Phoenix Project",
"isbnNumber": "978-1942788294",
"edition": {
"number": 5,
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-kebab-case-1-v2.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<book isbn-number="978-1942788294">
<id>f3758bf0-0ff7-4366-a5e5-c209d4352b2d</id>
<title>The Phoenix Project</title>
<title>{X} The Phoenix Project</title>
<edition number="5">5th Anniversary Limited Edition</edition>
<publish-date>2018-04-16</publish-date>
<author>Kevin Behr</author>
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-kebab-case-1.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<book isbn-number="978-1942788294">
<id>f3758bf0-0ff7-4366-a5e5-c209d4352b2d</id>
<title>The Phoenix Project</title>
<title>{X} The Phoenix Project</title>
<edition number="5">5th Anniversary Limited Edition</edition>
<publish-date>2018-04-16</publish-date>
<author>Kevin Behr</author>
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-kebab-case.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "f3758bf0-0ff7-4366-a5e5-c209d4352b2d",
"title": "The Phoenix Project",
"title": "{J} The Phoenix Project",
"isbn-number": "978-1942788294",
"edition": {
"number": 5,
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-snake-case-1.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<book isbn_number="978-1942788294">
<id>f3758bf0-0ff7-4366-a5e5-c209d4352b2d</id>
<title>The Phoenix Project</title>
<title>{X} The Phoenix Project</title>
<edition number="5">5th Anniversary Limited Edition</edition>
<publish_date>2018-04-16</publish_date>
<author>Kevin Behr</author>
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/the-phoenix-project-snake-case.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "f3758bf0-0ff7-4366-a5e5-c209d4352b2d",
"title": "The Phoenix Project",
"title": "{J} The Phoenix Project",
"isbn_number": "978-1942788294",
"edition": {
"number": 5,
Expand Down
21 changes: 21 additions & 0 deletions tests/model.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# encoding: utf-8
import re

# This file is part of py-serializable
#
Expand Down Expand Up @@ -68,6 +69,25 @@ def deserialize(cls, o: object) -> Set["BookReference"]:
raise ValueError(f'Attempt to deserialize a non-set: {o.__class__}')


class TitleMapper(BaseHelper):

@classmethod
def json_serialize(cls, o: str) -> str:
return f'{{J}} {o}'

@classmethod
def json_deserialize(cls, o: str) -> str:
return re.sub(r'^\{J} ', '', o)

@classmethod
def xml_serialize(cls, o: str) -> str:
return f'{{X}} {o}'

@classmethod
def xml_deserialize(cls, o: str) -> str:
return re.sub(r'^\{X} ', '', o)


@serializable.serializable_class
class Chapter:

Expand Down Expand Up @@ -223,6 +243,7 @@ def id(self) -> UUID:

@property # type: ignore[misc]
@serializable.xml_sequence(2)
@serializable.type_mapping(TitleMapper)
def title(self) -> str:
return self._title

Expand Down