Apply cargo fmt --all

This commit is contained in:
2025-08-12 22:45:59 -03:00
parent 39c455f617
commit 5806493ca8
6 changed files with 64 additions and 80 deletions
+4 -4
View File
@@ -45,16 +45,16 @@
//! ```shell //! ```shell
//! $ cargo run -- start [TOKEN] //! $ cargo run -- start [TOKEN]
//! ``` //! ```
//! //!
//! # Running the Documentation Server //! # Running the Documentation Server
//! //!
//! Payphone has a built-in documentation server that serves the project's documentation and //! Payphone has a built-in documentation server that serves the project's documentation and
//! refreshes it on changes. To start the documentation server, run the following command: //! refreshes it on changes. To start the documentation server, run the following command:
//! //!
//! ```shell //! ```shell
//! $ cargo run -- docs --open //! $ cargo run -- docs --open
//! ``` //! ```
//! //!
//! The `--open` flag is optional and will open the documentation in the default browser after //! The `--open` flag is optional and will open the documentation in the default browser after
//! starting the server. You can also use the `--bind` argument to specify the address to bind the //! starting the server. You can also use the `--bind` argument to specify the address to bind the
//! server to, which defaults to `0.0.0.0:3000`. //! server to, which defaults to `0.0.0.0:3000`.
+4 -24
View File
@@ -37,24 +37,14 @@ pub trait IntoPrefixes<T> {
#[async_trait] #[async_trait]
impl<T> IntoPrefixes<T> for String { impl<T> IntoPrefixes<T> for String {
async fn get( async fn get(&self, _: &Runtime<T>, _: Option<u64>, _: Option<u64>) -> Vec<String> {
&self,
_: &Runtime<T>,
_: Option<u64>,
_: Option<u64>,
) -> Vec<String> {
vec![self.to_string()] vec![self.to_string()]
} }
} }
#[async_trait] #[async_trait]
impl<T> IntoPrefixes<T> for &str { impl<T> IntoPrefixes<T> for &str {
async fn get( async fn get(&self, _: &Runtime<T>, _: Option<u64>, _: Option<u64>) -> Vec<String> {
&self,
_: &Runtime<T>,
_: Option<u64>,
_: Option<u64>,
) -> Vec<String> {
vec![self.to_string()] vec![self.to_string()]
} }
} }
@@ -64,12 +54,7 @@ impl<T: Send + Sync + 'static, const N: usize, S: Send + Sync + 'static> IntoPre
where where
T: ToString, T: ToString,
{ {
async fn get( async fn get(&self, _: &Runtime<S>, _: Option<u64>, _: Option<u64>) -> Vec<String> {
&self,
_: &Runtime<S>,
_: Option<u64>,
_: Option<u64>,
) -> Vec<String> {
self.iter().map(|s| s.to_string()).collect() self.iter().map(|s| s.to_string()).collect()
} }
} }
@@ -80,12 +65,7 @@ where
F: Fn() -> Fut + Send + Sync + 'static, F: Fn() -> Fut + Send + Sync + 'static,
Fut: Future<Output = Vec<String>> + Send, Fut: Future<Output = Vec<String>> + Send,
{ {
async fn get( async fn get(&self, _: &Runtime<T>, _: Option<u64>, _: Option<u64>) -> Vec<String> {
&self,
_: &Runtime<T>,
_: Option<u64>,
_: Option<u64>,
) -> Vec<String> {
(self)().await (self)().await
} }
} }
+37 -37
View File
@@ -1,35 +1,35 @@
//! A framework for building Discord bots, built with Twilight. //! A framework for building Discord bots, built with Twilight.
//! //!
//! Since Twilight is a low-level library, it can be hard to build a bot with it. Payphone's //! Since Twilight is a low-level library, it can be hard to build a bot with it. Payphone's
//! framework provides a high-level interface for building Discord bots, with a focus on modularity //! framework provides a high-level interface for building Discord bots, with a focus on modularity
//! and ease of use. The framework is designed to be extensible, allowing you to add new features //! and ease of use. The framework is designed to be extensible, allowing you to add new features
//! and commands without modifying the core codebase. It also provides a set of utilities for //! and commands without modifying the core codebase. It also provides a set of utilities for
//! common tasks, such as sending messages, handling events, and managing state. //! common tasks, such as sending messages, handling events, and managing state.
//! //!
//! # Creating a Bot //! # Creating a Bot
//! //!
//! Creating a bot with Payphone is as simple as creating a new instance of the `Bot` struct and //! Creating a bot with Payphone is as simple as creating a new instance of the `Bot` struct and
//! running it. The `Bot` struct is the main entry point for the framework and provides methods for //! running it. The `Bot` struct is the main entry point for the framework and provides methods for
//! running the bot, handling events, and managing state. //! running the bot, handling events, and managing state.
//! //!
//! ``` //! ```
//! use crate::framework::bot::Bot; //! use crate::framework::bot::Bot;
//! use crate::state::State; //! use crate::state::State;
//! //!
//! // Your app's state. //! // Your app's state.
//! let state = State::new(); //! let state = State::new();
//! //!
//! // Create a new bot instance with the state and a list of prefixes. //! // Create a new bot instance with the state and a list of prefixes.
//! let bot: Bot<State> = Bot::new(state, ["p."]); //! let bot: Bot<State> = Bot::new(state, ["p."]);
//! //!
//! bot.run(&token).await.unwrap(); //! bot.run(&token).await.unwrap();
//! ``` //! ```
//! //!
//! ### Prefixes //! ### Prefixes
//! //!
//! The framework supports multiple prefixes per command and allows you to set them dynamically //! The framework supports multiple prefixes per command and allows you to set them dynamically
//! based on server and user IDs. //! based on server and user IDs.
//! //!
//! ``` //! ```
//! async fn get_prefixes( //! async fn get_prefixes(
//! rt: &Runtime<State>, //! rt: &Runtime<State>,
@@ -37,15 +37,15 @@
//! user_id: Option<u64> //! user_id: Option<u64>
//! ) -> Vec<String> { //! ) -> Vec<String> {
//! // The runtime contains your state at [`Runtime::state`]. //! // The runtime contains your state at [`Runtime::state`].
//! //!
//! vec!["p.".to_string()] //! vec!["p.".to_string()]
//! } //! }
//! //!
//! let bot: Bot<State> = Bot::new(state, get_prefixes); //! let bot: Bot<State> = Bot::new(state, get_prefixes);
//! ``` //! ```
//! //!
//! Otherwise, you can just pass a static list of prefixes as shown in the previous example. //! Otherwise, you can just pass a static list of prefixes as shown in the previous example.
//! //!
//! ``` //! ```
//! // All of these are valid ways to create a bot with a prefix. //! // All of these are valid ways to create a bot with a prefix.
//! let bot: Bot<State> = Bot::new(state, ["p."]); //! let bot: Bot<State> = Bot::new(state, ["p."]);
@@ -53,77 +53,77 @@
//! let bot: Bot<State> = Bot::new(state, "p.".to_string()); //! let bot: Bot<State> = Bot::new(state, "p.".to_string());
//! let bot: Bot<State> = Bot::new(state, ["p.".to_string()]); //! let bot: Bot<State> = Bot::new(state, ["p.".to_string()]);
//! ``` //! ```
//! //!
//! Setting no prefix will make the bot raise errors when receiving messages. //! Setting no prefix will make the bot raise errors when receiving messages.
//! //!
//! ## Adding Commands //! ## Adding Commands
//! //!
//! Creating a command is quite simple. You just need to implement the `Command` trait and register //! Creating a command is quite simple. You just need to implement the `Command` trait and register
//! it with the bot. //! it with the bot.
//! //!
//! ``` //! ```
//! use crate::framework::commands::{Command, CommandError, context::CommandContext}; //! use crate::framework::commands::{Command, CommandError, context::CommandContext};
//! //!
//! pub struct MyCommand; //! pub struct MyCommand;
//! //!
//! #[async_trait::async_trait] //! #[async_trait::async_trait]
//! impl Command<State> for MyCommand { //! impl Command<State> for MyCommand {
//! fn name(&self) -> &'static str { //! fn name(&self) -> &'static str {
//! "my_command" //! "my_command"
//! } //! }
//! //!
//! async fn execute(&self, ctx: CommandContext<'_, T>, _args: &str) -> Result<(), CommandError> { //! async fn execute(&self, ctx: CommandContext<'_, T>, _args: &str) -> Result<(), CommandError> {
//! // Your command logic here. //! // Your command logic here.
//! ctx.send() //! ctx.send()
//! .content("Hello, world!") //! .content("Hello, world!")
//! .await //! .await
//! .map_err(|_| CommandError::MessageSendingFailed)?; //! .map_err(|_| CommandError::MessageSendingFailed)?;
//! //!
//! Ok(()) //! Ok(())
//! } //! }
//! } //! }
//! ``` //! ```
//! //!
//! Then you just need to register the command with the bot: //! Then you just need to register the command with the bot:
//! //!
//! ``` //! ```
//! let bot = Bot::new(state, ["p."]).command(MyCommand); //! let bot = Bot::new(state, ["p."]).command(MyCommand);
//! //!
//! bot.run(&token).await.unwrap(); //! bot.run(&token).await.unwrap();
//! ``` //! ```
//! //!
//! Log into your Discord account and invite the bot to your server. Then you can test the command //! Log into your Discord account and invite the bot to your server. Then you can test the command
//! by sending `p.my_command` in a channel the bot has access to. //! by sending `p.my_command` in a channel the bot has access to.
//! //!
//! ### Configuring Commands Further //! ### Configuring Commands Further
//! //!
//! Commands can be configured with additional metadata, such as aliases, descriptions, and //! Commands can be configured with additional metadata, such as aliases, descriptions, and
//! arguments. The following is a full example of a command with all these features: //! arguments. The following is a full example of a command with all these features:
//! //!
//! ``` //! ```
//! use crate::framework::commands::{ //! use crate::framework::commands::{
//! Command, CommandError, context::CommandContext, arguments::NeedyGreedyString //! Command, CommandError, context::CommandContext, arguments::NeedyGreedyString
//! }; //! };
//! use crate::state::State; //! use crate::state::State;
//! //!
//! pub struct HelloCommand; //! pub struct HelloCommand;
//! //!
//! #[async_trait::async_trait] //! #[async_trait::async_trait]
//! impl Command<State> for HelloCommand { //! impl Command<State> for HelloCommand {
//! fn name(&self) -> &'static str { //! fn name(&self) -> &'static str {
//! "hello" //! "hello"
//! } //! }
//! //!
//! /// A list of alternative names for the command. //! /// A list of alternative names for the command.
//! fn aliases(&self) -> &'static [&'static str] { //! fn aliases(&self) -> &'static [&'static str] {
//! &["hola", "hey", "hi", "konnichiwa"] //! &["hola", "hey", "hi", "konnichiwa"]
//! } //! }
//! //!
//! /// A description of the command and its functionality. //! /// A description of the command and its functionality.
//! fn description(&self) -> &'static str { //! fn description(&self) -> &'static str {
//! "This command responds with a greeting." //! "This command responds with a greeting."
//! } //! }
//! //!
//! /// A list of arguments the command accepts. These are solely for documentation purposes, //! /// A list of arguments the command accepts. These are solely for documentation purposes,
//! /// they won't affect the parsing you do in the command's `execute` method. //! /// they won't affect the parsing you do in the command's `execute` method.
//! fn arguments(&self) -> &'static [Argument] { //! fn arguments(&self) -> &'static [Argument] {
@@ -135,7 +135,7 @@
//! }, //! },
//! ] //! ]
//! } //! }
//! //!
//! async fn execute( //! async fn execute(
//! &self, //! &self,
//! ctx: CommandContext<'_, T>, //! ctx: CommandContext<'_, T>,
@@ -146,12 +146,12 @@
//! args //! args
//! ) //! )
//! .unwrap_or(NeedyGreedyString("???".to_string())); //! .unwrap_or(NeedyGreedyString("???".to_string()));
//! //!
//! ctx.send() //! ctx.send()
//! .content(format!("Hello, {}!", name.0)) //! .content(format!("Hello, {}!", name.0))
//! .await //! .await
//! .map_err(|_| CommandError::MessageSendingFailed)?; //! .map_err(|_| CommandError::MessageSendingFailed)?;
//! //!
//! Ok(()) //! Ok(())
//! } //! }
//! } //! }
+5 -1
View File
@@ -184,7 +184,11 @@ pub fn censor_message(
for finding in findings { for finding in findings {
for (index, _) in normalized.message.match_indices(finding) { for (index, _) in normalized.message.match_indices(finding) {
let start_index = normalized.mappings.get(index).cloned().unwrap_or(0); let start_index = normalized.mappings.get(index).cloned().unwrap_or(0);
let end_index = normalized.mappings.get(index + finding.len()).cloned().unwrap_or(original.len()); let end_index = normalized
.mappings
.get(index + finding.len())
.cloned()
.unwrap_or(original.len());
ranges.push((start_index, end_index)); ranges.push((start_index, end_index));
} }
+10 -10
View File
@@ -1,16 +1,16 @@
//! Log handling and formatting of the console's output. //! Log handling and formatting of the console's output.
//! //!
//! # Logging //! # Logging
//! //!
//! Payphone uses the [`log`] crate for logging, and the [`colored`] crate for formatting the //! Payphone uses the [`log`] crate for logging, and the [`colored`] crate for formatting the
//! output. //! output.
//! //!
//! Any logs that are not coming from the `payphone` crate are ignored. //! Any logs that are not coming from the `payphone` crate are ignored.
//! //!
//! ## Logging Levels //! ## Logging Levels
//! //!
//! There are 5 different logging levels: //! There are 5 different logging levels:
//! //!
//! - `trace`: The most verbose level, used for debugging purposes. //! - `trace`: The most verbose level, used for debugging purposes.
//! - `debug`: Events that are useful to be displayed during development, but not in production. //! - `debug`: Events that are useful to be displayed during development, but not in production.
//! - `info`: Used for general information about the bot's state and milestones. //! - `info`: Used for general information about the bot's state and milestones.
@@ -19,9 +19,9 @@
//! - `error`: Used for errors, when something goes wrong and the bot cannot continue running. //! - `error`: Used for errors, when something goes wrong and the bot cannot continue running.
//! //!
//! ## Usage //! ## Usage
//! //!
//! Logging is quite simple as it works like any [`println!`] calls. //! Logging is quite simple as it works like any [`println!`] calls.
//! //!
//! ``` //! ```
//! log::trace!("This is a trace message."); //! log::trace!("This is a trace message.");
//! log::debug!("This is a debug message."); //! log::debug!("This is a debug message.");
@@ -29,9 +29,9 @@
//! log::warn!("This is a warning message."); //! log::warn!("This is a warning message.");
//! log::error!("This is an error message."); //! log::error!("This is an error message.");
//! ``` //! ```
//! //!
//! Logging supports formatting, so you can use it like any other [`println!`] call: //! Logging supports formatting, so you can use it like any other [`println!`] call:
//! //!
//! ``` //! ```
//! let value = 42; //! let value = 42;
//! log::info!("The value is: {value}"); //! log::info!("The value is: {value}");
+4 -4
View File
@@ -1,18 +1,18 @@
//! Application state at runtime including shared resources. //! Application state at runtime including shared resources.
//! //!
//! Currently, it only contains the database connection, but it can be extended in the future to //! Currently, it only contains the database connection, but it can be extended in the future to
//! include other resources that need to be shared across the application, such as caches or //! include other resources that need to be shared across the application, such as caches or
//! configuration settings. //! configuration settings.
//! //!
//! It is shared around the application using an `Arc`, allowing it to be cloned and passed around //! It is shared around the application using an `Arc`, allowing it to be cloned and passed around
//! without needing to worry about ownership or lifetimes. This is particularly useful in an //! without needing to worry about ownership or lifetimes. This is particularly useful in an
//! asynchronous context. //! asynchronous context.
//! //!
//! ``` //! ```
//! let state = State { //! let state = State {
//! db: database::init("127.0.0.1:9042").await?, //! db: database::init("127.0.0.1:9042").await?,
//! }; //! };
//! //!
//! fn handler_which_needs_state(state: Arc<State>) { //! fn handler_which_needs_state(state: Arc<State>) {
//! // Use the state here //! // Use the state here
//! } //! }