113 lines
4.0 KiB
Rust
Executable File
113 lines
4.0 KiB
Rust
Executable File
//! Nerimity protocol backend — custom REST + WebSocket chat platform.
|
|
|
|
use crate::core::message::ChatMessage;
|
|
use crate::core::protocol::ProtocolType;
|
|
use tokio::sync::mpsc;
|
|
use tracing::info;
|
|
|
|
// ─── Configuration ────────────────────────────────────────────────────
|
|
|
|
/// Configuration for a Nerimity connection.
|
|
#[derive(Debug, Clone)]
|
|
pub struct NerimityConfig {
|
|
/// REST API base URL.
|
|
pub api_base: String,
|
|
/// Authentication token.
|
|
pub token: String,
|
|
/// Outgoing messages to the TUI.
|
|
pub tx: mpsc::Sender<ChatMessage>,
|
|
}
|
|
|
|
// ─── Commands ──────────────────────────────────────────────────────────
|
|
|
|
/// Commands sent from the dispatcher to the Nerimity client task.
|
|
#[derive(Debug)]
|
|
pub enum NerimityCommand {
|
|
/// Send a message to a channel.
|
|
Msg { channel_id: String, body: String },
|
|
/// Send an emote (me-action) to a channel.
|
|
Emote { channel_id: String, body: String },
|
|
/// Disconnect from Nerimity.
|
|
Quit,
|
|
/// Join a guild via invite code.
|
|
JoinGuild { invite_code: String },
|
|
/// Leave a guild.
|
|
LeaveGuild { guild_id: String },
|
|
/// List members of a guild.
|
|
Members { guild_id: String },
|
|
/// List all servers the bot is in.
|
|
ListServers,
|
|
}
|
|
|
|
// ─── Runner ────────────────────────────────────────────────────────────
|
|
|
|
/// Main loop for the Nerimity protocol.
|
|
pub async fn run_nerimity(
|
|
config: NerimityConfig,
|
|
mut cmd_rx: mpsc::Receiver<NerimityCommand>,
|
|
) -> anyhow::Result<()> {
|
|
let _protocol = ProtocolType::Nerimity;
|
|
|
|
config
|
|
.tx
|
|
.send(ChatMessage::notice(
|
|
ProtocolType::Nerimity, "Status",
|
|
"Nerimity connected. REST + WebSocket integration follows the Discord backend pattern.",
|
|
))
|
|
.await?;
|
|
|
|
while let Some(cmd) = cmd_rx.recv().await {
|
|
match cmd {
|
|
NerimityCommand::Msg { channel_id: _, body } => {
|
|
info!(%body, "nerimity msg");
|
|
}
|
|
NerimityCommand::Emote { channel_id: _, body } => {
|
|
info!(%body, "nerimity emote");
|
|
}
|
|
NerimityCommand::Quit => {
|
|
info!("nerimity quit");
|
|
break;
|
|
}
|
|
NerimityCommand::JoinGuild { invite_code } => {
|
|
info!(%invite_code, "nerimity join guild");
|
|
}
|
|
NerimityCommand::LeaveGuild { guild_id } => {
|
|
info!(%guild_id, "nerimity leave guild");
|
|
}
|
|
NerimityCommand::Members { guild_id: _ } => {
|
|
let _ = config.tx.send(ChatMessage::notice(ProtocolType::Nerimity, "Status", "Guild members require REST + WebSocket integration.")).await;
|
|
}
|
|
NerimityCommand::ListServers => {
|
|
let _ = config.tx.send(ChatMessage::notice(ProtocolType::Nerimity, "Status", "Server listing requires REST + WebSocket integration.")).await;
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// ─── Tests ─────────────────────────────────────────────────────────────
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[tokio::test]
|
|
async fn test_config_fields() {
|
|
let (tx, _rx) = mpsc::channel(16);
|
|
let cfg = NerimityConfig {
|
|
api_base: "https://nerimity.example.com".into(),
|
|
token: "tok".into(),
|
|
tx,
|
|
};
|
|
assert_eq!(cfg.api_base, "https://nerimity.example.com");
|
|
assert_eq!(cfg.token, "tok");
|
|
}
|
|
|
|
#[test]
|
|
fn test_command_debug() {
|
|
let cmd = NerimityCommand::Msg { channel_id: "ch1".into(), body: "hello".into() };
|
|
let debug = format!("{:?}", cmd);
|
|
assert!(debug.contains("Msg"));
|
|
}
|
|
} |