You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: mod.rs
    path of file: ./repos/serenity/src/framework/standard
    
    the code of the file until where you have to start completion: #![cfg_attr(
    not(ignore_serenity_deprecated),
    deprecated = "The standard framework is deprecated, and will be removed in 0.13. Please migrate to `poise` for command handling"
)]

pub mod help_commands;
pub mod macros {
    pub use command_attr::{check, command, group, help, hook};
}

mod args;
mod configuration;
mod parse;
mod structures;

use std::collections::HashMap;
use std::sync::Arc;

pub use args::{Args, Delimiter, Error as ArgError, Iter, RawArguments};
use async_trait::async_trait;
pub use configuration::{Configuration, WithWhiteSpace};
use futures::future::BoxFuture;
use parse::map::{CommandMap, GroupMap, Map};
use parse::{Invoke, ParseError};
pub use structures::buckets::BucketBuilder;
use structures::buckets::{Bucket, RateLimitAction};
pub use structures::*;
use tokio::sync::Mutex;
use tokio::time::sleep;
use tracing::instrument;
use uwl::Stream;

use self::buckets::{RateLimitInfo, RevertBucket};
use super::Framework;
#[cfg(feature = "cache")]
use crate::cache::Cache;
use crate::client::{Context, FullEvent};
use crate::model::channel::Message;
#[cfg(feature = "cache")]
use crate::model::guild::Member;
use crate::model::permissions::Permissions;
#[cfg(all(feature = "cache", feature = "http", feature = "model"))]
use crate::model::{guild::Role, id::RoleId};

/// An enum representing all possible fail conditions under which a command won't be executed.
#[derive(Debug)]
#[non_exhaustive]
pub enum DispatchError {
    /// When a custom function check has failed.
    CheckFailed(&'static str, Reason),
    /// When the command caller has exceeded a ratelimit bucket.
    Ratelimited(RateLimitInfo),
    /// When the requested command is disabled in bot configuration.
    CommandDisabled,
    /// When the user is blocked in bot configuration.
    BlockedUser,
    /// When th
    
    async fn dispatch(&self, mut ctx: Context, event: FullEvent) {
        let FullEvent::Message {
            new_message: msg,
        } = event
        else {
            return;
        };

        if self.should_ignore(&msg) {
            return;
        }

        let mut stream = Stream::new(&msg.content);

        stream.take_while_char(char::is_whitespace);

        let config = self.config.read().clone();

        let prefix = parse::prefix(&ctx, &msg, &mut stream, &config).await;

        if prefix.is_some() && stream.rest().is_empty() {
            if let Some(prefix_only) = &self.prefix_only {
                prefix_only(&mut ctx, &msg).await;
            }

            return;
        }

        if prefix.is_none() && !(config.no_dm_prefix && msg.is_private()) {
            if let Some(normal) = &self.normal_message {
                normal(&mut ctx, &msg).await;
            }

            return;
        }

        let invocation = parse::command(
            &ctx,
            &msg,
            &mut stream,
            &self.groups,
            &config,
            self.help.map(|h| h.options.names),
        )
        .await;

        let invoke = match invocation {
            Ok(i) => i,
            Err(ParseError::UnrecognisedCommand(unreg)) => {
                if let Some(unreg) = unreg {
                    if let Some(unrecognised_command) = &self.unrecognised_command {
                        unrecognised_command(&mut ctx, &msg, &unreg).await;
                    }
                }

                if let Some(normal) = &self.normal_message {
                    normal(&mut ctx, &msg).await;
                }

                return;
            },
            Err(ParseError::Dispatch {
                error,
                command_name,
            }) => {
                if let Some(dispatch) = &self.dispatch {
                    dispatch(&mut ctx, &msg, error, &command_name).await;
                }

                return;
            },
        };

        match invoke {
            Invoke::Help(name) => {
                if !config.allow_dm && msg.is_private() {
                    return;
                }

                let args = Args::new(stream.rest(), &config.delimiters);

                let groups = self.groups.iter().map(|(g, _)| *g).collect::<Vec<_>>();

                // `parse_command` promises to never return a help invocation if
                // `StandardFramework::help` is `None`.
                #[allow(clippy::unwrap_used)]
                let help = self.help.unwrap();

                if let Some(before) = &self.before {
                    if !before(&mut ctx, &msg, name).await {
                        return;
                    }
                }

                let res =
                    (help.fun)(&mut ctx, &msg, args, help.options, &groups, config.owners).await;

                if let Some(after) = &self.after {
                    after(&mut ctx, &msg, name, res).await;
                }
            },
            Invoke::Command {
                command,
                group,
            } => {
                let mut args = {
                    use std::borrow::Cow;

                    let mut delims = Cow::Borrowed(&config.delimiters);

                    // If user has configured the command's own delimiters, use those instead.
                    if !command.options.delimiters.is_empty() {
                        // FIXME: Get rid of this allocation.
                        let mut v = Vec::with_capacity(command.options.delimiters.len());

                        for delim in command.options.delimiters {
                            if delim.len() == 1 {
                                // Should always be Some() in this case
                                #[allow(clippy::unwrap_used)]
                                v.push(Delimiter::Single(delim.chars().next().unwrap()));
                            } else {
                                // This too.
                                v.push(Delimiter::Multiple((*delim).to_string()));
                            }
                        }

                        delims = Cow::Owned(v);
                    }

                    Args::new(stream.rest(), &delims)
                };

                if let Some(error) =
                    self.should_fail(&ctx, &msg, &mut args, command.options, group.options).await
                {
                    if let Some(dispatch) = &self.dispatch {
                        let command_name = command.options.names[0];
                        dispatch(&mut ctx, &msg, error, command_name).await;
                    }

                    return;
                }

                let name = command.options.names[0];

                if let Some(before) = &self.before {
                    if !before(&mut ctx, &msg, name).await {
                        return;
                    }
                }

                let res = (command.fun)(&mut ctx, &msg, args).await;

                // Check if the command wants to revert the bucket by giving back a ticket.
                if matches!(&res, Err(e) if e.is::<RevertBucket>()) {
                    let mut buckets = self.buckets.lock().await;

                    if let Some(bucket) = command.options.bucket.and_then(|b| buckets.get_mut(b)) {
                        bucket.give(&ctx, &msg).await;
                    }
                }

                if let Some(after) = &self.after {
                    after(&mut ctx, &msg, name, res).await;
                }
            },
        }
    }