From 318079d18c53a5f5bb20cfee57a9d425dc848c5c Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Mon, 4 Dec 2023 16:04:03 -0800 Subject: [PATCH] more array funcs --- .../script/functions/array_functions.py | 37 +++++++++++++++++++ src/ytdl_sub/script/utils/exceptions.py | 4 ++ .../script/functions/test_array_functions.py | 12 ++++++ 3 files changed, 53 insertions(+) diff --git a/src/ytdl_sub/script/functions/array_functions.py b/src/ytdl_sub/script/functions/array_functions.py index 809c53fc..b2e31fee 100644 --- a/src/ytdl_sub/script/functions/array_functions.py +++ b/src/ytdl_sub/script/functions/array_functions.py @@ -1,11 +1,16 @@ from typing import List +from typing import Optional from ytdl_sub.script.types.array import Array from ytdl_sub.script.types.array import ResolvedArray +from ytdl_sub.script.types.resolvable import AnyArgument +from ytdl_sub.script.types.resolvable import Boolean from ytdl_sub.script.types.resolvable import Integer from ytdl_sub.script.types.resolvable import Lambda from ytdl_sub.script.types.resolvable import LambdaTwo from ytdl_sub.script.types.resolvable import Resolvable +from ytdl_sub.script.utils.exceptions import UNREACHABLE +from ytdl_sub.script.utils.exceptions import ArrayValueDoesNotExist class ArrayFunctions: @@ -27,6 +32,38 @@ class ArrayFunctions: """ return array.value[idx.value] + @staticmethod + def array_contains(array: Array, value: AnyArgument) -> Boolean: + """ + Return True if the value exists in the Array. False otherwise. + """ + return Boolean(value in array.value) + + @staticmethod + def array_index(array: Array, value: AnyArgument) -> Integer: + """ + Return the index of the value within the Array if it exists. If it does not, it will + throw an error. + """ + if not ArrayFunctions.array_contains(array=array, value=value): + raise ArrayValueDoesNotExist( + "Tried to get the index of a value in an Array that does not exist" + ) + + if isinstance(value, Resolvable): + return Integer(array.value.index(value)) + + raise UNREACHABLE + + @staticmethod + def array_slice(array: Array, start: Integer, end: Optional[Integer] = None) -> Array: + """ + Returns the slice of the Array. + """ + if end is not None: + return ResolvedArray(array.value[start.value : end.value]) + return ResolvedArray(array.value[start.value :]) + @staticmethod def array_flatten(array: Array) -> Array: """ diff --git a/src/ytdl_sub/script/utils/exceptions.py b/src/ytdl_sub/script/utils/exceptions.py index b6845971..fdf95545 100644 --- a/src/ytdl_sub/script/utils/exceptions.py +++ b/src/ytdl_sub/script/utils/exceptions.py @@ -76,6 +76,10 @@ class KeyNotHashableRuntimeException(RuntimeException): """Map tried to use a non-hashable key at runtime""" +class ArrayValueDoesNotExist(RuntimeException): + """Tried to get an index of a value in an Array that does not exist""" + + class FunctionDoesNotExistRuntimeException(RuntimeException): """Tried to get a function that does not exist""" diff --git a/tests/unit/script/functions/test_array_functions.py b/tests/unit/script/functions/test_array_functions.py index 6534076c..8397b2eb 100644 --- a/tests/unit/script/functions/test_array_functions.py +++ b/tests/unit/script/functions/test_array_functions.py @@ -28,6 +28,18 @@ class TestArrayFunctions: output = single_variable_output("{%array_flatten(['a', ['b'], [['c']]])}") assert output == ["a", "b", "c"] + def test_array_contains(self): + output = single_variable_output("{%array_contains(['a', ['b'], [['c']]], [['c']])}") + assert output is True + + def test_array_index(self): + output = single_variable_output("{%array_index(['a', ['b'], [['c']]], [['c']])}") + assert output == 2 + + def test_array_slice(self): + output = single_variable_output("{%array_slice(['a', ['b'], [['c']]], 1, -1)}") + assert output == [["b"]] + def test_array_reverse(self): output = single_variable_output("{%array_reverse(['a', 'b', 'c'])}") assert output == ["c", "b", "a"]