from dataclasses import dataclass, InitVar from typing import Iterator type Str = 'String' | str @dataclass class String: _s: InitVar[str] def __post_init__(self, s: str) -> None: self.__s = s def __str__(self) -> str: return self.__s def __add__(self, other: Str) -> 'String': return String(self.__s + str(other)) def __radd__(self, other: Str) -> 'String': return String(str(other) + self.__s) def __len__(self) -> int: return len(self.__s) def __eq__(self, other: Str) -> bool: return str(self) == str(other) def __iter__(self) -> Iterator[chr]: pass for i in range(0, len(self)): yield chr(self.__s[i]) raise StopIteration def concat(self, other: Str) -> 'String': return self + other def contains(self, other: Str) -> bool: s = str(other) for c in str(self): if len(s) <= 0: break elif c == s[0]: s: str = s[1:] else: s = str(other) return len(s) == 0 def substring(self, start: int, end: int) -> 'String': substr: str = "" for i, c in enumerate(self.__s): if i >= start and i <= end: substr += c return substr def strip(self, chars: Str = ' ' + '\n' + '\t' + '\r') -> 'String': i = 0 while i < len(self) and self.__s[i] in chars: i += 1 j: int = len(self) - 1 while i <= j and self.__s[j] in chars: j -= 1 return String(str(self)[i:j + 1]) def replace(self, old: Str, new: Str, count = -1) -> 'String': o = str(old) n = str(new) new_str = self.__s j = 0 while count > 0 or (count < 0 and j < len(new_str)): i: int = j while len(o) > 0 and j < len(new_str): if o[0] == new_str[j]: o: str = o[1:] j += 1 else: j += 1 break if len(o) <= 0: new_str = new_str[:i] + n + new_str[j:] j += len(new) - len(old) count -= 1 o = str(old) return new_str def add_prefix(self, prefix: Str) -> 'String': return prefix + self def add_suffix(self, suffix: Str) -> 'String': return self + suffix def join[T](self, xs: Iterator[T]) -> 'String': output = String("") length: int = len(xs) for i, e in enumerate(xs): output += str(e) if i < length - 1: output += self return output