about summary refs log tree commit diff
path: root/src/util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.rs')
-rw-r--r--src/util.rs97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/util.rs b/src/util.rs
new file mode 100644
index 0000000..a746cb3
--- /dev/null
+++ b/src/util.rs
@@ -0,0 +1,97 @@
+//! Uh-oh, a `util.rs` file. That can't be good.
+
+use twilight_model::id::{Id, marker::UserMarker};
+
+use crate::database::{BoardRow, Placement};
+
+#[macro_export]
+macro_rules! bail {
+	($msg:expr) => {
+		return twilight_util::builder::InteractionResponseDataBuilder::new()
+			.content(&format!("❌ {}", $msg))
+			.build()
+	};
+}
+
+#[macro_export]
+macro_rules! fail {
+	($msg:expr) => {
+		twilight_util::builder::InteractionResponseDataBuilder::new()
+			.content(&format!("❌ {}", $msg))
+			.build()
+	};
+}
+
+#[macro_export]
+macro_rules! success {
+	($msg:expr) => {
+		twilight_util::builder::InteractionResponseDataBuilder::new()
+			.content(&format!("✅ {}", $msg))
+			.build()
+	};
+}
+
+pub fn tiebreak_shared_positions(board: Vec<BoardRow>) -> Vec<Placement> {
+	let first = match board.first() {
+		Some(r) => r.clone(),
+		None => return vec![],
+	};
+
+	let mut last_score = first.points;
+	let mut last_placed = 1;
+	let mut placed = vec![Placement {
+		row: first,
+		placement: 1,
+		placement_tie: 1,
+		placement_first_of_tie: true,
+	}];
+
+	for (idx, row) in board.into_iter().enumerate().skip(1) {
+		if row.points == last_score {
+			placed.push(Placement {
+				row,
+				placement: idx + 1,
+				placement_tie: last_placed,
+				placement_first_of_tie: false,
+			});
+		} else {
+			last_score = row.points;
+			last_placed = idx + 1;
+
+			placed.push(Placement {
+				row,
+				placement: idx + 1,
+				placement_tie: last_placed,
+				placement_first_of_tie: true,
+			});
+		}
+	}
+
+	placed
+}
+
+/// Takes a `&str` and extracts all mentions of users, sticking them in a Vec
+pub fn extract_user_mentions(mut raw: &str) -> Vec<Id<UserMarker>> {
+	let mut ret = vec![];
+
+	loop {
+		let Some(start) = raw.find("<@") else {
+			break;
+		};
+
+		let Some(end) = raw.find('>') else {
+			break;
+		};
+
+		let id_str = &raw[start + 2..end];
+		raw = &raw[end + 1..];
+
+		let Ok(id) = u64::from_str_radix(id_str, 10) else {
+			continue;
+		};
+
+		ret.push(Id::new(id));
+	}
+
+	ret
+}