Source code for fastpyxl.descriptors.nested

# Copyright (c) 2010-2024 fastpyxl

"""
Generic serialisable classes.
"""

from fastpyxl.compat import safe_string
from fastpyxl.xml.functions import Element, localname, whitespace

from .base import Bool, Convertible, Descriptor, Float, Integer, MinMax, NoneSet, Set, String


[docs] class Nested(Descriptor): nested = True attribute = "val" def __set__(self, instance, value): if hasattr(value, "tag"): tag = localname(value) if tag != self.name: raise ValueError("Tag does not match attribute") value = self.from_tree(value) super().__set__(instance, value)
[docs] def from_tree(self, node): return node.get(self.attribute)
[docs] def to_tree(self, tagname=None, value=None, namespace=None): namespace = self.namespace or namespace if value is not None: if namespace is not None: tagname = "{%s}%s" % (namespace, tagname) assert tagname is not None value = safe_string(value) return Element(tagname, {self.attribute: value})
[docs] class NestedValue(Nested, Convertible): """ Nested tag storing the value on the 'val' attribute. """
[docs] class NestedText(NestedValue): """ Represents any nested tag with the value as the contents of the tag. """
[docs] def from_tree(self, node): return node.text
[docs] def to_tree(self, tagname=None, value=None, namespace=None): namespace = self.namespace or namespace if value is not None: if namespace is not None: tagname = "{%s}%s" % (namespace, tagname) assert tagname is not None el = Element(tagname) el.text = safe_string(value) whitespace(el) return el
[docs] class NestedFloat(NestedValue, Float): pass
[docs] class NestedInteger(NestedValue, Integer): pass
[docs] class NestedString(NestedValue, String): pass
[docs] class NestedBool(NestedValue, Bool):
[docs] def from_tree(self, node): return node.get("val", True)
[docs] class NestedNoneSet(Nested, NoneSet): pass
[docs] class NestedSet(Nested, Set): pass
[docs] class NestedMinMax(Nested, MinMax): pass
[docs] class EmptyTag(Nested, Bool): """ Boolean if a tag exists or not. """
[docs] def from_tree(self, node): return True
[docs] def to_tree(self, tagname=None, value=None, namespace=None): if value: namespace = self.namespace or namespace if namespace is not None: tagname = "{%s}%s" % (namespace, tagname) assert tagname is not None return Element(tagname)