budget/pfbudget/utils/serializer.py

55 lines
1.3 KiB
Python

from collections.abc import Mapping
from dataclasses import fields
from functools import singledispatch
from typing import Any
from pfbudget.db.model import Transaction, TransactionCategory, TransactionTag, Note
class NotSerializableError(Exception):
pass
@singledispatch
def serialize(obj: Any) -> Mapping[str, Any]:
return {field.name: getattr(obj, field.name) for field in fields(obj)}
@serialize.register
def _(obj: Transaction) -> Mapping[str, Any]:
category = None
if obj.category:
category = {
"name": obj.category.name,
"selector": str(obj.category.selector.selector)
if obj.category.selector
else None,
}
return dict(
id=obj.id,
date=obj.date.isoformat(),
description=obj.description,
amount=str(obj.amount),
split=obj.split,
category=category if category else None,
tags=[{"tag": tag.tag} for tag in obj.tags],
note=obj.note,
type=obj.type,
)
@serialize.register
def _(_: TransactionCategory) -> Mapping[str, Any]:
raise NotSerializableError("TransactionCategory")
@serialize.register
def _(_: TransactionTag) -> Mapping[str, Any]:
raise NotSerializableError("TransactionTag")
@serialize.register
def _(_: Note) -> Mapping[str, Any]:
raise NotSerializableError("Note")