sparkle_convenience/
lib.rs

1#![allow(deprecated)]
2#![warn(
3    clippy::cargo,
4    clippy::nursery,
5    clippy::pedantic,
6    rustdoc::broken_intra_doc_links,
7    rustdoc::private_intra_doc_links,
8    rustdoc::missing_crate_level_docs,
9    rustdoc::private_doc_tests,
10    rustdoc::invalid_codeblock_attributes,
11    rustdoc::invalid_html_tags,
12    rustdoc::invalid_rust_codeblocks,
13    rustdoc::bare_urls,
14    absolute_paths_not_starting_with_crate,
15    elided_lifetimes_in_paths,
16    explicit_outlives_requirements,
17    keyword_idents,
18    macro_use_extern_crate,
19    meta_variable_misuse,
20    missing_abi,
21    missing_copy_implementations,
22    missing_debug_implementations,
23    missing_docs,
24    non_ascii_idents,
25    noop_method_call,
26    pointer_structural_match,
27    rust_2021_incompatible_closure_captures,
28    rust_2021_incompatible_or_patterns,
29    rust_2021_prefixes_incompatible_syntax,
30    rust_2021_prelude_collisions,
31    single_use_lifetimes,
32    trivial_casts,
33    trivial_numeric_casts,
34    unsafe_code,
35    unsafe_op_in_unsafe_fn,
36    unstable_features,
37    unused_crate_dependencies,
38    unused_extern_crates,
39    unused_import_braces,
40    unused_lifetimes,
41    unused_macro_rules,
42    unused_qualifications,
43    variant_size_differences,
44    // Nightly lints:
45    // fuzzy_provenance_casts,
46    // lossy_provenance_casts,
47    // must_not_suspend,
48    // non_exhaustive_omitted_patterns,
49)]
50#![doc = include_str!("../README.md")]
51
52use std::fmt::Debug;
53
54use error::Error;
55use log::DisplayFormat;
56use twilight_gateway::{stream, ConfigBuilder, EventTypeFlags, Intents, Shard};
57use twilight_http::Client;
58use twilight_model::{
59    id::{marker::WebhookMarker, Id},
60    oauth::Application,
61    user::CurrentUser,
62};
63
64/// User error types and converting options to results
65pub mod error;
66/// Convenient interaction handling
67pub mod interaction;
68/// Logging methods on [`Bot`]
69pub mod log;
70/// Convenient message handling
71pub mod message;
72/// Formatting types into user-readable pretty strings
73pub mod prettify;
74/// The [`reply::Reply`] struct
75pub mod reply;
76/// Convenient webhook handling
77#[deprecated(note = "use `Reply::execute_webhook` instead")]
78pub mod webhook;
79
80/// All data required to make a bot run
81#[derive(Debug)]
82#[must_use]
83pub struct Bot {
84    /// Twilight's HTTP client
85    pub http: Client,
86    /// The application info of the bot
87    pub application: Application,
88    /// The user info of the bot
89    pub user: CurrentUser,
90    /// The format configuration for logging
91    #[deprecated(note = "Will be removed as `Bot::log` will take `String`")]
92    pub logging_format: DisplayFormat,
93    /// Whether to print messages when logging
94    #[deprecated(note = "Logging functionality will be reduced to webhooks only")]
95    pub logging_print_enabled: bool,
96    /// The webhook to log errors using
97    pub logging_webhook: Option<(Id<WebhookMarker>, String)>,
98    /// The file to append errors to
99    #[deprecated(note = "Logging functionality will be reduced to webhooks only")]
100    pub logging_file_path: Option<String>,
101}
102
103impl Bot {
104    /// Create a new bot with the given token, intents and event types
105    ///
106    /// It's recommended to pass [`EventTypeFlags::all`] if using a cache
107    ///
108    /// By default [`Bot::log`] only prints the message, see
109    /// [`Bot::set_logging_channel`] and [`Bot::set_logging_file`]
110    ///
111    /// If you need more customization, every field of [`Bot`] is public so you
112    /// can create it with a struct literal
113    ///
114    /// # Errors
115    ///
116    /// Returns [`Error::StartRecommended`] if creating the cluster fails
117    ///
118    /// Returns [`Error::Http`] or [`Error::DeserializeBody`] if getting the
119    /// application info fails
120    pub async fn new(
121        token: String,
122        intents: Intents,
123        event_types: EventTypeFlags,
124    ) -> Result<(Self, Vec<Shard>), Error> {
125        let http = Client::new(token.clone());
126
127        let shards = stream::create_recommended(
128            &http,
129            ConfigBuilder::new(token.clone(), intents)
130                .event_types(event_types)
131                .build(),
132            |_, config_builder| config_builder.build(),
133        )
134        .await?
135        .collect::<Vec<Shard>>();
136
137        let application = http.current_user_application().await?.model().await?;
138        let user = http.current_user().await?.model().await?;
139
140        Ok((
141            Self {
142                http,
143                application,
144                user,
145                logging_format: DisplayFormat::Display,
146                logging_print_enabled: true,
147                logging_webhook: None,
148                logging_file_path: None,
149            },
150            shards,
151        ))
152    }
153}