Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[workspace]
resolver = "3"
members = [ "factorion-lib", "factorion-math","factorion-bot-reddit", "factorion-bot-discord"]
members = [ "factorion-lib", "factorion-math","factorion-bot-reddit", "factorion-bot-discord", "factorion-cli"]
exclude = [ ".old" ]
4 changes: 2 additions & 2 deletions factorion-bot-discord/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "factorion-bot-discord"
version = "2.1.1"
version = "2.1.2"
edition = "2024"
description = "factorion-bot (for factorials and related) on Discord"
license = "MIT"
Expand All @@ -10,7 +10,7 @@ keywords = ["factorial", "termial", "bot", "math", "discord"]
categories = ["mathematics", "web-programming", "parser-implementations"]

[dependencies]
factorion-lib = { path = "../factorion-lib", version = "4.1.1", features = ["serde", "influxdb"] }
factorion-lib = { path = "../factorion-lib", version = "4.2.0", features = ["serde", "influxdb"] }
serenity = { version = "0.12", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "cache"] }
tokio = { version = "1.48.0", features = ["macros", "rt-multi-thread", "time"] }
dotenvy = "^0.15.7"
Expand Down
4 changes: 2 additions & 2 deletions factorion-bot-discord/src/discord_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::time::SystemTime;

use anyhow::Error;
use factorion_lib::Consts;
use factorion_lib::comment::{Commands, Comment, CommentConstructed};
use factorion_lib::comment::{Commands, Comment, CommentConstructed, Formatting};
use factorion_lib::influxdb::InfluxDbClient;
use log::{error, info, warn};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -178,7 +178,7 @@ impl<'a> Handler<'a> {
return Ok(());
}

let reply_text = comment.get_reply(&self.consts);
let reply_text = comment.get_reply(&self.consts, Formatting::Markdown);
let message_locale = comment.locale;

processed.insert(msg.id);
Expand Down
4 changes: 2 additions & 2 deletions factorion-bot-reddit/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "factorion-bot-reddit"
version = "5.2.1"
version = "5.2.2"
edition = "2024"
description = "factorion-bot (for factorials and related) on Reddit"
license = "MIT"
Expand All @@ -10,7 +10,7 @@ keywords = ["factorial", "termial", "bot", "math"]
categories = ["mathematics", "web-programming", "parser-implementations"]

[dependencies]
factorion-lib = {path = "../factorion-lib", version = "4.1.1", features = ["serde", "influxdb"]}
factorion-lib = {path = "../factorion-lib", version = "4.2.0", features = ["serde", "influxdb"]}
reqwest = { version = "0.12.26", features = ["json", "native-tls"], default-features = false }
serde = { version = "1.0.219", default-features = false, features = ["derive"] }
serde_json = "1.0.140"
Expand Down
6 changes: 3 additions & 3 deletions factorion-bot-reddit/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#![doc = include_str!("../README.md")]
use crate::reddit_api::Thread;
use dotenvy::dotenv;
use factorion_lib::comment::Formatting;
use factorion_lib::{
Consts,
comment::{Commands, Comment, Status},
Expand All @@ -20,8 +22,6 @@ use std::sync::OnceLock;
use std::time::SystemTime;
use tokio::time::{Duration, sleep};

use crate::reddit_api::Thread;

mod reddit_api;

const API_COMMENT_COUNT: u32 = 100;
Expand Down Expand Up @@ -383,7 +383,7 @@ async fn main() -> Result<(), Box<dyn Error>> {

if should_answer {
let Ok(reply): Result<String, _> =
std::panic::catch_unwind(|| comment.get_reply(&consts))
std::panic::catch_unwind(|| comment.get_reply(&consts, Formatting::Markdown))
else {
error!("Failed to format comment!");
continue;
Expand Down
17 changes: 17 additions & 0 deletions factorion-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "factorion-cli"
version = "1.0.0"
edition = "2024"
description = "Basic CLI implementation of factorion"
license = "MIT"
repository = "https://github.com/tolik518/factorion-bot/"
readme = "../README.md"
keywords = ["factorial", "termial", "bot", "math"]
categories = ["mathematics"]

[dependencies]
factorion-lib = {path = "../factorion-lib", version = "4.0.1", features = ["serde", "influxdb"]}
serde_json = "1.0.140"
tokio = { version = "1.48.0", features = ["macros", "rt-multi-thread"] }
dotenvy = "^0.15.7"
env_logger = { version = "0.11.8"}
102 changes: 102 additions & 0 deletions factorion-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use dotenvy::dotenv;
use factorion_lib::comment::{Commands, Comment, Formatting};
use factorion_lib::comment::{CommentCalculated, CommentConstructed, CommentExtracted};
use factorion_lib::{Consts, locale::Locale};
use std::collections::HashMap;
use std::error::Error;
use std::io::Write;
use std::panic;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
init();

let consts = Consts {
float_precision: factorion_lib::recommended::FLOAT_PRECISION,
upper_calculation_limit: factorion_lib::recommended::UPPER_CALCULATION_LIMIT(),
upper_approximation_limit: factorion_lib::recommended::UPPER_APPROXIMATION_LIMIT(),
upper_subfactorial_limit: factorion_lib::recommended::UPPER_SUBFACTORIAL_LIMIT(),
upper_termial_limit: factorion_lib::recommended::UPPER_TERMIAL_LIMIT(),
upper_termial_approximation_limit:
factorion_lib::recommended::UPPER_TERMIAL_APPROXIMATION_LIMIT,
integer_construction_limit: factorion_lib::recommended::INTEGER_CONSTRUCTION_LIMIT(),
number_decimals_scientific: 16,
locales: std::env::var("LOCALES_DIR")
.map(|dir| {
let files = std::fs::read_dir(dir).unwrap();
let mut map = HashMap::new();
for (key, value) in files
.map(|file| {
let file = file.unwrap();
let locale: Locale<'static> = serde_json::de::from_str(
std::fs::read_to_string(file.path()).unwrap().leak(),
)
.unwrap();
(file.file_name().into_string().unwrap(), locale)
})
.collect::<Box<_>>()
{
map.insert(key, value);
}
map
})
.unwrap_or_else(|_| {
factorion_lib::locale::get_all()
.map(|(k, v)| (k.to_owned(), v))
.into()
}),
default_locale: "en".to_owned(),
};

let args: Vec<String> = std::env::args().collect();
let comment = args[1].clone();

//let consts = Consts::default();
let comment: CommentConstructed<&str> = Comment::new(
&*comment,
"meta",
Commands::TERMIAL | Commands::NO_NOTE,
10_000,
"en",
);
let comment: CommentExtracted<&str> = comment.extract(&consts);
let comment: CommentCalculated<&str> = comment.calc(&consts);

let reply = comment.get_reply(&consts, Formatting::None);
println!("{}", reply);

Ok(())
}

fn init() {
dotenv().ok();
env_logger::builder()
.format(|buf, record| {
let style = buf.default_level_style(record.level());
writeln!(
buf,
"{style}{} | {} | {} | {}",
record.level(),
record.target(),
buf.timestamp(),
record.args()
)
})
.init();

panic::set_hook(Box::new(|panic_info| {
let location = panic_info
.location()
.map(|l| format!("{}:{}", l.file(), l.line()))
.unwrap_or_else(|| "unknown location".to_string());

let message = panic_info
.payload()
.downcast_ref::<&str>()
.map(|s| s.to_string())
.or_else(|| panic_info.payload().downcast_ref::<String>().cloned())
.unwrap_or_else(|| format!("Unknown panic payload: {panic_info:?}"));

println!("Thread panicked at {location} with message: {message}");
}));
}
2 changes: 1 addition & 1 deletion factorion-lib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "factorion-lib"
version = "4.1.1"
version = "4.2.0"
edition = "2024"
description = "A library used to create bots to recognize and calculate factorials and related concepts"
license = "MIT"
Expand Down
4 changes: 3 additions & 1 deletion factorion-lib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ You can use the given abstraction for comments in [comment]:
```rust
use factorion_lib::comment::{Comment, CommentConstructed, CommentExtracted, CommentCalculated, Commands, Status};
use factorion_lib::Consts;
use factorion_lib::comment::Formatting;

// You need to define constants first
let consts = Consts::default();
Expand All @@ -19,7 +20,7 @@ let mut comment: CommentCalculated<&str> = comment.calc(&consts);
// Set flag, so a user will be notified (used when summoning on someone else)
comment.notify = Some("@you".to_owned());
// Format the reply
let reply = comment.get_reply(&consts);
let reply = comment.get_reply(&consts, Formatting::Markdown);
// Metadata is retained throughout
assert_eq!(comment.meta, "meta");
// Useful status
Expand All @@ -30,6 +31,7 @@ assert_eq!(reply, "Hey @you!\n\nTermial of factorial of 5 is 7260 \n\n\n*^(This
Or manually do the steps:
```rust
use factorion_lib::{parse::parse, calculation_tasks::{CalculationJob, CalculationBase}, calculation_results::{Calculation, CalculationResult, Number}, Consts};
use factorion_lib::comment::Formatting;

// You need to define constants first
let consts = Consts::default();
Expand Down
5 changes: 3 additions & 2 deletions factorion-lib/src/calculation_tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ pub mod recommended {
// Limit for exact subfactorial calculation, set to limit calculation time
pub static UPPER_SUBFACTORIAL_LIMIT: fn() -> Integer = || 1_000_000.into();
// Limit for exact termial calculation, set to limit calculation time (absurdly high)
pub static UPPER_TERMIAL_LIMIT: fn() -> Integer = || Integer::u64_pow_u64(10, 10000).complete();
pub static UPPER_TERMIAL_LIMIT: fn() -> Integer =
|| Integer::u64_pow_u64(10, 10_000).complete();
// Limit for approximation, set to ensure enough accuracy (5 decimals)
// Based on max float. (bits)
pub static UPPER_TERMIAL_APPROXIMATION_LIMIT: u32 = 1073741822;
pub static UPPER_TERMIAL_APPROXIMATION_LIMIT: u32 = 1_073_741_822;
}

/// Representation of the calculation to be done
Expand Down
28 changes: 22 additions & 6 deletions factorion-lib/src/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#[cfg(any(feature = "serde", test))]
use serde::{Deserialize, Serialize};
use std::cmp::PartialEq;

use crate::rug::integer::IntegerExt64;
use crate::rug::{Complete, Integer};
Expand Down Expand Up @@ -214,6 +215,12 @@ impl Commands {
}
}

#[derive(PartialEq, Eq)]
pub enum Formatting {
Markdown,
None,
}

macro_rules! contains_comb {
// top level (advance both separately)
($var:ident, [$start:tt,$($start_rest:tt),* $(,)?], [$end:tt,$($end_rest:tt),* $(,)?]) => {
Expand Down Expand Up @@ -408,7 +415,7 @@ impl<Meta> CommentExtracted<Meta> {
}
impl<Meta> CommentCalculated<Meta> {
/// Does the formatting for the reply using [calculation_result](crate::calculation_results).
pub fn get_reply(&self, consts: &Consts) -> String {
pub fn get_reply(&self, consts: &Consts, formatting: Formatting) -> String {
let mut fell_back = false;
let locale = consts.locales.get(&self.locale).unwrap_or_else(|| {
fell_back = true;
Expand All @@ -423,7 +430,12 @@ impl<Meta> CommentCalculated<Meta> {
if fell_back {
let _ = note.write_str("Sorry, I currently don't speak ");
let _ = note.write_str(&self.locale);
let _ = note.write_str(". Maybe you could [teach me](https://github.com/tolik518/factorion-bot/blob/master/CONTRIBUTING.md#translation)? \n\n");
if formatting == Formatting::Markdown {
let _ = note.write_str(". Maybe you could [teach me](https://github.com/tolik518/factorion-bot/blob/master/CONTRIBUTING.md#translation)? \n\n");
}
if formatting == Formatting::None {
let _ = note.write_str(". Maybe you could teach me: https://github.com/tolik518/factorion-bot/blob/master/CONTRIBUTING.md#translation \n\n");
}
}

let too_big_number = Integer::u64_pow_u64(10, self.max_length as u64).complete();
Expand Down Expand Up @@ -603,9 +615,13 @@ impl<Meta> CommentCalculated<Meta> {
}
}
if !locale.bot_disclaimer().is_empty() {
reply.push_str("\n*^(");
if formatting == Formatting::Markdown {
reply.push_str("\n*^(");
}
reply.push_str(locale.bot_disclaimer());
reply.push_str(")*");
if formatting == Formatting::Markdown {
reply.push_str(")*");
}
}
reply
}
Expand Down Expand Up @@ -727,7 +743,7 @@ mod tests {
let comment = Comment::new_already_replied((), MAX_LENGTH, "n/a")
.extract(&consts)
.calc(&consts);
let reply = comment.get_reply(&consts);
let reply = comment.get_reply(&consts, Formatting::Markdown);
assert_eq!(
reply,
"Sorry, I currently don't speak n/a. Maybe you could [teach me](https://github.com/tolik518/factorion-bot/blob/master/CONTRIBUTING.md#translation)? \n\n\n*^(This action was performed by a bot.)*"
Expand All @@ -741,7 +757,7 @@ mod tests {
.extract(&consts)
.calc(&consts);
comment.add_status(Status::LIMIT_HIT);
let reply = comment.get_reply(&consts);
let reply = comment.get_reply(&consts, Formatting::Markdown);
assert_eq!(
reply,
"I have repeated myself enough, I won't do that calculation again.\n\n\n*^(This action was performed by a bot.)*"
Expand Down
6 changes: 3 additions & 3 deletions factorion-lib/src/parse.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Parses text and extracts calculations

use crate::locale::{self, NumFormat};
use crate::locale::NumFormat;
use crate::rug::{Complete, Float, Integer, integer::IntegerExt64};

use crate::Consts;
Expand Down Expand Up @@ -833,9 +833,9 @@ fn parse_num_simple(
mod test {
use super::*;
use crate::calculation_tasks::CalculationBase::Num;
use arbtest::arbtest;

use crate::locale;
use crate::recommended::FLOAT_PRECISION;
use arbtest::arbtest;

#[test]
fn test_text_only() {
Expand Down
Loading
Loading