from __future__ import annotations
from dataclasses import dataclass
from typing import Generic, TypeVar, Union, cast
import weechat
from slack.shared import shared
class WeeChatColor(str):
pass
@dataclass
class WeeChatConfig:
name: str
def __post_init__(self):
self.pointer = weechat.config_new(self.name, "", "")
@dataclass
class WeeChatSection:
weechat_config: WeeChatConfig
name: str
user_can_add_options: bool = False
user_can_delete_options: bool = False
callback_read: str = ""
callback_write: str = ""
def __post_init__(self):
self.pointer = weechat.config_new_section(
self.weechat_config.pointer,
self.name,
self.user_can_add_options,
self.user_can_delete_options,
self.callback_read,
"",
self.callback_write,
"",
"",
"",
"",
"",
"",
"",
)
WeeChatOptionType = TypeVar("WeeChatOptionType", bound=Union[int, str])
@dataclass
class WeeChatOption(Generic[WeeChatOptionType]):
section: WeeChatSection
name: str
description: str
default_value: WeeChatOptionType
min_value: Union[int, None] = None
max_value: Union[int, None] = None
string_values: Union[str, None] = None
parent_option: Union[WeeChatOption[WeeChatOptionType], None] = None
def __post_init__(self):
self._pointer = self._create_weechat_option()
@property
def value(self) -> WeeChatOptionType:
if weechat.config_option_is_null(self._pointer):
if self.parent_option:
return self.parent_option.value
return self.default_value
if isinstance(self.default_value, bool):
return cast(WeeChatOptionType, weechat.config_boolean(self._pointer) == 1)
if isinstance(self.default_value, int):
return cast(WeeChatOptionType, weechat.config_integer(self._pointer))
if isinstance(self.default_value, WeeChatColor):
color = weechat.config_color(self._pointer)
return cast(WeeChatOptionType, WeeChatColor(color))
return cast(WeeChatOptionType, weechat.config_string(self._pointer))
@value.setter
def value(self, value: WeeChatOptionType):
rc = self.value_set_as_str(str(value))
if rc == weechat.WEECHAT_CONFIG_OPTION_SET_ERROR:
raise Exception(f"Failed to value for option: {self.name}")
def value_set_as_str(self, value: str) -> int:
return weechat.config_option_set(self._pointer, value, 1)
def value_set_null(self) -> int:
if not self.parent_option:
raise Exception(
f"Can't set null value for option without parent: {self.name}"
)
return weechat.config_option_set_null(self._pointer, 1)
@property
def weechat_type(self) -> str:
if self.string_values:
return "integer"
if isinstance(self.default_value, bool):
return "boolean"
if isinstance(self.default_value, int):
return "integer"
if isinstance(self.default_value, WeeChatColor):
return "color"
return "string"
def _create_weechat_option(self) -> str:
if self.parent_option:
parent_option_name = (
f"{self.parent_option.section.weechat_config.name}"
f".{self.parent_option.section.name}"
f".{self.parent_option.name}"
)
name = f"{self.name} << {parent_option_name}"
default_value = None
null_value_allowed = True
else:
name = self.name
default_value = str(self.default_value)
null_value_allowed = False
value = None
if shared.weechat_version < 0x3050000:
default_value = str(self.default_value)
value = default_value
return weechat.config_new_option(
self.section.weechat_config.pointer,
self.section.pointer,
name,
self.weechat_type,
self.description,
self.string_values or "",
self.min_value or -(2**31),
self.max_value or 2**31 - 1,
default_value,
value,
null_value_allowed,
"",
"",
"",
"",
"",
"",
)