mirror of
https://github.com/nonebot/nonebot2.git
synced 2024-11-27 18:45:05 +08:00
✨ support user-defined format spec for message template
This commit is contained in:
parent
620938c26c
commit
983e5aefdb
@ -4,6 +4,9 @@ from string import Formatter
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Callable,
|
||||
Dict,
|
||||
Optional,
|
||||
Set,
|
||||
List,
|
||||
Type,
|
||||
@ -23,6 +26,9 @@ if TYPE_CHECKING:
|
||||
TM = TypeVar("TM", bound="Message")
|
||||
TF = TypeVar("TF", str, "Message")
|
||||
|
||||
FormatSpecFunc = Callable[[Any], str]
|
||||
FormatSpecFunc_T = TypeVar("FormatSpecFunc_T", bound=FormatSpecFunc)
|
||||
|
||||
|
||||
class MessageTemplate(Formatter, Generic[TF]):
|
||||
"""消息模板格式化实现类"""
|
||||
@ -50,8 +56,18 @@ class MessageTemplate(Formatter, Generic[TF]):
|
||||
* ``template: Union[str, Message]``: 模板
|
||||
* ``factory: Union[str, Message]``: 消息构造类型,默认为 `str`
|
||||
"""
|
||||
self.template: Union[str, TF] = template
|
||||
self.template: TF = template
|
||||
self.factory: Type[TF] = factory
|
||||
self.format_specs: Dict[str, FormatSpecFunc] = {}
|
||||
|
||||
def add_format_spec(
|
||||
self, spec: FormatSpecFunc_T, name: Optional[str] = None
|
||||
) -> FormatSpecFunc_T:
|
||||
name = name or spec.__name__
|
||||
if name in self.format_specs:
|
||||
raise ValueError(f"Format spec {name} already exists!")
|
||||
self.format_specs[name] = spec
|
||||
return spec
|
||||
|
||||
def format(self, *args: Any, **kwargs: Any) -> TF:
|
||||
"""
|
||||
@ -69,7 +85,7 @@ class MessageTemplate(Formatter, Generic[TF]):
|
||||
else:
|
||||
raise TypeError("template must be a string or instance of Message!")
|
||||
|
||||
return msg
|
||||
return msg # type:ignore
|
||||
|
||||
def vformat(
|
||||
self, format_string: str, args: Sequence[Any], kwargs: Mapping[str, Any]
|
||||
@ -165,13 +181,15 @@ class MessageTemplate(Formatter, Generic[TF]):
|
||||
(
|
||||
super().format_field(value, format_spec)
|
||||
if (
|
||||
(method is None)
|
||||
or (
|
||||
not isinstance(method_type, (classmethod, staticmethod))
|
||||
) # Only Call staticmethod or classmethod
|
||||
method is None
|
||||
or not isinstance(method_type, (classmethod, staticmethod))
|
||||
)
|
||||
else (
|
||||
self.format_specs[format_spec](value)
|
||||
if format_spec in self.format_specs
|
||||
else method(value)
|
||||
)
|
||||
)
|
||||
if format_spec
|
||||
else value
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user