smol bot
Diffstat (limited to 'src/bot/schematic.rs')
-rw-r--r--src/bot/schematic.rs66
1 files changed, 26 insertions, 40 deletions
diff --git a/src/bot/schematic.rs b/src/bot/schematic.rs
index 20545ef..b28df4a 100644
--- a/src/bot/schematic.rs
+++ b/src/bot/schematic.rs
@@ -1,4 +1,5 @@
use anyhow::Result;
+use logos::Logos;
use mindus::data::DataRead;
use mindus::*;
use poise::serenity_prelude::*;
@@ -60,48 +61,10 @@ pub async fn with(
.attachment("image.png")
.author(CreateEmbedAuthor::new(author).icon_url(m.avatar));
if let Some(tags) = v.tags.get("labels") {
- // yes, this is incorrect. no, i dont care if your tag is `\u{208} useful tag`.
- static RE: LazyLock<Regex> =
- LazyLock::new(|| Regex::new(r"\\u\{([a-f0-9]+)\}").unwrap());
- let mut yes = tags.clone();
- for c in RE.captures_iter(&tags) {
- if let Ok(Some(y)) =
- u32::from_str_radix(c.get(1).unwrap().as_str(), 16)
- .map(char::from_u32)
- {
- yes = yes.replace(
- c.get(0).unwrap().as_str(),
- y.encode_utf8(&mut [0; 4]),
- );
- }
- }
- let mut s = yes[1..].as_bytes();
- let mut o = vec![];
- let mut t = Vec::new();
-
- while s.len() > 0 {
- loop {
- let b = s[0];
- s = &s[1..];
- match b {
- b',' | b']' => {
- o.push(emoji::mindustry::to_discord(
- std::str::from_utf8(&t)
- .unwrap()
- .trim()
- .trim_start_matches('"')
- .trim_end_matches('"'),
- ));
- break;
- }
- b => t.push(b),
- }
- }
- t.clear();
- }
e = e.field(
"tags",
- o.iter()
+ decode_tags(tags)
+ .iter()
.map(String::as_str)
.intersperse(" | ")
.fold(String::new(), |acc, x| acc + x),
@@ -163,3 +126,26 @@ pub fn from_msg(msg: &str) -> Result<Option<Schematic>> {
.trim();
Ok(Some(Schematic::deserialize_base64(schem_text)?))
}
+
+fn decode_tags(tags: &str) -> Vec<String> {
+ #[derive(logos::Logos, PartialEq, Debug)]
+ #[logos(skip r"[\s\n,]+")]
+ enum Tokens<'s> {
+ #[token("[", priority = 8)]
+ Open,
+ #[token("]", priority = 8)]
+ Close,
+ #[regex(r#""[^"]+""#, priority = 7, callback = |x| &x.slice()[1..x.slice().len()-1])]
+ #[regex(r"[^,\]\[]+", priority = 6)]
+ String(&'s str),
+ }
+ let mut lexer = Tokens::lexer(&tags);
+ let mut t = Vec::new();
+ let mut next = || lexer.find_map(|x| x.ok());
+ assert_eq!(next().unwrap(), Tokens::Open);
+ while let Some(Tokens::String(x)) = next() {
+ t.push(emoji::mindustry::to_discord(x));
+ }
+ assert_eq!(lexer.next(), None);
+ t
+}