aboutsummaryrefslogtreecommitdiff
path: root/tools/cru-py/cru/_list.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/cru-py/cru/_list.py')
-rw-r--r--tools/cru-py/cru/_list.py104
1 files changed, 51 insertions, 53 deletions
diff --git a/tools/cru-py/cru/_list.py b/tools/cru-py/cru/_list.py
index f1965db..45122bf 100644
--- a/tools/cru-py/cru/_list.py
+++ b/tools/cru-py/cru/_list.py
@@ -1,77 +1,75 @@
+from __future__ import annotations
+from collections.abc import Callable
+from typing import Generic, Iterable, Self, TypeAlias, TypeVar
+from ._iter import CruIterable
-class CruInplaceList(CruList, Generic[_V]):
+_T = TypeVar("_T")
- def clear(self) -> "CruInplaceList[_V]":
- self.clear()
- return self
- def extend(self, *l: Iterable[_V]) -> "CruInplaceList[_V]":
- self.extend(l)
- return self
+class CruListEdit(CruIterable.Wrapper[_T]):
+ def done(self) -> CruList[_T]:
+ l: CruList[_T] = self.my_attr["list"]
+ l.reset(self)
+ return l
- def reset(self, *l: Iterable[_V]) -> "CruInplaceList[_V]":
+
+class CruList(list[_T]):
+ def reset(self, new_values: Iterable[_T]):
+ if self is new_values:
+ new_values = list(new_values)
self.clear()
- self.extend(l)
+ self.extend(new_values)
return self
- def transform(self, *f: OptionalElementTransformer) -> "CruInplaceList"[Any]:
- return self.reset(super().transform(*f))
-
- def transform_if(
- self, f: OptionalElementTransformer, p: ElementPredicate[_V]
- ) -> "CruInplaceList"[Any]:
- return self.reset(super().transform_if(f, p))
+ def as_iterable_wrapper(self) -> CruIterable.Wrapper[_T]:
+ return CruIterable.Wrapper(self)
- def remove_by_indices(self, *index: int) -> "CruInplaceList"[_V]:
- return self.reset(super().remove_by_indices(*index))
-
- def remove_all_if(self, p: ElementPredicate[_V]) -> "CruInplaceList"[_V]:
- return self.reset(super().remove_all_if(p))
-
- def remove_all_value(self, *r: Any) -> "CruInplaceList"[_V]:
- return self.reset(super().remove_all_value(*r))
-
- def replace_all_value(
- self, old_value: Any, new_value: R
- ) -> "CruInplaceList"[_V | R]:
- return self.reset(super().replace_all_value(old_value, new_value))
+ def as_edit_iterable_wrapper(self) -> CruListEdit[_T]:
+ return CruListEdit(self, attr={"list": self})
@staticmethod
- def make(l: CanBeList[_V]) -> "CruInplaceList"[_V]:
- return CruInplaceList(ListOperations.make(l))
-
+ def make(maybe_list: Iterable[_T] | _T | None) -> CruList[_T]:
+ if maybe_list is None:
+ return CruList()
+ if isinstance(maybe_list, Iterable):
+ return CruList(maybe_list)
+ return CruList([maybe_list])
-K = TypeVar("K")
+_K = TypeVar("_K")
+_KeyGetter: TypeAlias = Callable[[_T], _K]
-class CruUniqueKeyInplaceList(Generic[_V, K]):
- KeyGetter = Callable[[_V], K]
+class CruUniqueKeyList(Generic[_T, _K]):
def __init__(
- self, get_key: KeyGetter, *, before_add: Callable[[_V], _V] | None = None
+ self,
+ key_getter: _KeyGetter[_T, _K],
+ *,
+ before_add: Callable[[_T], _T] | None = None,
):
super().__init__()
- self._get_key = get_key
+ self._key_getter = key_getter
self._before_add = before_add
- self._l: CruInplaceList[_V] = CruInplaceList()
+ self._list: CruList[_T] = CruList()
@property
- def object_key_getter(self) -> KeyGetter:
- return self._get_key
+ def key_getter(self) -> _KeyGetter[_T, _K]:
+ return self._key_getter
@property
- def internal_list(self) -> CruInplaceList[_V]:
- return self._l
+ def internal_list(self) -> CruList[_T]:
+ return self._list
def validate_self(self):
- keys = self._l.transform(self._get_key)
+ keys = self._list.transform(self._key_getter)
if len(keys) != len(set(keys)):
raise ValueError("Duplicate keys!")
- def get_or(self, k: K, fallback: Any = CRU_NOT_FOUND) -> _V | Any:
- r = self._l.find_if(lambda i: k == self._get_key(i))
+ # TODO: Continue here!
+ def get_or(self, key: K, fallback: Any = CRU_NOT_FOUND) -> _V | Any:
+ r = self._l.find_if(lambda i: k == self._key_getter(i))
return r if r is not CRU_NOT_FOUND else fallback
def get(self, k: K) -> _V:
@@ -84,10 +82,10 @@ class CruUniqueKeyInplaceList(Generic[_V, K]):
return self.get_or(k, CRU_NOT_FOUND) is not CRU_NOT_FOUND
def has_any_key(self, *k: K) -> bool:
- return self._l.any(lambda i: self._get_key(i) in k)
+ return self._l.any(lambda i: self._key_getter(i) in k)
def try_remove(self, k: K) -> bool:
- i = self._l.find_index_if(lambda v: k == self._get_key(v))
+ i = self._l.find_index_if(lambda v: k == self._key_getter(v))
if i is CRU_NOT_FOUND:
return False
self._l.remove_by_indices(i)
@@ -98,11 +96,11 @@ class CruUniqueKeyInplaceList(Generic[_V, K]):
raise KeyError(f"Key {k} not found!")
def add(self, v: _V, /, replace: bool = False) -> None:
- if self.has_key(self._get_key(v)):
+ if self.has_key(self._key_getter(v)):
if replace:
- self.remove(self._get_key(v))
+ self.remove(self._key_getter(v))
else:
- raise ValueError(f"Key {self._get_key(v)} already exists!")
+ raise ValueError(f"Key {self._key_getter(v)} already exists!")
if self._before_add is not None:
v = self._before_add(v)
self._l.append(v)
@@ -111,12 +109,12 @@ class CruUniqueKeyInplaceList(Generic[_V, K]):
self.add(v, True)
def extend(self, l: Iterable[_V], /, replace: bool = False) -> None:
- if not replace and self.has_any_key([self._get_key(i) for i in l]):
+ if not replace and self.has_any_key([self._key_getter(i) for i in l]):
raise ValueError("Keys already exists!")
if self._before_add is not None:
l = [self._before_add(i) for i in l]
- keys = [self._get_key(i) for i in l]
- self._l.remove_all_if(lambda i: self._get_key(i) in keys).extend(l)
+ keys = [self._key_getter(i) for i in l]
+ self._l.remove_all_if(lambda i: self._key_getter(i) in keys).extend(l)
def clear(self) -> None:
self._l.clear()