use serde_json::Value;
use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
#[derive(Clone, Debug)]
pub enum OneBotTransport {
Forward { url: String },
ReverseWs { bind: SocketAddr, path: String },
Http { api_url: String, post_bind: SocketAddr, post_path: String, secret: Option<String> },
HttpApi { api_url: String },
LLOneBotHttp { api_url: String, events: LLOneBotEventMode },
}
#[derive(Clone, Debug)]
pub enum LLOneBotEventMode {
Sse,
LongPoll { interval: Duration },
}
#[derive(Clone, Debug)]
pub struct OneBotConfig {
pub access_token: Option<String>,
pub mode: OneBotTransport,
}
impl OneBotConfig {
pub fn new(url: impl Into<String>) -> Self {
OneBotConfig { access_token: None, mode: OneBotTransport::Forward { url: url.into() } }
}
pub fn reverse_ws(bind: SocketAddr, path: impl Into<String>) -> Self {
OneBotConfig { access_token: None, mode: OneBotTransport::ReverseWs { bind, path: path.into() } }
}
pub fn http(api_url: impl Into<String>, post_bind: SocketAddr, post_path: impl Into<String>) -> Self {
OneBotConfig {
access_token: None,
mode: OneBotTransport::Http {
api_url: api_url.into(),
post_bind,
post_path: post_path.into(),
secret: None,
},
}
}
pub fn http_api(api_url: impl Into<String>) -> Self {
OneBotConfig { access_token: None, mode: OneBotTransport::HttpApi { api_url: api_url.into() } }
}
pub fn llonebot_http_sse(api_url: impl Into<String>) -> Self {
OneBotConfig {
access_token: None,
mode: OneBotTransport::LLOneBotHttp { api_url: api_url.into(), events: LLOneBotEventMode::Sse },
}
}
pub fn llonebot_http_long_poll(api_url: impl Into<String>, interval: Duration) -> Self {
OneBotConfig {
access_token: None,
mode: OneBotTransport::LLOneBotHttp {
api_url: api_url.into(),
events: LLOneBotEventMode::LongPoll { interval },
},
}
}
pub fn with_token(mut self, token: impl Into<String>) -> Self {
self.access_token = Some(token.into());
self
}
pub fn with_secret(mut self, secret: impl Into<String>) -> Self {
if let OneBotTransport::Http { secret: s, .. } = &mut self.mode {
*s = Some(secret.into());
}
self
}
}
pub type QuickOpFn = Arc<dyn Fn(&nagisa_types::event::Event) -> Option<Value> + Send + Sync>;
pub(crate) fn encode_query(s: &str) -> String {
let mut out = String::with_capacity(s.len());
for b in s.bytes() {
match b {
b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'.' | b'_' | b'~' => out.push(b as char),
_ => out.push_str(&format!("%{b:02X}")),
}
}
out
}