refactored dice output
This commit is contained in:
parent
7b6eecf40e
commit
8e2f75d624
2 changed files with 259 additions and 78 deletions
313
src/dice.rs
313
src/dice.rs
|
|
@ -1,6 +1,9 @@
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use rand::{Rng, RngExt};
|
use rand::{Rng, RngExt};
|
||||||
use std::io::Write;
|
use std::convert::Infallible;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fmt::{Write, format};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
pub type ExpBox = Box<Expression>;
|
pub type ExpBox = Box<Expression>;
|
||||||
|
|
||||||
|
|
@ -35,13 +38,13 @@ pub enum CompareFragment {
|
||||||
Le(ExpBox),
|
Le(ExpBox),
|
||||||
}
|
}
|
||||||
|
|
||||||
const DICE_POOL_LIMIT: usize = 100_000;
|
const DICE_POOL_LIMIT: usize = 10_000;
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
pub fn collect_evaluation(&self, mut rng: impl Rng) -> anyhow::Result<String> {
|
pub fn collect_evaluation(&self, mut rng: impl Rng) -> anyhow::Result<String> {
|
||||||
let mut buffer = Vec::new();
|
let mut witness = DiscordMdWitness::default();
|
||||||
let total = self.evaluate(&mut rng, &mut buffer, 100)?;
|
let total = self.evaluate(&mut rng, &mut witness, 100)?;
|
||||||
let result_text = String::from_utf8(buffer)?;
|
let result_text = witness.buffer;
|
||||||
Ok(format!("**{total}** = {result_text}"))
|
Ok(format!("**{total}** = {result_text}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,21 +59,25 @@ impl Expression {
|
||||||
Ok(average)
|
Ok(average)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn evaluate(
|
fn evaluate<W, E>(
|
||||||
&self,
|
&self,
|
||||||
rng: &mut impl Rng,
|
rng: &mut impl Rng,
|
||||||
writer: &mut impl Write,
|
w: &mut W,
|
||||||
outer_precedence: i64,
|
outer_precedence: i64,
|
||||||
) -> anyhow::Result<f64> {
|
) -> anyhow::Result<f64>
|
||||||
|
where
|
||||||
|
W: Witness<Error = E>,
|
||||||
|
E: Error + Send + Sync + 'static,
|
||||||
|
{
|
||||||
use Expression::*;
|
use Expression::*;
|
||||||
let precedence = self.precedence();
|
let precedence = self.precedence();
|
||||||
let needs_parens = precedence > outer_precedence;
|
let needs_parens = precedence > outer_precedence;
|
||||||
if needs_parens {
|
if needs_parens {
|
||||||
write!(writer, "(")?;
|
write!(w, "(")?;
|
||||||
}
|
}
|
||||||
let result = match self {
|
let result = match self {
|
||||||
Const(x) => {
|
Const(x) => {
|
||||||
write!(writer, "{}", x)?;
|
write!(w, "{}", x)?;
|
||||||
*x
|
*x
|
||||||
}
|
}
|
||||||
Dice(DiceFormula {
|
Dice(DiceFormula {
|
||||||
|
|
@ -83,15 +90,15 @@ impl Expression {
|
||||||
x,
|
x,
|
||||||
}) => {
|
}) => {
|
||||||
let count = if let Some(count_node) = count_node {
|
let count = if let Some(count_node) = count_node {
|
||||||
count_node.evaluate(rng, writer, precedence)? as usize
|
count_node.evaluate(rng, w, precedence)? as usize
|
||||||
} else {
|
} else {
|
||||||
1
|
1
|
||||||
};
|
};
|
||||||
if count > DICE_POOL_LIMIT {
|
if count > DICE_POOL_LIMIT {
|
||||||
bail!("Too many dice.")
|
bail!("Too many dice.")
|
||||||
};
|
};
|
||||||
write!(writer, "d")?;
|
write!(w, "d")?;
|
||||||
let size = size_node.evaluate(rng, writer, precedence)? as i64;
|
let size = size_node.evaluate(rng, w, precedence)? as i64;
|
||||||
if size < 1 {
|
if size < 1 {
|
||||||
bail!("Invalid die size.")
|
bail!("Invalid die size.")
|
||||||
}
|
}
|
||||||
|
|
@ -102,13 +109,13 @@ impl Expression {
|
||||||
|
|
||||||
// Exploding dice are early, they add rolls
|
// Exploding dice are early, they add rolls
|
||||||
if let Some(fragments) = x {
|
if let Some(fragments) = x {
|
||||||
write!(writer, "x")?;
|
write!(w, "x")?;
|
||||||
if size < 2 {
|
if size < 2 {
|
||||||
bail!("Infinite explosion.")
|
bail!("Infinite explosion.")
|
||||||
}
|
}
|
||||||
let mut comparers = Vec::with_capacity(fragments.len());
|
let mut comparers = Vec::with_capacity(fragments.len());
|
||||||
for fragment in fragments {
|
for fragment in fragments {
|
||||||
comparers.push(fragment.comparer(rng, writer)?);
|
comparers.push(fragment.comparer(rng, w)?);
|
||||||
}
|
}
|
||||||
for i in 0..DICE_POOL_LIMIT {
|
for i in 0..DICE_POOL_LIMIT {
|
||||||
if i >= rolls.len() {
|
if i >= rolls.len() {
|
||||||
|
|
@ -133,26 +140,26 @@ impl Expression {
|
||||||
|
|
||||||
// Advantage/disadvantage roll filters
|
// Advantage/disadvantage roll filters
|
||||||
let kh = if let Some(child) = kh {
|
let kh = if let Some(child) = kh {
|
||||||
write!(writer, "kh")?;
|
write!(w, "kh")?;
|
||||||
Some(child.evaluate(rng, writer, precedence)? as usize)
|
Some(child.evaluate(rng, w, precedence)? as usize)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let kl = if let Some(child) = kl {
|
let kl = if let Some(child) = kl {
|
||||||
write!(writer, "kl")?;
|
write!(w, "kl")?;
|
||||||
Some(child.evaluate(rng, writer, precedence)? as usize)
|
Some(child.evaluate(rng, w, precedence)? as usize)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let dh = if let Some(child) = dh {
|
let dh = if let Some(child) = dh {
|
||||||
write!(writer, "dh")?;
|
write!(w, "dh")?;
|
||||||
Some(child.evaluate(rng, writer, precedence)? as usize)
|
Some(child.evaluate(rng, w, precedence)? as usize)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let dl = if let Some(child) = dl {
|
let dl = if let Some(child) = dl {
|
||||||
write!(writer, "dl")?;
|
write!(w, "dl")?;
|
||||||
Some(child.evaluate(rng, writer, precedence)? as usize)
|
Some(child.evaluate(rng, w, precedence)? as usize)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
@ -168,11 +175,9 @@ impl Expression {
|
||||||
}
|
}
|
||||||
let mut result_set = Vec::with_capacity(rolls.len());
|
let mut result_set = Vec::with_capacity(rolls.len());
|
||||||
|
|
||||||
let print_all_rolls = rolls.len() <= 100;
|
write!(w, " ")?;
|
||||||
|
let mut w_set = w.witness_set()?;
|
||||||
|
|
||||||
if print_all_rolls {
|
|
||||||
write!(writer, " ‹ ")?;
|
|
||||||
}
|
|
||||||
for idx in 0..rolls.len() {
|
for idx in 0..rolls.len() {
|
||||||
let mut skip = false;
|
let mut skip = false;
|
||||||
let roll = rolls[idx];
|
let roll = rolls[idx];
|
||||||
|
|
@ -200,58 +205,50 @@ impl Expression {
|
||||||
if !skip {
|
if !skip {
|
||||||
result_set.push(roll as f64);
|
result_set.push(roll as f64);
|
||||||
}
|
}
|
||||||
if print_all_rolls {
|
w_set.witness_roll(DiceRoll {
|
||||||
if skip {
|
size: size as usize,
|
||||||
write!(writer, "~~`{}`~~", roll)?;
|
roll: roll as usize,
|
||||||
} else if size > 2 && (roll == 1 || roll == size) {
|
is_admitted: !skip,
|
||||||
write!(writer, "**`{}`**", roll)?;
|
did_proliferate: false,
|
||||||
} else {
|
is_from_proliferation: idx >= count,
|
||||||
write!(writer, "`{}`", roll)?;
|
})?;
|
||||||
}
|
|
||||||
|
|
||||||
if idx != rolls.len() - 1 {
|
|
||||||
write!(writer, " ")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if print_all_rolls {
|
|
||||||
write!(writer, " ›")?;
|
|
||||||
}
|
}
|
||||||
|
w_set.end()?;
|
||||||
|
|
||||||
result_set.iter().sum()
|
result_set.iter().sum()
|
||||||
}
|
}
|
||||||
Neg(inner_node) => {
|
Neg(inner_node) => {
|
||||||
write!(writer, "-")?;
|
write!(w, "-")?;
|
||||||
let inner = inner_node.evaluate(rng, writer, precedence)?;
|
let inner = inner_node.evaluate(rng, w, precedence)?;
|
||||||
-inner
|
-inner
|
||||||
}
|
}
|
||||||
Add(lhs_node, rhs_node) => {
|
Add(lhs_node, rhs_node) => {
|
||||||
let lhs = lhs_node.evaluate(rng, writer, precedence)?;
|
let lhs = lhs_node.evaluate(rng, w, precedence)?;
|
||||||
write!(writer, " + ")?;
|
write!(w, " + ")?;
|
||||||
let rhs = rhs_node.evaluate(rng, writer, precedence)?;
|
let rhs = rhs_node.evaluate(rng, w, precedence)?;
|
||||||
lhs + rhs
|
lhs + rhs
|
||||||
}
|
}
|
||||||
Sub(lhs_node, rhs_node) => {
|
Sub(lhs_node, rhs_node) => {
|
||||||
let lhs = lhs_node.evaluate(rng, writer, precedence)?;
|
let lhs = lhs_node.evaluate(rng, w, precedence)?;
|
||||||
write!(writer, " - ")?;
|
write!(w, " - ")?;
|
||||||
let rhs = rhs_node.evaluate(rng, writer, precedence)?;
|
let rhs = rhs_node.evaluate(rng, w, precedence)?;
|
||||||
lhs - rhs
|
lhs - rhs
|
||||||
}
|
}
|
||||||
Mul(lhs_node, rhs_node) => {
|
Mul(lhs_node, rhs_node) => {
|
||||||
let lhs = lhs_node.evaluate(rng, writer, precedence)?;
|
let lhs = lhs_node.evaluate(rng, w, precedence)?;
|
||||||
write!(writer, " × ")?;
|
write!(w, " × ")?;
|
||||||
let rhs = rhs_node.evaluate(rng, writer, precedence)?;
|
let rhs = rhs_node.evaluate(rng, w, precedence)?;
|
||||||
lhs * rhs
|
lhs * rhs
|
||||||
}
|
}
|
||||||
Div(lhs_node, rhs_node) => {
|
Div(lhs_node, rhs_node) => {
|
||||||
let lhs = lhs_node.evaluate(rng, writer, precedence)?;
|
let lhs = lhs_node.evaluate(rng, w, precedence)?;
|
||||||
write!(writer, " ÷ ")?;
|
write!(w, " ÷ ")?;
|
||||||
let rhs = rhs_node.evaluate(rng, writer, precedence)?;
|
let rhs = rhs_node.evaluate(rng, w, precedence)?;
|
||||||
lhs / rhs
|
lhs / rhs
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if needs_parens {
|
if needs_parens {
|
||||||
write!(writer, ")")?;
|
write!(w, ")")?;
|
||||||
}
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
@ -315,35 +312,39 @@ impl Expression {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompareFragment {
|
impl CompareFragment {
|
||||||
fn comparer(
|
fn comparer<W, E>(
|
||||||
&self,
|
&self,
|
||||||
rng: &mut impl Rng,
|
rng: &mut impl Rng,
|
||||||
writer: &mut impl Write,
|
witness: &mut W,
|
||||||
) -> anyhow::Result<Box<dyn Fn(f64) -> bool>> {
|
) -> anyhow::Result<Box<dyn Fn(f64) -> bool>>
|
||||||
|
where
|
||||||
|
W: Witness<Error = E>,
|
||||||
|
E: Error + Send + Sync + 'static,
|
||||||
|
{
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
CompareFragment::Eq(inner) => {
|
CompareFragment::Eq(inner) => {
|
||||||
write!(writer, "=")?;
|
write!(witness, "=")?;
|
||||||
let comp = inner.evaluate(rng, writer, 2)?;
|
let comp = inner.evaluate(rng, witness, 2)?;
|
||||||
Box::new(move |value| value == comp)
|
Box::new(move |value| value == comp)
|
||||||
}
|
}
|
||||||
CompareFragment::Gt(inner) => {
|
CompareFragment::Gt(inner) => {
|
||||||
write!(writer, ">")?;
|
write!(witness, ">")?;
|
||||||
let comp = inner.evaluate(rng, writer, 2)?;
|
let comp = inner.evaluate(rng, witness, 2)?;
|
||||||
Box::new(move |value| value > comp)
|
Box::new(move |value| value > comp)
|
||||||
}
|
}
|
||||||
CompareFragment::Ge(inner) => {
|
CompareFragment::Ge(inner) => {
|
||||||
write!(writer, ">=")?;
|
write!(witness, ">=")?;
|
||||||
let comp = inner.evaluate(rng, writer, 2)?;
|
let comp = inner.evaluate(rng, witness, 2)?;
|
||||||
Box::new(move |value| value >= comp)
|
Box::new(move |value| value >= comp)
|
||||||
}
|
}
|
||||||
CompareFragment::Lt(inner) => {
|
CompareFragment::Lt(inner) => {
|
||||||
write!(writer, "<")?;
|
write!(witness, "<")?;
|
||||||
let comp = inner.evaluate(rng, writer, 2)?;
|
let comp = inner.evaluate(rng, witness, 2)?;
|
||||||
Box::new(move |value| value < comp)
|
Box::new(move |value| value < comp)
|
||||||
}
|
}
|
||||||
CompareFragment::Le(inner) => {
|
CompareFragment::Le(inner) => {
|
||||||
write!(writer, "<=")?;
|
write!(witness, "<=")?;
|
||||||
let comp = inner.evaluate(rng, writer, 2)?;
|
let comp = inner.evaluate(rng, witness, 2)?;
|
||||||
Box::new(move |value| value <= comp)
|
Box::new(move |value| value <= comp)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -362,3 +363,173 @@ impl Expression {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait Witness {
|
||||||
|
type Ok;
|
||||||
|
type Error: Error;
|
||||||
|
type WitnessSet<'a>: WitnessSet<Ok = Self::Ok, Error = Self::Error>
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
|
fn witness_source_text(&mut self, text: &str) -> Result<Self::Ok, Self::Error>;
|
||||||
|
fn witness_set(&mut self) -> Result<Self::WitnessSet<'_>, Self::Error>;
|
||||||
|
fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> Result<Self::Ok, Self::Error>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
self.witness_source_text(&format(args))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait WitnessSet {
|
||||||
|
type Ok;
|
||||||
|
type Error: Error;
|
||||||
|
|
||||||
|
fn witness_roll(&mut self, dice: DiceRoll) -> Result<Self::Ok, Self::Error>;
|
||||||
|
fn end(self) -> Result<Self::Ok, Self::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct DiceRoll {
|
||||||
|
size: usize,
|
||||||
|
roll: usize,
|
||||||
|
is_admitted: bool,
|
||||||
|
did_proliferate: bool,
|
||||||
|
is_from_proliferation: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DiceRoll {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
size: 1,
|
||||||
|
roll: 1,
|
||||||
|
is_admitted: true,
|
||||||
|
did_proliferate: false,
|
||||||
|
is_from_proliferation: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DiscordMdWitness {
|
||||||
|
buffer: String,
|
||||||
|
dice_written: usize,
|
||||||
|
}
|
||||||
|
struct DiscordMdWitnessSet<'a> {
|
||||||
|
parent: &'a mut DiscordMdWitness,
|
||||||
|
index: usize,
|
||||||
|
dice_elided: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
enum DiscordMdWitnessError {
|
||||||
|
#[error("formatting failed")]
|
||||||
|
Format(#[from] std::fmt::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DiscordMdWitness {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
buffer: String::new(),
|
||||||
|
dice_written: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Witness for DiscordMdWitness {
|
||||||
|
type Ok = ();
|
||||||
|
type Error = DiscordMdWitnessError;
|
||||||
|
type WitnessSet<'a> = DiscordMdWitnessSet<'a>;
|
||||||
|
|
||||||
|
fn witness_source_text(&mut self, text: &str) -> Result<Self::Ok, Self::Error> {
|
||||||
|
self.buffer.push_str(text);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn witness_set(&mut self) -> Result<Self::WitnessSet<'_>, Self::Error> {
|
||||||
|
write!(self.buffer, "‹ ")?;
|
||||||
|
Ok(DiscordMdWitnessSet {
|
||||||
|
parent: self,
|
||||||
|
index: 0,
|
||||||
|
dice_elided: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> WitnessSet for DiscordMdWitnessSet<'a> {
|
||||||
|
type Ok = ();
|
||||||
|
type Error = DiscordMdWitnessError;
|
||||||
|
|
||||||
|
fn witness_roll(&mut self, dice: DiceRoll) -> Result<Self::Ok, Self::Error> {
|
||||||
|
if self.parent.dice_written >= 100 {
|
||||||
|
if !self.dice_elided {
|
||||||
|
write!(self.parent.buffer, "…")?;
|
||||||
|
self.dice_elided = true;
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let is_extreme = dice.size >= 4 && (dice.roll == 1 || dice.roll == dice.size);
|
||||||
|
if self.index > 0 {
|
||||||
|
write!(self.parent.buffer, " ")?;
|
||||||
|
}
|
||||||
|
if !dice.is_admitted {
|
||||||
|
write!(self.parent.buffer, "~~")?;
|
||||||
|
}
|
||||||
|
if dice.is_from_proliferation {
|
||||||
|
write!(self.parent.buffer, "*")?;
|
||||||
|
}
|
||||||
|
if is_extreme || dice.did_proliferate {
|
||||||
|
write!(self.parent.buffer, "**")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(self.parent.buffer, "`{}`", dice.roll)?;
|
||||||
|
|
||||||
|
if is_extreme || dice.did_proliferate {
|
||||||
|
write!(self.parent.buffer, "**")?;
|
||||||
|
}
|
||||||
|
if dice.is_from_proliferation {
|
||||||
|
write!(self.parent.buffer, "*")?;
|
||||||
|
}
|
||||||
|
if !dice.is_admitted {
|
||||||
|
write!(self.parent.buffer, "~~")?;
|
||||||
|
}
|
||||||
|
self.index += 1;
|
||||||
|
self.parent.dice_written += 1;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||||
|
write!(self.parent.buffer, " ›")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Witness for std::io::Sink {
|
||||||
|
type Ok = ();
|
||||||
|
type Error = Infallible;
|
||||||
|
type WitnessSet<'a>
|
||||||
|
= &'a mut Self
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
|
fn witness_source_text(&mut self, _text: &str) -> Result<Self::Ok, Self::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn witness_set(&mut self) -> Result<Self::WitnessSet<'_>, Self::Error> {
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WitnessSet for &mut std::io::Sink {
|
||||||
|
type Ok = ();
|
||||||
|
type Error = Infallible;
|
||||||
|
|
||||||
|
fn witness_roll(&mut self, _dice: DiceRoll) -> Result<Self::Ok, Self::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
24
src/main.rs
24
src/main.rs
|
|
@ -14,7 +14,7 @@ use serenity::builder::{
|
||||||
};
|
};
|
||||||
use serenity::{async_trait, prelude::*};
|
use serenity::{async_trait, prelude::*};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::{info, warn};
|
use tracing::{debug, info, warn};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
|
|
@ -46,7 +46,7 @@ impl EventHandler for Handler {
|
||||||
match event {
|
match event {
|
||||||
FullEvent::InteractionCreate { interaction, .. } => {
|
FullEvent::InteractionCreate { interaction, .. } => {
|
||||||
if let Interaction::Command(command) = interaction {
|
if let Interaction::Command(command) = interaction {
|
||||||
info!("Received command interaction: {command:#?}");
|
debug!("Received command interaction: {command:#?}");
|
||||||
|
|
||||||
let content = match command.data.name.as_str() {
|
let content = match command.data.name.as_str() {
|
||||||
"roll" => {
|
"roll" => {
|
||||||
|
|
@ -62,14 +62,12 @@ impl EventHandler for Handler {
|
||||||
let data = CreateInteractionResponseMessage::new().content(content);
|
let data = CreateInteractionResponseMessage::new().content(content);
|
||||||
let builder = CreateInteractionResponse::Message(data);
|
let builder = CreateInteractionResponse::Message(data);
|
||||||
if let Err(why) = command.create_response(&ctx.http, builder).await {
|
if let Err(why) = command.create_response(&ctx.http, builder).await {
|
||||||
info!("Cannot respond to slash command: {why}");
|
warn!("Cannot respond to slash command: {why}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FullEvent::Ready { data_about_bot, .. } => {
|
FullEvent::Ready { data_about_bot, .. } => {
|
||||||
info!("{} is connected!", data_about_bot.user.name);
|
|
||||||
|
|
||||||
let global_command = Command::create_global_command(
|
let global_command = Command::create_global_command(
|
||||||
&ctx.http,
|
&ctx.http,
|
||||||
CreateCommand::new("roll")
|
CreateCommand::new("roll")
|
||||||
|
|
@ -102,7 +100,7 @@ impl EventHandler for Handler {
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
info!("I created the following global slash command: {global_command:#?}");
|
debug!("I created the following global slash command: {global_command:#?}");
|
||||||
|
|
||||||
info!("{} is connected!", data_about_bot.user.name);
|
info!("{} is connected!", data_about_bot.user.name);
|
||||||
}
|
}
|
||||||
|
|
@ -200,8 +198,20 @@ pub async fn roll(ctx: &Context, command: &CommandInteraction) -> anyhow::Result
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
for _ in 0..repeat {
|
for _ in 0..repeat {
|
||||||
|
let result = match expression.collect_evaluation(&mut rng) {
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(err) => {
|
||||||
|
command
|
||||||
|
.create_followup(
|
||||||
|
&ctx.http,
|
||||||
|
CreateInteractionResponseFollowup::new().content(format!("{}", err)),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
text_components.push(CreateContainerComponent::TextDisplay(
|
text_components.push(CreateContainerComponent::TextDisplay(
|
||||||
CreateTextDisplay::new(format!("{}\n", expression.collect_evaluation(&mut rng)?)),
|
CreateTextDisplay::new(format!("{}\n", result)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if fixed_seed.is_some() {
|
if fixed_seed.is_some() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue