"""Ties & transform API"""
import typing
from ._binding import Target, coerce_binding
class _Transformable(Transform):
def __init__(self, transform: Transform):
super().__init__()
self.args['transform'] = transform
class _Comparable(Transform):
def __init__(self, comparison: Transform):
super().__init__()
self.args['comparison'] = comparison
class _ValueTransform(Transform):
def __init__(self, value: typing.Any):
super().__init__()
self.args['value'] = value
class _TargetTransform(Transform):
def __init__(self, target: typing.Union[str, Target]):
super().__init__()
self.args['target'] = coerce_binding(target, Target)
class _Comparison(Transform):
def __init__(self, other):
super().__init__()
self.args['other'] = other
# Number transform
[docs]class Add(_ValueTransform):
"""Perform an addition on the chain value."""
[docs]class Sub(_ValueTransform):
"""Subtract values."""
[docs]class Divide(_ValueTransform):
"""Division operation Left / Right"""
[docs]class Multiply(_ValueTransform):
"""Multiply chain value * value"""
[docs]class Modulus(_ValueTransform):
"""Perform a modulus operation on the chain."""
[docs]class ToPrecision(Transform):
[docs] def __init__(self, precision: int):
super().__init__()
self.args['precision'] = precision
# String transform
[docs]class Split(Transform):
"""Split a string value into a list."""
[docs] def __init__(self, separator: str):
super().__init__()
self.args['separator'] = separator
[docs]class ToLower(Transform):
"""Transform a string chained value to lower case."""
[docs]class ToUpper(Transform):
"""Transform a string chained value to upper case."""
[docs]class Trim(Transform):
"""Trim whitespace around a chained string value."""
# List transforms
[docs]class Concat(Transform):
"""
Concat a list or string into a new string/list containing entries
from both sides.
"""
[docs] def __init__(self, other: typing.Union[list, str]):
super().__init__()
self.args['other'] = other
[docs]class Slice(Transform):
"""Take a slice of a list from ``start`` to ``stop``."""
[docs] def __init__(self, start: int, stop: int):
super().__init__()
self.args['start'] = start
self.args['stop'] = stop
[docs]class Map(_Transformable):
"""
Map a chained array values.
"""
[docs]class Reduce(_Transformable):
"""Reduce the list value"""
[docs]class Filter(_Comparable):
"""Filter elements of the list"""
[docs]class Pluck(Transform):
"""
Take a value at ``field`` from a list of objects.
.. code-block:: python
from dazzler.system.transforms import RawValue, Pluck
RawValue([{'a': 1, 'b': 2, 'c': 3}]).t(Pick('a'))
# => [1]
"""
[docs] def __init__(self, field: str):
super().__init__()
self.args['field'] = field
[docs]class Append(_ValueTransform):
"""Append a value a the end of the chained list."""
[docs]class Prepend(_ValueTransform):
"""Prepend a value at the beginning of the list."""
[docs]class Insert(_TargetTransform):
"""Insert the value into the target list."""
[docs] def __init__(self, target, front=False):
super().__init__(target)
self.args['front'] = front
[docs]class Take(Transform):
"""Take the first `n` elements of the list."""
[docs] def __init__(self, n: int):
super().__init__()
self.args['n'] = n
[docs]class Length(Transform):
"""Resolve the length of the list."""
[docs]class Range(Transform):
"""Return an array of number from ``start`` to ``end``"""
[docs] def __init__(self, start: int, end: int, step: int = 1):
super().__init__()
self.args['start'] = start
self.args['end'] = end
self.args['step'] = step
[docs]class Includes(_ValueTransform):
"""True if value is included in the chained list."""
[docs]class Find(_Comparable):
"""
Find an item in a list with a comparison.
.. code-block:: python
from dazzler.system.transforms import RawValue, Find, Get, Equals
RawValue([{'a': 'a', 'b': 'b'}, {'a': 'b', 'b': 'a'}])\
.transform(Find(Get('a').t(Equals('b'))))
# => {'a': 'b', 'b': 'a'}
"""
[docs]class Join(Transform):
[docs] def __init__(self, separator):
super().__init__()
self.args['separator'] = separator
[docs]class Reverse(Transform):
"""Reverse a string or array elements."""
[docs]class Unique(Transform):
"""Filter duplicates out of the list."""
[docs]class Zip(_ValueTransform):
"""Associates values from each list"""
[docs]class Sort(_Transformable):
"""Sort transform should return a number"""
[docs]class ToPairs(Transform):
"""Transform an object into pairs of [key, value]"""
[docs]class FromPairs(Transform):
"""Transform a list of list of key value pairs into an object."""
# Object transforms
[docs]class Pick(Transform):
"""
Pick the fields of the object.
.. code-block:: python
from dazzler.system.transforms import RawValue, Pick
RawValue({'a': 1, 'b': 2, 'c': 3}).t(Pick(['a', 'b']))
# => {'a': 1, 'b': 2}
"""
[docs] def __init__(self, fields: typing.List[str]):
super().__init__()
self.args['fields'] = fields
[docs]class Get(Transform):
"""Get the field value of the chain object."""
[docs] def __init__(self, field: str):
super().__init__()
self.args['field'] = field
[docs]class Set(Transform):
"""
Set the key value on the trigger value.
Value can be raw or a :py:class:`dazzler.system.Target` aspect.
"""
[docs] def __init__(self, key: str, value: typing.Any):
"""
:param key:
:param value:
"""
super().__init__()
self.args['key'] = key
self.args['value'] = value
[docs]class Put(Transform):
"""
Put the value at key on target
Target should be a dict or a `~.dazzler.system.Target` aspect
resolving to a dict.
"""
[docs] def __init__(self, key: str, target):
super().__init__()
self.args['key'] = key
self.args['target'] = target
[docs]class Merge(Transform):
"""
Merge a chained ``dict`` value with another ``dict``, either raw value
or a :py:class:`~.dazzler.system.Target` aspect.
.. code-block:: python
from dazzler.system.transforms import RawValue, Merge
RawValue({'a': 1}).transform(Merge({'b': 2}))
# => {'a': 1, 'b': 2}
"""
[docs] def __init__(self, other, direction='right', deep=False):
super().__init__()
self.args['other'] = other
self.args['direction'] = direction
self.args['deep'] = deep
[docs]class ToJson(Transform):
"""Serialize the chain value to JSON."""
[docs]class FromJson(Transform):
"""Parse the chain value from JSON."""
# Conditionals
[docs]class If(_Comparable):
"""
Initiate a comparison on the value.
``then`` is execute if the comparison is ``True`` else ``otherwise`` will
be executed if defined.
.. code-block:: python
from dazzler.system.transforms import If, RawValue, Equals, Format
RawValue('foo').t(If(Equals('foo'), then=Format('${value} bar')))
"""
[docs] def __init__(self, comparison, then, otherwise=None):
super().__init__(comparison)
self.args['then'] = then
self.args['otherwise'] = otherwise
[docs]class Equals(_Comparison):
pass
[docs]class NotEquals(_Comparison):
pass
[docs]class Match(_Comparison):
pass
[docs]class Greater(_Comparison):
pass
[docs]class GreaterOrEquals(_Comparison):
pass
[docs]class Lesser(_Comparison):
pass
[docs]class LesserOrEquals(_Comparison):
pass
[docs]class And(_Comparison):
pass
[docs]class Or(_Comparison):
pass
[docs]class Not(Transform):
pass
[docs]class RawValue(_ValueTransform):
"""Resolve a raw value."""
[docs]class AspectValue(_TargetTransform):
"""Resolve the target value."""