Merge pull request 'Port sedbot' (#5) from karx/uberbot:master into master

Reviewed-on: lemonsh/uberbot#5
This commit is contained in:
lemonsh 2022-01-01 05:50:25 -06:00
commit 274f064d35
4 changed files with 85 additions and 0 deletions

View file

@ -22,3 +22,5 @@ arrayvec = "0.7"
rand = "0.8"
meval = "0.2"
async-circe = { git = "https://git.karx.xyz/circe/async-circe" }
lazy_static = "1.4.0"
sedregex = "0.2.5"

View file

@ -1,3 +1,4 @@
pub mod leek;
pub mod title;
pub mod misc;
pub mod sed;

69
src/bots/sed.rs Normal file
View file

@ -0,0 +1,69 @@
use std::{fmt::Display, error::Error};
use arrayvec::{ArrayString, CapacityError};
use fancy_regex::Regex;
use lazy_static::lazy_static;
use sedregex::find_and_replace;
#[derive(Debug)]
pub enum SedErrorKind {
Capacity(CapacityError),
Regex(fancy_regex::Error),
SedRegex(sedregex::ErrorKind)
}
#[derive(Debug)]
pub struct SedCapacityError(SedErrorKind);
impl Display for SedCapacityError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// yeah it's ugly but there's no better way afaik
match &self.0 {
SedErrorKind::Capacity(e) => Display::fmt(e, f),
SedErrorKind::Regex(e) => Display::fmt(e, f),
SedErrorKind::SedRegex(e) => Display::fmt(e, f),
}
}
}
impl Error for SedCapacityError {}
impl<T> From<CapacityError<T>> for SedCapacityError {
fn from(e: CapacityError<T>) -> Self {
Self { 0: SedErrorKind::Capacity(e.simplify()) }
}
}
impl From<fancy_regex::Error> for SedCapacityError {
fn from(e: fancy_regex::Error) -> Self {
Self { 0: SedErrorKind::Regex(e) }
}
}
impl From<sedregex::ErrorKind> for SedCapacityError {
fn from(e: sedregex::ErrorKind) -> Self {
Self { 0: SedErrorKind::SedRegex(e) }
}
}
type SedResult = Result<Option<ArrayString<512>>, SedCapacityError>;
pub fn resolve(prev_msg: &str, cmd: &str) -> SedResult {
lazy_static! {
static ref RE: Regex = Regex::new(r"^s/.*/.*").unwrap(); // yes this regex is valid, don't worry about it
}
if RE.is_match(cmd)? {
if let Some(mat) = RE.find(cmd)? {
let slice = &cmd[mat.start()..mat.end()];
let formatted = find_and_replace(&prev_msg, [slice])?;
return Ok(Some(ArrayString::from(&formatted)?));
} else {
return Ok(None);
}
}
Ok(None)
}

View file

@ -1,5 +1,6 @@
mod bots;
use arrayvec::ArrayString;
use async_circe::{commands::Command, Client, Config};
use bots::title::Titlebot;
use bots::{leek, misc};
@ -10,6 +11,7 @@ use std::io::Read;
use std::{collections::HashMap, env};
use tokio::select;
use tracing_subscriber::EnvFilter;
use std::fmt::Write;
// this will be displayed when the help command is used
const HELP: &[&str] = &[
@ -167,6 +169,17 @@ async fn handle_privmsg(
if let Some(titlebot_msg) = state.titlebot.resolve(&message).await? {
state.client.privmsg(&channel, &titlebot_msg).await?;
}
if let Some(prev_msg) = state.last_msgs.get(&nick) {
if let Some(formatted) = bots::sed::resolve(prev_msg, &message)? {
let mut result = ArrayString::<512>::new();
write!(result, "<{}> {}", nick, formatted)?;
state.client.privmsg(&channel, &result).await?;
state.last_msgs.insert(nick, formatted.to_string()); // yes i know this is an allocation, but the hashmap takes a string so nothing i can do
return Ok(());
}
}
state.last_msgs.insert(nick, message);
return Ok(());
}