text: from cytoolz.curried import get_in, merge, update_in, reduce, pipe, map, filter
  from attr import attrib, attrs, fields, asdict
  
  
  def serde(cls=None, from_key="from", to_key="to"):
      def serde_with_class(cls):
          from_fields = list(
              map(lambda a: (a, get_in([from_key], a.metadata, [a.name])), fields(cls))
          )
  
          to_fields = pipe(
              fields(cls),
              map(lambda a: (a, get_in([to_key], a.metadata))),
              filter(lambda f: f[1]),
              list,
          )
  
          def from_dict(d):
              return cls(
                  **dict(
                      map(
                          lambda f: (f[0].name, get_in(f[1], d, f[0].default)),
                          from_fields,
                      )
                  )
              )
  
          def to_dict(self):
              d = asdict(self)
              if not to_fields:
                  return d
  
              return reduce(
                  lambda acc, f: update_in(acc, f[1], lambda _: d[f[0].name]),
                  to_fields,
                  {},
              )
  
          cls.from_dict = staticmethod(from_dict)
          cls.to_dict = to_dict
          return cls
  
      if cls:
          return serde_with_class(cls)
      else:
          return serde_with_class