Compare commits
4 Commits
402f236ba7
...
5643677627
Author | SHA1 | Date |
---|---|---|
projectmoon | 5643677627 | |
projectmoon | de63fd914e | |
projectmoon | e73ad118b2 | |
projectmoon | 3d5cda39c8 |
|
@ -10,10 +10,6 @@ repository = 'https://git.agnos.is/projectmoon/matrix-dicebot'
|
||||||
keywords = ["games", "dice", "matrix", "bot"]
|
keywords = ["games", "dice", "matrix", "bot"]
|
||||||
categories = ["games"]
|
categories = ["games"]
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "dicebot-migrate"
|
|
||||||
path = "src/migrate_cli.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
tracing-subscriber = "0.2"
|
tracing-subscriber = "0.2"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::error::{BotError, DiceRollingError};
|
use crate::error::{BotError, DiceRollingError};
|
||||||
use crate::parser::{Amount, Element, Operator};
|
use crate::parser::dice::{Amount, Element, Operator};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -308,7 +308,7 @@ pub async fn roll_pool(pool: &DicePoolWithContext<'_>) -> Result<RolledDicePool,
|
||||||
return Err(DiceRollingError::ExpressionTooLarge.into());
|
return Err(DiceRollingError::ExpressionTooLarge.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let num_dice = crate::dice::calculate_dice_amount(&pool.0.amounts, &pool.1).await?;
|
let num_dice = crate::logic::calculate_dice_amount(&pool.0.amounts, &pool.1).await?;
|
||||||
let mut roller = RngDieRoller(rand::thread_rng());
|
let mut roller = RngDieRoller(rand::thread_rng());
|
||||||
|
|
||||||
if num_dice > 0 {
|
if num_dice > 0 {
|
||||||
|
@ -578,7 +578,7 @@ mod tests {
|
||||||
let pool = DicePool::new(amounts, DicePoolModifiers::default());
|
let pool = DicePool::new(amounts, DicePoolModifiers::default());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
crate::dice::calculate_dice_amount(&pool.amounts, &ctx)
|
crate::logic::calculate_dice_amount(&pool.amounts, &ctx)
|
||||||
.await
|
.await
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
10
|
10
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::cofd::dice::{DicePool, DicePoolModifiers, DicePoolQuality};
|
use crate::cofd::dice::{DicePool, DicePoolModifiers, DicePoolQuality};
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
use crate::parser::{parse_amounts, DiceParsingError};
|
use crate::parser::dice::{parse_amounts, DiceParsingError};
|
||||||
use combine::parser::char::{digit, spaces, string};
|
use combine::parser::char::{digit, spaces, string};
|
||||||
use combine::{choice, count, many1, one_of, Parser};
|
use combine::{choice, count, many1, one_of, Parser};
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dice_pool_complex_expression_test() {
|
fn dice_pool_complex_expression_test() {
|
||||||
use crate::parser::*;
|
use crate::parser::dice::*;
|
||||||
let modifiers = DicePoolModifiers::custom(DicePoolQuality::Rote, 3);
|
let modifiers = DicePoolModifiers::custom(DicePoolQuality::Rote, 3);
|
||||||
let amounts = vec![
|
let amounts = vec![
|
||||||
Amount {
|
Amount {
|
||||||
|
|
|
@ -19,7 +19,7 @@ use crate::commands::{
|
||||||
use crate::cthulhu::parser::{parse_advancement_roll, parse_regular_roll};
|
use crate::cthulhu::parser::{parse_advancement_roll, parse_regular_roll};
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
use crate::help::parse_help_topic;
|
use crate::help::parse_help_topic;
|
||||||
use crate::variables::parse_set_variable;
|
use crate::parser::variables::parse_set_variable;
|
||||||
use combine::parser::char::{char, letter, space};
|
use combine::parser::char::{char, letter, space};
|
||||||
use combine::{any, many1, optional, Parser};
|
use combine::{any, many1, optional, Parser};
|
||||||
use nom::Err as NomErr;
|
use nom::Err as NomErr;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::db::Variables;
|
use crate::db::Variables;
|
||||||
use crate::error::{BotError, DiceRollingError};
|
use crate::error::{BotError, DiceRollingError};
|
||||||
use crate::parser::{Amount, Element};
|
use crate::logic::calculate_single_die_amount;
|
||||||
use crate::{dice::calculate_single_die_amount, parser::DiceParsingError};
|
use crate::parser::dice::{Amount, DiceParsingError, Element};
|
||||||
use rand::rngs::StdRng;
|
use rand::rngs::StdRng;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
|
@ -420,7 +420,7 @@ pub async fn advancement_roll(
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::db::sqlite::Database;
|
use crate::db::sqlite::Database;
|
||||||
use crate::parser::{Amount, Element, Operator};
|
use crate::parser::dice::{Amount, Element, Operator};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
macro_rules! dummy_room {
|
macro_rules! dummy_room {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use super::dice::{AdvancementRoll, DiceRoll, DiceRollModifier};
|
use super::dice::{AdvancementRoll, DiceRoll, DiceRollModifier};
|
||||||
use crate::parser::DiceParsingError;
|
use crate::parser::dice::DiceParsingError;
|
||||||
|
|
||||||
//TOOD convert these to use parse_amounts from the common dice code.
|
//TOOD convert these to use parse_amounts from the common dice code.
|
||||||
|
|
||||||
|
@ -30,13 +30,13 @@ pub fn parse_regular_roll(input: &str) -> Result<DiceRoll, DiceParsingError> {
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
let modifier = parse_modifier(modifiers_str)?;
|
let modifier = parse_modifier(modifiers_str)?;
|
||||||
let amount = crate::parser::parse_single_amount(amounts_str)?;
|
let amount = crate::parser::dice::parse_single_amount(amounts_str)?;
|
||||||
Ok(DiceRoll { modifier, amount })
|
Ok(DiceRoll { modifier, amount })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_advancement_roll(input: &str) -> Result<AdvancementRoll, DiceParsingError> {
|
pub fn parse_advancement_roll(input: &str) -> Result<AdvancementRoll, DiceParsingError> {
|
||||||
let input = input.trim();
|
let input = input.trim();
|
||||||
let amounts = crate::parser::parse_single_amount(input)?;
|
let amounts = crate::parser::dice::parse_single_amount(input)?;
|
||||||
|
|
||||||
Ok(AdvancementRoll {
|
Ok(AdvancementRoll {
|
||||||
existing_skill: amounts,
|
existing_skill: amounts,
|
||||||
|
@ -45,9 +45,8 @@ pub fn parse_advancement_roll(input: &str) -> Result<AdvancementRoll, DiceParsin
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::parser::{Amount, Element, Operator};
|
use crate::parser::dice::{Amount, Element, Operator};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn regular_roll_accepts_single_number() {
|
fn regular_roll_accepts_single_number() {
|
||||||
|
|
45
src/dice.rs
45
src/dice.rs
|
@ -1,45 +0,0 @@
|
||||||
use crate::context::Context;
|
|
||||||
use crate::db::Variables;
|
|
||||||
use crate::error::BotError;
|
|
||||||
use crate::error::DiceRollingError;
|
|
||||||
use crate::parser::Amount;
|
|
||||||
use crate::parser::Element as NewElement;
|
|
||||||
use futures::stream::{self, StreamExt, TryStreamExt};
|
|
||||||
use std::slice;
|
|
||||||
|
|
||||||
/// Calculate the amount of dice to roll by consulting the database
|
|
||||||
/// and replacing variables with corresponding the amount. Errors out
|
|
||||||
/// if it cannot find a variable defined, or if the database errors.
|
|
||||||
pub async fn calculate_single_die_amount(
|
|
||||||
amount: &Amount,
|
|
||||||
ctx: &Context<'_>,
|
|
||||||
) -> Result<i32, BotError> {
|
|
||||||
calculate_dice_amount(slice::from_ref(amount), ctx).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate the amount of dice to roll by consulting the database
|
|
||||||
/// and replacing variables with corresponding amounts. Errors out if
|
|
||||||
/// it cannot find a variable defined, or if the database errors.
|
|
||||||
pub async fn calculate_dice_amount(amounts: &[Amount], ctx: &Context<'_>) -> Result<i32, BotError> {
|
|
||||||
let stream = stream::iter(amounts);
|
|
||||||
let variables = &ctx
|
|
||||||
.db
|
|
||||||
.get_user_variables(&ctx.username, ctx.room_id().as_str())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
use DiceRollingError::VariableNotFound;
|
|
||||||
let dice_amount: i32 = stream
|
|
||||||
.then(|amount| async move {
|
|
||||||
match &amount.element {
|
|
||||||
NewElement::Number(num_dice) => Ok(num_dice * amount.operator.mult()),
|
|
||||||
NewElement::Variable(variable) => variables
|
|
||||||
.get(variable)
|
|
||||||
.ok_or_else(|| VariableNotFound(variable.clone()))
|
|
||||||
.map(|i| *i),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.try_fold(0, |total, num_dice| async move { Ok(total + num_dice) })
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(dice_amount)
|
|
||||||
}
|
|
|
@ -50,7 +50,7 @@ pub enum BotError {
|
||||||
IoError(#[from] std::io::Error),
|
IoError(#[from] std::io::Error),
|
||||||
|
|
||||||
#[error("dice parsing error: {0}")]
|
#[error("dice parsing error: {0}")]
|
||||||
DiceParsingError(#[from] crate::parser::DiceParsingError),
|
DiceParsingError(#[from] crate::parser::dice::DiceParsingError),
|
||||||
|
|
||||||
#[error("command parsing error: {0}")]
|
#[error("command parsing error: {0}")]
|
||||||
CommandParsingError(#[from] crate::commands::parser::CommandParsingError),
|
CommandParsingError(#[from] crate::commands::parser::CommandParsingError),
|
||||||
|
@ -59,7 +59,7 @@ pub enum BotError {
|
||||||
DiceRollingError(#[from] DiceRollingError),
|
DiceRollingError(#[from] DiceRollingError),
|
||||||
|
|
||||||
#[error("variable parsing error: {0}")]
|
#[error("variable parsing error: {0}")]
|
||||||
VariableParsingError(#[from] crate::variables::VariableParsingError),
|
VariableParsingError(#[from] crate::parser::variables::VariableParsingError),
|
||||||
|
|
||||||
#[error("legacy parsing error")]
|
#[error("legacy parsing error")]
|
||||||
NomParserError(nom::error::ErrorKind),
|
NomParserError(nom::error::ErrorKind),
|
||||||
|
|
|
@ -6,7 +6,6 @@ pub mod config;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod cthulhu;
|
pub mod cthulhu;
|
||||||
pub mod db;
|
pub mod db;
|
||||||
pub mod dice;
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
mod help;
|
mod help;
|
||||||
pub mod logic;
|
pub mod logic;
|
||||||
|
@ -14,4 +13,3 @@ pub mod matrix;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
mod parser;
|
mod parser;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod variables;
|
|
||||||
|
|
46
src/logic.rs
46
src/logic.rs
|
@ -1,9 +1,12 @@
|
||||||
use crate::db::Rooms;
|
use crate::context::Context;
|
||||||
use crate::error::BotError;
|
use crate::db::{Rooms, Variables};
|
||||||
|
use crate::error::{BotError, DiceRollingError};
|
||||||
use crate::matrix;
|
use crate::matrix;
|
||||||
use crate::models::RoomInfo;
|
use crate::models::RoomInfo;
|
||||||
use futures::stream::{self, StreamExt};
|
use crate::parser::dice::{Amount, Element};
|
||||||
|
use futures::stream::{self, StreamExt, TryStreamExt};
|
||||||
use matrix_sdk::{self, identifiers::RoomId, Client};
|
use matrix_sdk::{self, identifiers::RoomId, Client};
|
||||||
|
use std::slice;
|
||||||
|
|
||||||
/// Record the information about a room, including users in it.
|
/// Record the information about a room, including users in it.
|
||||||
pub async fn record_room_information(
|
pub async fn record_room_information(
|
||||||
|
@ -46,3 +49,40 @@ pub async fn record_room_information(
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculate the amount of dice to roll by consulting the database
|
||||||
|
/// and replacing variables with corresponding the amount. Errors out
|
||||||
|
/// if it cannot find a variable defined, or if the database errors.
|
||||||
|
pub async fn calculate_single_die_amount(
|
||||||
|
amount: &Amount,
|
||||||
|
ctx: &Context<'_>,
|
||||||
|
) -> Result<i32, BotError> {
|
||||||
|
calculate_dice_amount(slice::from_ref(amount), ctx).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculate the amount of dice to roll by consulting the database
|
||||||
|
/// and replacing variables with corresponding amounts. Errors out if
|
||||||
|
/// it cannot find a variable defined, or if the database errors.
|
||||||
|
pub async fn calculate_dice_amount(amounts: &[Amount], ctx: &Context<'_>) -> Result<i32, BotError> {
|
||||||
|
let stream = stream::iter(amounts);
|
||||||
|
let variables = &ctx
|
||||||
|
.db
|
||||||
|
.get_user_variables(&ctx.username, ctx.room_id().as_str())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
use DiceRollingError::VariableNotFound;
|
||||||
|
let dice_amount: i32 = stream
|
||||||
|
.then(|amount| async move {
|
||||||
|
match &amount.element {
|
||||||
|
Element::Number(num_dice) => Ok(num_dice * amount.operator.mult()),
|
||||||
|
Element::Variable(variable) => variables
|
||||||
|
.get(variable)
|
||||||
|
.ok_or_else(|| VariableNotFound(variable.clone()))
|
||||||
|
.map(|i| *i),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.try_fold(0, |total, num_dice| async move { Ok(total + num_dice) })
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(dice_amount)
|
||||||
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub enum DiceParsingError {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::num::ParseIntError> for DiceParsingError {
|
impl From<std::num::ParseIntError> for DiceParsingError {
|
||||||
fn from(_error: std::num::ParseIntError) -> Self {
|
fn from(_: std::num::ParseIntError) -> Self {
|
||||||
DiceParsingError::ConversionError
|
DiceParsingError::ConversionError
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod dice;
|
||||||
|
pub mod variables;
|
Loading…
Reference in New Issue