puniyu_adapter_console 0.8.4

puniyu的控制台适配器
Documentation
use crate::input::{ConsolePayload, ParsedConsoleInput};
use puniyu_adapter::event::{
	crate_friend_message, crate_group_message, crate_group_temp_message, crate_guild_message,
	create_event, create_message, send_event,
};
use puniyu_adapter::contact::*;
use puniyu_adapter::element::receive::*;
use puniyu_adapter::sender::*;
use puniyu_adapter::bot::Bot;
use rand::distr::{Alphanumeric, SampleString};
use std::time::{SystemTime, UNIX_EPOCH};

pub(crate) fn make_random_id() -> String {
	Alphanumeric.sample_string(&mut rand::rng(), 32)
}

const DEFAULT_GUILD_ID: &str = "test_guild";
const DEFAULT_GUILD_NAME: &str = "test_guild";
const DEFAULT_GUILD_SUB_NAME: &str = "test_channel";

macro_rules! dispatch_message {
	(Friend, $bot:expr, $event_id:expr, $time:expr, $msg_id:expr, $elements:expr) => {{
		let bot_name = $bot.self_id();
		let contact = contact_friend!(bot_name, bot_name);
		let sender = sender_friend!(user_id: bot_name, nick: bot_name);
		let event = create_event!(
			Message,
			create_message!(Friend, crate_friend_message!(
				bot: $bot,
				event_id: $event_id,
				user_id: bot_name,
				contact: &contact,
				sender: &sender,
				time: $time,
				message_id: $msg_id,
				elements: $elements,
			))
		);
		send_event(event).await;
	}};
	(Group, $bot:expr, $event_id:expr, $time:expr, $msg_id:expr, $elements:expr) => {{
		let bot_name = $bot.self_id();
		let contact = contact_group!(bot_name, bot_name);
		let sender = sender_group!(user_id: bot_name, nick: bot_name, sex: Sex::Unknown, age: 0, role: Role::Member);
		let event = create_event!(
			Message,
			create_message!(Group, crate_group_message!(
				bot: $bot,
				event_id: $event_id,
				user_id: bot_name,
				contact: &contact,
				sender: &sender,
				time: $time,
				message_id: $msg_id,
				elements: $elements,
			))
		);
		send_event(event).await;
	}};
	(GroupTemp, $bot:expr, $event_id:expr, $time:expr, $msg_id:expr, $elements:expr) => {{
		let bot_name = $bot.self_id();
		let contact = contact_group_temp!(bot_name, bot_name);
		let sender = sender_group_temp!(user_id: bot_name, nick: bot_name, sex: Sex::Unknown, age: 0, role: Role::Member);
		let event = create_event!(
			Message,
			create_message!(GroupTemp, crate_group_temp_message!(
				bot: $bot,
				event_id: $event_id,
				user_id: bot_name,
				contact: &contact,
				sender: &sender,
				time: $time,
				message_id: $msg_id,
				elements: $elements,
			))
		);
		send_event(event).await;
	}};
	(Guild, $bot:expr, $event_id:expr, $time:expr, $msg_id:expr, $elements:expr) => {{
		let bot_name = $bot.self_id();
		let contact = contact_guild!(peer: DEFAULT_GUILD_ID, name: DEFAULT_GUILD_NAME, sub_name: DEFAULT_GUILD_SUB_NAME);
		let sender = sender_guild!(user_id: bot_name, nick: bot_name, sex: Sex::Unknown, age: 0, role: Role::Member);
		let event = create_event!(
			Message,
			create_message!(Guild, crate_guild_message!(
				bot: $bot,
				event_id: $event_id,
				user_id: bot_name,
				contact: &contact,
				sender: &sender,
				time: $time,
				message_id: $msg_id,
				elements: $elements,
			))
		);
		send_event(event).await;
	}};
}

pub async fn dispatch_event(bot: &Bot, input: &ParsedConsoleInput) {
	let elements = build_elements(&input.payload);
	let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
	let message_id = make_random_id();
	let event_id = make_random_id();

	match input.scene {
		SceneType::Friend => dispatch_message!(Friend, bot, &event_id, timestamp, &message_id, &elements),
		SceneType::Group => dispatch_message!(Group, bot, &event_id, timestamp, &message_id, &elements),
		SceneType::GroupTemp => dispatch_message!(GroupTemp, bot, &event_id, timestamp, &message_id, &elements),
		SceneType::Guild => dispatch_message!(Guild, bot, &event_id, timestamp, &message_id, &elements),
	}
}

fn build_elements(payload: &ConsolePayload) -> Vec<Elements<'_>> {
	match payload {
		ConsolePayload::At(target_id) => vec![Elements::At(AtElement { target_id })],
		ConsolePayload::Text(text) => vec![Elements::Text(TextElement { text })],
		ConsolePayload::Image(image_url) => vec![Elements::Image(ImageElement {
			file: image_url.as_str().as_bytes().to_vec().into(),
			file_name: "image.png",
			summary: "image",
			width: 100,
			height: 100,
		})],
		ConsolePayload::Json(json_content) => {
			vec![Elements::Json(JsonElement { data: json_content })]
		}
		ConsolePayload::Video(video_url) => vec![Elements::Video(VideoElement {
			file: video_url.as_str().as_bytes().to_vec().into(),
			file_name: "video",
		})],
		ConsolePayload::Record(record_url) => vec![Elements::Record(RecordElement {
			file: record_url.as_str().as_bytes().to_vec().into(),
			file_name: "record",
		})],
		ConsolePayload::File(file_url) => vec![Elements::File(FileElement {
			file: file_url.as_str().as_bytes().to_vec().into(),
			file_size: 0,
			file_name: "file",
		})],
		ConsolePayload::Xml(xml_content) => vec![Elements::Xml(XmlElement { data: xml_content })],
	}
}