diff options
| author | Sophie Forrest <git@sophieforrest.com> | 2024-08-30 23:13:20 +1200 |
|---|---|---|
| committer | Sophie Forrest <git@sophieforrest.com> | 2024-08-30 23:13:44 +1200 |
| commit | e3cb82a3b33bd2a2e49c58ce18d1258fb505869e (patch) | |
| tree | 2375279182fb4f90f5c28560a08cda90591f608b /crates/messenger_server/src/main.rs | |
Diffstat (limited to 'crates/messenger_server/src/main.rs')
| -rw-r--r-- | crates/messenger_server/src/main.rs | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/crates/messenger_server/src/main.rs b/crates/messenger_server/src/main.rs new file mode 100644 index 0000000..76ce81d --- /dev/null +++ b/crates/messenger_server/src/main.rs @@ -0,0 +1,142 @@ +#![feature(async_fn_in_trait)] +#![feature(custom_inner_attributes)] +#![feature(lint_reasons)] +#![feature(never_type)] +#![feature(lazy_cell)] +#![clippy::msrv = "1.69.0"] +#![deny(clippy::nursery)] +#![deny(clippy::pedantic)] +#![deny(clippy::alloc_instead_of_core)] +#![deny(clippy::as_underscore)] +#![deny(clippy::clone_on_ref_ptr)] +#![deny(clippy::create_dir)] +#![warn(clippy::dbg_macro)] +#![deny(clippy::default_numeric_fallback)] +#![deny(clippy::default_union_representation)] +#![deny(clippy::deref_by_slicing)] +#![deny(clippy::else_if_without_else)] +#![deny(clippy::empty_structs_with_brackets)] +#![deny(clippy::exit)] +#![deny(clippy::expect_used)] +#![deny(clippy::filetype_is_file)] +#![deny(clippy::fn_to_numeric_cast)] +#![deny(clippy::format_push_string)] +#![deny(clippy::get_unwrap)] +#![deny(clippy::if_then_some_else_none)] +#![allow( + clippy::implicit_return, + reason = "returns should be done implicitly, not explicitly" +)] +#![deny(clippy::indexing_slicing)] +#![deny(clippy::large_include_file)] +#![deny(clippy::let_underscore_must_use)] +#![deny(clippy::lossy_float_literal)] +#![deny(clippy::map_err_ignore)] +#![deny(clippy::mem_forget)] +#![deny(clippy::missing_docs_in_private_items)] +#![deny(clippy::missing_trait_methods)] +#![deny(clippy::multiple_inherent_impl)] +#![deny(clippy::needless_return)] +#![deny(clippy::non_ascii_literal)] +#![deny(clippy::panic_in_result_fn)] +#![deny(clippy::pattern_type_mismatch)] +#![deny(clippy::rc_buffer)] +#![deny(clippy::rc_mutex)] +#![deny(clippy::rest_pat_in_fully_bound_structs)] +#![deny(clippy::same_name_method)] +#![deny(clippy::separated_literal_suffix)] +#![deny(clippy::str_to_string)] +#![deny(clippy::string_add)] +#![deny(clippy::string_slice)] +#![deny(clippy::string_to_string)] +#![allow( + clippy::tabs_in_doc_comments, + reason = "tabs are preferred for this project" +)] +#![deny(clippy::try_err)] +#![deny(clippy::undocumented_unsafe_blocks)] +#![deny(clippy::unnecessary_self_imports)] +#![deny(clippy::unneeded_field_pattern)] +#![deny(clippy::unwrap_in_result)] +#![deny(clippy::unwrap_used)] +#![warn(clippy::use_debug)] +#![deny(clippy::verbose_file_reads)] +#![deny(clippy::wildcard_dependencies)] +#![deny(clippy::wildcard_enum_match_arm)] +#![deny(clippy::missing_panics_doc)] +#![deny(missing_copy_implementations)] +#![deny(missing_debug_implementations)] +#![deny(missing_docs)] +#![deny(single_use_lifetimes)] +#![deny(unsafe_code)] +#![deny(unused)] +// Server-specific lint disables +#![allow(clippy::redundant_pub_crate)] + +//! # Messenger Server +//! +//! Provides a server-side implementation of the messenger protocol + +mod app; +mod message; +mod session; +mod websocket; + +use std::{ + collections::{HashSet, VecDeque}, + net::{Ipv4Addr, SocketAddr, SocketAddrV4}, + sync::Arc, +}; + +use app::State as AppState; +use axum::{response::Html, routing::get, Router}; +use tokio::sync::{broadcast, Mutex}; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; + +/// Socket Address the server is bound to when ran. +const ADDR: SocketAddr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 3000)); + +#[tokio::main] +async fn main() { + tracing_subscriber::registry() + .with( + tracing_subscriber::EnvFilter::try_from_default_env() + .unwrap_or_else(|_| "chat=trace".into()), + ) + .with(tracing_subscriber::fmt::layer()) + .init(); + + // Set up application state for use with with_state(). + let user_set: Mutex<HashSet<String>> = Mutex::new(HashSet::new()); + let (tx, _rx) = broadcast::channel::<String>(100); + let message_history = Mutex::new(VecDeque::new()); + + let app_state = Arc::new(AppState { + message_history, + tx, + user_set, + }); + + let app = Router::new() + .route("/", get(index)) + .route("/websocket", get(websocket::handler)) + .with_state(app_state); + + tracing::debug!("listening on {ADDR}"); + + if let Err(error) = axum::Server::bind(&ADDR) + .serve(app.into_make_service()) + .await + { + tracing::error!("server failed to start: {error}"); + } +} + +/// Include utf-8 file at **compile** time. +#[expect( + clippy::unused_async, + reason = "axum requires this function to by async, but clippy disallows this" +)] +async fn index() -> Html<&'static str> { + Html(std::include_str!("../chat.html")) +} |