VWED_server/utils/built_in_functions.py

275 lines
8.4 KiB
Python
Raw Normal View History

2025-04-30 16:57:46 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
内置函数管理模块
为任务编辑器提供系统内置函数信息
支持异步函数调用
"""
import asyncio
from typing import Dict, List, Any, Callable, Awaitable, Union, Optional
from utils.string_utils import (
is_blank, is_not_blank, is_any_blank, is_all_blank,
is_numeric, is_alpha, starts_with, ends_with,
contains, split, chop, chomp, index_of,
difference, replace, remove, right, left,
length, reverse
)
# 函数类型定义
AsyncFunc = Callable[..., Awaitable[Any]]
# 注册所有内置函数及其元数据
BUILT_IN_FUNCTIONS = [
{
"id": "isBlank()",
"name": "是否为空",
"description": "检查字符串是否为null、空字符串或只包含空白字符",
"syntax": "isBlank(str)",
"example": "isBlank(' ') // 返回 true",
"category": "string",
"func": is_blank
},
{
"id": "isNotBlank()",
"name": "是否不为空",
"description": "检查字符串是否不为空与isBlank()相反",
"syntax": "isNotBlank(str)",
"example": "isNotBlank('hello') // 返回 true",
"category": "string",
"func": is_not_blank
},
{
"id": "isAnyBlank()",
"name": "是否任意一个为空",
"description": "检查多个字符串中是否有任意一个为空",
"syntax": "isAnyBlank(str1, str2, ...)",
"example": "isAnyBlank('hello', '') // 返回 true",
"category": "string",
"func": is_any_blank
},
{
"id": "isAllBlank()",
"name": "是否全部为空",
"description": "检查一个或多个字符串是否全部为空",
"syntax": "isAllBlank(str1, str2, ...)",
"example": "isAllBlank('', ' ') // 返回 true",
"category": "string",
"func": is_all_blank
},
{
"id": "isNumeric()",
"name": "是否为数字",
"description": "检查字符串是否为数字",
"syntax": "isNumeric(str)",
"example": "isNumeric('123') // 返回 true",
"category": "string",
"func": is_numeric
},
{
"id": "isAlpha()",
"name": "是否为字母",
"description": "检查字符串是否只包含字母",
"syntax": "isAlpha(str)",
"example": "isAlpha('abc') // 返回 true",
"category": "string",
"func": is_alpha
},
{
"id": "startsWith()",
"name": "以某字符开头",
"description": "检查字符串是否以某个字符开头",
"syntax": "startsWith(str, prefix)",
"example": "startsWith('hello', 'he') // 返回 true",
"category": "string",
"func": starts_with
},
{
"id": "endsWith()",
"name": "以某字符结尾",
"description": "判断字符串是否以某个字符结尾",
"syntax": "endsWith(str, suffix)",
"example": "endsWith('hello', 'lo') // 返回 true",
"category": "string",
"func": ends_with
},
{
"id": "contains()",
"name": "包含字符",
"description": "判断字符串是否包含某个字符",
"syntax": "contains(str, substr)",
"example": "contains('hello', 'll') // 返回 true",
"category": "string",
"func": contains
},
{
"id": "split()",
"name": "拆分字符串",
"description": "将字符串按照某个字符进行拆分,返回字符串数组",
"syntax": "split(str, separator)",
"example": "split('a,b,c', ',') // 返回 ['a', 'b', 'c']",
"category": "string",
"func": split
},
{
"id": "chop()",
"name": "去掉最后一个字符",
"description": "将字符串的最后一个字符去掉,返回去掉之后的字符串",
"syntax": "chop(str)",
"example": "chop('hello') // 返回 'hell'",
"category": "string",
"func": chop
},
{
"id": "chomp()",
"name": "去除尾部子字符串",
"description": "切除字符串最后面的换行符等",
"syntax": "chomp(str)",
"example": "chomp('hello\\n') // 返回 'hello'",
"category": "string",
"func": chomp
},
{
"id": "indexOf()",
"name": "查找索引位置",
"description": "获取某个字符在字符串中的索引位置",
"syntax": "indexOf(str, substr)",
"example": "indexOf('hello', 'l') // 返回 2",
"category": "string",
"func": index_of
},
{
"id": "difference()",
"name": "获取差异部分",
"description": "获取第二个字符串在第一个字符串中不一样的部分",
"syntax": "difference(str1, str2)",
"example": "difference('abc', 'abd') // 返回 'd'",
"category": "string",
"func": difference
},
{
"id": "replace",
"name": "替换字符",
"description": "将字符串中的某些字符替换成另外的字符",
"syntax": "replace(str, old, new)",
"example": "replace('hello', 'l', 'x') // 返回 'hexxo'",
"category": "string",
"func": replace
},
{
"id": "remove()",
"name": "删除字符",
"description": "删除字符串的某一部分",
"syntax": "remove(str, substr)",
"example": "remove('hello', 'll') // 返回 'heo'",
"category": "string",
"func": remove
},
{
"id": "right()",
"name": "截取右侧字符",
"description": "从字符串右边截取指定长度的子字符串",
"syntax": "right(str, length)",
"example": "right('hello', 2) // 返回 'lo'",
"category": "string",
"func": right
},
{
"id": "left()",
"name": "截取左侧字符",
"description": "截取字符串左侧指定长度的字符串",
"syntax": "left(str, length)",
"example": "left('hello', 2) // 返回 'he'",
"category": "string",
"func": left
},
{
"id": "length()",
"name": "获取字符串长度",
"description": "获得字符串长度",
"syntax": "length(str)",
"example": "length('hello') // 返回 5",
"category": "string",
"func": length
},
{
"id": "reverse()",
"name": "反转字符串",
"description": "反转字符串",
"syntax": "reverse(str)",
"example": "reverse('hello') // 返回 'olleh'",
"category": "string",
"func": reverse
}
]
# 创建函数字典以便根据ID快速查找
FUNCTION_MAP = {func["id"]: func for func in BUILT_IN_FUNCTIONS}
def get_function_list() -> List[Dict[str, Any]]:
"""
获取所有内置函数的元数据列表
Returns:
List[Dict[str, Any]]: 函数列表不包含func实现
"""
return [{k: v for k, v in func.items() if k != 'func'} for func in BUILT_IN_FUNCTIONS]
def get_function_by_id(function_id: str) -> Optional[Dict[str, Any]]:
"""
根据ID获取指定函数的元数据
Args:
function_id: 函数ID
Returns:
Optional[Dict[str, Any]]: 函数元数据如果不存在则返回None
"""
return FUNCTION_MAP.get(function_id)
async def call_function(function_id: str, *args, **kwargs) -> Any:
"""
异步调用指定ID的函数
Args:
function_id: 函数ID
*args: 位置参数
**kwargs: 关键字参数
Returns:
Any: 调用函数的结果
Raises:
ValueError: 如果函数不存在
"""
func_data = FUNCTION_MAP.get(function_id)
if not func_data:
raise ValueError(f"内置函数 {function_id} 不存在")
# 获取异步函数并调用
async_func: AsyncFunc = func_data["func"]
return await async_func(*args, **kwargs)
def call_function_sync(function_id: str, *args, **kwargs) -> Any:
"""
同步调用指定ID的函数在内部使用事件循环执行异步函数
适用于非异步环境中调用异步函数
Args:
function_id: 函数ID
*args: 位置参数
**kwargs: 关键字参数
Returns:
Any: 调用函数的结果
Raises:
ValueError: 如果函数不存在
"""
# 创建一个新的事件循环来执行异步函数
loop = asyncio.new_event_loop()
try:
return loop.run_until_complete(call_function(function_id, *args, **kwargs))
finally:
loop.close()