use mineral_config_macros::config_section;
#[config_section]
pub struct QueueConfig {
#[serde(deserialize_with = "de_transforms")]
transforms: Vec<QueueTransform>,
}
#[config_section]
#[lua_optional_by_serde]
#[lua_extra_field(
"transform",
"fun(queue: mineral.Song[], ctx: mineral.QueueCtx): mineral.Song[]",
"变换函数,收有序队列与位置上下文,返回新的有序队列"
)]
pub struct QueueTransform {
name: String,
}
fn de_transforms<'de, D>(deserializer: D) -> Result<Vec<QueueTransform>, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::Deserialize;
let transforms = Vec::<QueueTransform>::deserialize(deserializer)?;
let mut names = rustc_hash::FxHashSet::<&str>::default();
for transform in &transforms {
let name = transform.name();
if name.trim().is_empty() {
return Err(serde::de::Error::custom("队列变换名称不可为空"));
}
if !names.insert(name.as_str()) {
return Err(serde::de::Error::custom(format!(
"队列变换名称重复: {name}"
)));
}
}
Ok(transforms)
}