diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index 1997a39e..df13ad1f 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -1,6 +1,6 @@ use std::{ collections::BTreeMap, - fmt::{self, Write as _}, + fmt, net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}, path::PathBuf, }; @@ -522,364 +522,360 @@ impl Config { impl fmt::Display for Config { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Prepare a list of config values to show - let lines = [ - ("Server name", self.server_name.host()), - ("Database backend", &self.database_backend), - ("Database path", &self.database_path.to_string_lossy()), - ( - "Database backup path", - self.database_backup_path - .as_ref() - .map_or("", |path| path.to_str().unwrap_or("")), - ), - ("Database backups to keep", &self.database_backups_to_keep.to_string()), - ("Database cache capacity (MB)", &self.db_cache_capacity_mb.to_string()), - ("Cache capacity modifier", &self.conduit_cache_capacity_modifier.to_string()), - ("PDU cache capacity", &self.pdu_cache_capacity.to_string()), - ("Auth chain cache capacity", &self.auth_chain_cache_capacity.to_string()), - ("Short eventid cache capacity", &self.shorteventid_cache_capacity.to_string()), - ("Eventid short cache capacity", &self.eventidshort_cache_capacity.to_string()), - ("Short statekey cache capacity", &self.shortstatekey_cache_capacity.to_string()), - ("Statekey short cache capacity", &self.statekeyshort_cache_capacity.to_string()), - ( - "Server visibility cache capacity", - &self.server_visibility_cache_capacity.to_string(), - ), - ( - "User visibility cache capacity", - &self.user_visibility_cache_capacity.to_string(), - ), - ("Stateinfo cache capacity", &self.stateinfo_cache_capacity.to_string()), - ( - "Roomid space hierarchy cache capacity", - &self.roomid_spacehierarchy_cache_capacity.to_string(), - ), - ("DNS cache entry limit", &self.dns_cache_entries.to_string()), - ("DNS minimum TTL", &self.dns_min_ttl.to_string()), - ("DNS minimum NXDOMAIN TTL", &self.dns_min_ttl_nxdomain.to_string()), - ("DNS attempts", &self.dns_attempts.to_string()), - ("DNS timeout", &self.dns_timeout.to_string()), - ("DNS fallback to TCP", &self.dns_tcp_fallback.to_string()), - ("DNS query over TCP only", &self.query_over_tcp_only.to_string()), - ("Query all nameservers", &self.query_all_nameservers.to_string()), - ("Maximum request size (bytes)", &self.max_request_size.to_string()), - ("Sender retry backoff limit", &self.sender_retry_backoff_limit.to_string()), - ("Request connect timeout", &self.request_conn_timeout.to_string()), - ("Request timeout", &self.request_timeout.to_string()), - ("Request total timeout", &self.request_total_timeout.to_string()), - ("Idle connections per host", &self.request_idle_per_host.to_string()), - ("Request pool idle timeout", &self.request_idle_timeout.to_string()), - ("Well_known connect timeout", &self.well_known_conn_timeout.to_string()), - ("Well_known timeout", &self.well_known_timeout.to_string()), - ("Federation timeout", &self.federation_timeout.to_string()), - ("Federation pool idle per host", &self.federation_idle_per_host.to_string()), - ("Federation pool idle timeout", &self.federation_idle_timeout.to_string()), - ("Sender timeout", &self.sender_timeout.to_string()), - ("Sender pool idle timeout", &self.sender_idle_timeout.to_string()), - ("Appservice timeout", &self.appservice_timeout.to_string()), - ("Appservice pool idle timeout", &self.appservice_idle_timeout.to_string()), - ("Pusher pool idle timeout", &self.pusher_idle_timeout.to_string()), - ("Allow registration", &self.allow_registration.to_string()), - ( - "Registration token", - if self.registration_token.is_some() { - "set" - } else { - "not set (open registration!)" - }, - ), - ( - "Allow guest registration (inherently false if allow registration is false)", - &self.allow_guest_registration.to_string(), - ), - ( - "Log guest registrations in admin room", - &self.log_guest_registrations.to_string(), - ), - ( - "Allow guests to auto join rooms", - &self.allow_guests_auto_join_rooms.to_string(), - ), - ("New user display name suffix", &self.new_user_displayname_suffix), - ("Allow encryption", &self.allow_encryption.to_string()), - ("Allow federation", &self.allow_federation.to_string()), - ( - "Allow incoming federated presence requests (updates)", - &self.allow_incoming_presence.to_string(), - ), - ( - "Allow outgoing federated presence requests (updates)", - &self.allow_outgoing_presence.to_string(), - ), - ( - "Allow local presence requests (updates)", - &self.allow_local_presence.to_string(), - ), - ( - "Allow incoming remote read receipts", - &self.allow_incoming_read_receipts.to_string(), - ), - ( - "Allow outgoing remote read receipts", - &self.allow_outgoing_read_receipts.to_string(), - ), - ( - "Block non-admin room invites (local and remote, admins can still send and receive invites)", - &self.block_non_admin_invites.to_string(), - ), - ("Enable admin escape commands", &self.admin_escape_commands.to_string()), - ("Allow outgoing federated typing", &self.allow_outgoing_typing.to_string()), - ("Allow incoming federated typing", &self.allow_incoming_typing.to_string()), - ( - "Incoming federated typing timeout", - &self.typing_federation_timeout_s.to_string(), - ), - ("Client typing timeout minimum", &self.typing_client_timeout_min_s.to_string()), - ("Client typing timeout maxmimum", &self.typing_client_timeout_max_s.to_string()), - ("Allow device name federation", &self.allow_device_name_federation.to_string()), - ( - "Allow incoming profile lookup federation requests", - &self.allow_profile_lookup_federation_requests.to_string(), - ), - ( - "Auto deactivate banned room join attempts", - &self.auto_deactivate_banned_room_attempts.to_string(), - ), - ("Notification push path", &self.notification_push_path), - ("Allow room creation", &self.allow_room_creation.to_string()), - ( - "Allow public room directory over federation", - &self.allow_public_room_directory_over_federation.to_string(), - ), - ( - "Allow public room directory without authentication", - &self.allow_public_room_directory_without_auth.to_string(), - ), - ( - "Lockdown public room directory (only allow admins to publish)", - &self.lockdown_public_room_directory.to_string(), - ), - ( - "JWT secret", - match self.jwt_secret { - Some(_) => "set", - None => "not set", - }, - ), - ( - "Trusted key servers", - &self - .trusted_servers - .iter() - .map(|server| server.host()) - .join(", "), - ), - ( - "Query Trusted Key Servers First", - &self.query_trusted_key_servers_first.to_string(), - ), - ("OpenID Token TTL", &self.openid_token_ttl.to_string()), - ( - "TURN username", - if self.turn_username.is_empty() { - "not set" - } else { - &self.turn_username - }, - ), - ("TURN password", { - if self.turn_password.is_empty() { - "not set" - } else { - "set" - } - }), - ("TURN secret", { - if self.turn_secret.is_empty() { - "not set" - } else { - "set" - } - }), - ("Turn TTL", &self.turn_ttl.to_string()), - ("Turn URIs", { - let mut lst = vec![]; - for item in self.turn_uris.iter().cloned().enumerate() { - let (_, uri): (usize, String) = item; - lst.push(uri); - } - &lst.join(", ") - }), - ("Auto Join Rooms", { - let mut lst = vec![]; - for room in &self.auto_join_rooms { - lst.push(room); - } - &lst.into_iter().join(", ") - }), - #[cfg(feature = "zstd_compression")] - ("Zstd HTTP Compression", &self.zstd_compression.to_string()), - #[cfg(feature = "gzip_compression")] - ("Gzip HTTP Compression", &self.gzip_compression.to_string()), - #[cfg(feature = "brotli_compression")] - ("Brotli HTTP Compression", &self.brotli_compression.to_string()), - ("RocksDB database LOG level", &self.rocksdb_log_level), - ("RocksDB database LOG to stderr", &self.rocksdb_log_stderr.to_string()), - ("RocksDB database LOG time-to-roll", &self.rocksdb_log_time_to_roll.to_string()), - ("RocksDB Max LOG Files", &self.rocksdb_max_log_files.to_string()), - ( - "RocksDB database max LOG file size", - &self.rocksdb_max_log_file_size.to_string(), - ), - ( - "RocksDB database optimize for spinning disks", - &self.rocksdb_optimize_for_spinning_disks.to_string(), - ), - ("RocksDB Direct-IO", &self.rocksdb_direct_io.to_string()), - ("RocksDB Parallelism Threads", &self.rocksdb_parallelism_threads.to_string()), - ("RocksDB Compression Algorithm", &self.rocksdb_compression_algo), - ("RocksDB Compression Level", &self.rocksdb_compression_level.to_string()), - ( - "RocksDB Bottommost Compression Level", - &self.rocksdb_bottommost_compression_level.to_string(), - ), - ( - "RocksDB Bottommost Level Compression", - &self.rocksdb_bottommost_compression.to_string(), - ), - ("RocksDB Recovery Mode", &self.rocksdb_recovery_mode.to_string()), - ("RocksDB Repair Mode", &self.rocksdb_repair.to_string()), - ("RocksDB Read-only Mode", &self.rocksdb_read_only.to_string()), - ( - "RocksDB Compaction Idle Priority", - &self.rocksdb_compaction_prio_idle.to_string(), - ), - ( - "RocksDB Compaction Idle IOPriority", - &self.rocksdb_compaction_ioprio_idle.to_string(), - ), - ("Media integrity checks on startup", &self.media_startup_check.to_string()), - ("Media compatibility filesystem links", &self.media_compat_file_link.to_string()), - ("Prevent Media Downloads From", { - let mut lst = vec![]; - for domain in &self.prevent_media_downloads_from { - lst.push(domain.host()); - } - &lst.join(", ") - }), - ("Forbidden Remote Server Names (\"Global\" ACLs)", { - let mut lst = vec![]; - for domain in &self.forbidden_remote_server_names { - lst.push(domain.host()); - } - &lst.join(", ") - }), - ("Forbidden Remote Room Directory Server Names", { - let mut lst = vec![]; - for domain in &self.forbidden_remote_room_directory_server_names { - lst.push(domain.host()); - } - &lst.join(", ") - }), - ("Outbound Request IP Range Denylist", { - let mut lst = vec![]; - for item in self.ip_range_denylist.iter().cloned().enumerate() { - let (_, ip): (usize, String) = item; - lst.push(ip); - } - &lst.join(", ") - }), - ("Forbidden usernames", { - &self.forbidden_usernames.patterns().iter().join(", ") - }), - ("Forbidden room aliases", { - &self.forbidden_alias_names.patterns().iter().join(", ") - }), - ( - "URL preview domain contains allowlist", - &self.url_preview_domain_contains_allowlist.join(", "), - ), - ( - "URL preview domain explicit allowlist", - &self.url_preview_domain_explicit_allowlist.join(", "), - ), - ( - "URL preview domain explicit denylist", - &self.url_preview_domain_explicit_denylist.join(", "), - ), - ( - "URL preview URL contains allowlist", - &self.url_preview_url_contains_allowlist.join(", "), - ), - ("URL preview maximum spider size", &self.url_preview_max_spider_size.to_string()), - ("URL preview check root domain", &self.url_preview_check_root_domain.to_string()), - ( - "Allow check for updates / announcements check", - &self.allow_check_for_updates.to_string(), - ), - ("Enable netburst on startup", &self.startup_netburst.to_string()), - #[cfg(feature = "sentry_telemetry")] - ("Sentry.io reporting and tracing", &self.sentry.to_string()), - #[cfg(feature = "sentry_telemetry")] - ("Sentry.io send server_name in logs", &self.sentry_send_server_name.to_string()), - #[cfg(feature = "sentry_telemetry")] - ("Sentry.io tracing sample rate", &self.sentry_traces_sample_rate.to_string()), - ("Sentry.io attach stacktrace", &self.sentry_attach_stacktrace.to_string()), - ("Sentry.io send panics", &self.sentry_send_panic.to_string()), - ("Sentry.io send errors", &self.sentry_send_error.to_string()), - ( - "Well-known server name", - self.well_known - .server - .as_ref() - .map_or("", |server| server.as_str()), - ), - ( - "Well-known client URL", - self.well_known - .client - .as_ref() - .map_or("", |url| url.as_str()), - ), - ( - "Well-known support email", - self.well_known - .support_email - .as_ref() - .map_or("", |str| str.as_ref()), - ), - ( - "Well-known support Matrix ID", - self.well_known - .support_mxid - .as_ref() - .map_or("", |mxid| mxid.as_str()), - ), - ( - "Well-known support role", - self.well_known - .support_role - .as_ref() - .map_or("", |role| role.as_str()), - ), - ( - "Well-known support page/URL", - self.well_known - .support_page - .as_ref() - .map_or("", |url| url.as_str()), - ), - ("Enable the tokio-console", &self.tokio_console.to_string()), - ]; + writeln!(f, "Active config values:\n\n").expect("wrote line to formatter stream"); + let mut line = |key: &str, val: &str| { + writeln!(f, "{key}: {val}").expect("wrote line to formatter stream"); + }; - let mut msg: String = "Active config values:\n\n".to_owned(); + line("Server name", self.server_name.host()); + line("Database backend", &self.database_backend); + line("Database path", &self.database_path.to_string_lossy()); + line( + "Database backup path", + self.database_backup_path + .as_ref() + .map_or("", |path| path.to_str().unwrap_or("")), + ); + line("Database backups to keep", &self.database_backups_to_keep.to_string()); + line("Database cache capacity (MB)", &self.db_cache_capacity_mb.to_string()); + line("Cache capacity modifier", &self.conduit_cache_capacity_modifier.to_string()); + line("PDU cache capacity", &self.pdu_cache_capacity.to_string()); + line("Auth chain cache capacity", &self.auth_chain_cache_capacity.to_string()); + line("Short eventid cache capacity", &self.shorteventid_cache_capacity.to_string()); + line("Eventid short cache capacity", &self.eventidshort_cache_capacity.to_string()); + line("Short statekey cache capacity", &self.shortstatekey_cache_capacity.to_string()); + line("Statekey short cache capacity", &self.statekeyshort_cache_capacity.to_string()); + line( + "Server visibility cache capacity", + &self.server_visibility_cache_capacity.to_string(), + ); + line( + "User visibility cache capacity", + &self.user_visibility_cache_capacity.to_string(), + ); + line("Stateinfo cache capacity", &self.stateinfo_cache_capacity.to_string()); + line( + "Roomid space hierarchy cache capacity", + &self.roomid_spacehierarchy_cache_capacity.to_string(), + ); + line("DNS cache entry limit", &self.dns_cache_entries.to_string()); + line("DNS minimum TTL", &self.dns_min_ttl.to_string()); + line("DNS minimum NXDOMAIN TTL", &self.dns_min_ttl_nxdomain.to_string()); + line("DNS attempts", &self.dns_attempts.to_string()); + line("DNS timeout", &self.dns_timeout.to_string()); + line("DNS fallback to TCP", &self.dns_tcp_fallback.to_string()); + line("DNS query over TCP only", &self.query_over_tcp_only.to_string()); + line("Query all nameservers", &self.query_all_nameservers.to_string()); + line("Maximum request size (bytes)", &self.max_request_size.to_string()); + line("Sender retry backoff limit", &self.sender_retry_backoff_limit.to_string()); + line("Request connect timeout", &self.request_conn_timeout.to_string()); + line("Request timeout", &self.request_timeout.to_string()); + line("Request total timeout", &self.request_total_timeout.to_string()); + line("Idle connections per host", &self.request_idle_per_host.to_string()); + line("Request pool idle timeout", &self.request_idle_timeout.to_string()); + line("Well_known connect timeout", &self.well_known_conn_timeout.to_string()); + line("Well_known timeout", &self.well_known_timeout.to_string()); + line("Federation timeout", &self.federation_timeout.to_string()); + line("Federation pool idle per host", &self.federation_idle_per_host.to_string()); + line("Federation pool idle timeout", &self.federation_idle_timeout.to_string()); + line("Sender timeout", &self.sender_timeout.to_string()); + line("Sender pool idle timeout", &self.sender_idle_timeout.to_string()); + line("Appservice timeout", &self.appservice_timeout.to_string()); + line("Appservice pool idle timeout", &self.appservice_idle_timeout.to_string()); + line("Pusher pool idle timeout", &self.pusher_idle_timeout.to_string()); + line("Allow registration", &self.allow_registration.to_string()); + line( + "Registration token", + if self.registration_token.is_some() { + "set" + } else { + "not set (open registration!)" + }, + ); + line( + "Allow guest registration (inherently false if allow registration is false)", + &self.allow_guest_registration.to_string(), + ); + line( + "Log guest registrations in admin room", + &self.log_guest_registrations.to_string(), + ); + line( + "Allow guests to auto join rooms", + &self.allow_guests_auto_join_rooms.to_string(), + ); + line("New user display name suffix", &self.new_user_displayname_suffix); + line("Allow encryption", &self.allow_encryption.to_string()); + line("Allow federation", &self.allow_federation.to_string()); + line( + "Allow incoming federated presence requests (updates)", + &self.allow_incoming_presence.to_string(), + ); + line( + "Allow outgoing federated presence requests (updates)", + &self.allow_outgoing_presence.to_string(), + ); + line( + "Allow local presence requests (updates)", + &self.allow_local_presence.to_string(), + ); + line( + "Allow incoming remote read receipts", + &self.allow_incoming_read_receipts.to_string(), + ); + line( + "Allow outgoing remote read receipts", + &self.allow_outgoing_read_receipts.to_string(), + ); + line( + "Block non-admin room invites (local and remote, admins can still send and receive invites)", + &self.block_non_admin_invites.to_string(), + ); + line("Enable admin escape commands", &self.admin_escape_commands.to_string()); + line("Allow outgoing federated typing", &self.allow_outgoing_typing.to_string()); + line("Allow incoming federated typing", &self.allow_incoming_typing.to_string()); + line( + "Incoming federated typing timeout", + &self.typing_federation_timeout_s.to_string(), + ); + line("Client typing timeout minimum", &self.typing_client_timeout_min_s.to_string()); + line("Client typing timeout maxmimum", &self.typing_client_timeout_max_s.to_string()); + line("Allow device name federation", &self.allow_device_name_federation.to_string()); + line( + "Allow incoming profile lookup federation requests", + &self.allow_profile_lookup_federation_requests.to_string(), + ); + line( + "Auto deactivate banned room join attempts", + &self.auto_deactivate_banned_room_attempts.to_string(), + ); + line("Notification push path", &self.notification_push_path); + line("Allow room creation", &self.allow_room_creation.to_string()); + line( + "Allow public room directory over federation", + &self.allow_public_room_directory_over_federation.to_string(), + ); + line( + "Allow public room directory without authentication", + &self.allow_public_room_directory_without_auth.to_string(), + ); + line( + "Lockdown public room directory (only allow admins to publish)", + &self.lockdown_public_room_directory.to_string(), + ); + line( + "JWT secret", + match self.jwt_secret { + Some(_) => "set", + None => "not set", + }, + ); + line( + "Trusted key servers", + &self + .trusted_servers + .iter() + .map(|server| server.host()) + .join(", "), + ); + line( + "Query Trusted Key Servers First", + &self.query_trusted_key_servers_first.to_string(), + ); + line("OpenID Token TTL", &self.openid_token_ttl.to_string()); + line( + "TURN username", + if self.turn_username.is_empty() { + "not set" + } else { + &self.turn_username + }, + ); + line("TURN password", { + if self.turn_password.is_empty() { + "not set" + } else { + "set" + } + }); + line("TURN secret", { + if self.turn_secret.is_empty() { + "not set" + } else { + "set" + } + }); + line("Turn TTL", &self.turn_ttl.to_string()); + line("Turn URIs", { + let mut lst = vec![]; + for item in self.turn_uris.iter().cloned().enumerate() { + let (_, uri): (usize, String) = item; + lst.push(uri); + } + &lst.join(", ") + }); + line("Auto Join Rooms", { + let mut lst = vec![]; + for room in &self.auto_join_rooms { + lst.push(room); + } + &lst.into_iter().join(", ") + }); + #[cfg(feature = "zstd_compression")] + line("Zstd HTTP Compression", &self.zstd_compression.to_string()); + #[cfg(feature = "gzip_compression")] + line("Gzip HTTP Compression", &self.gzip_compression.to_string()); + #[cfg(feature = "brotli_compression")] + line("Brotli HTTP Compression", &self.brotli_compression.to_string()); + line("RocksDB database LOG level", &self.rocksdb_log_level); + line("RocksDB database LOG to stderr", &self.rocksdb_log_stderr.to_string()); + line("RocksDB database LOG time-to-roll", &self.rocksdb_log_time_to_roll.to_string()); + line("RocksDB Max LOG Files", &self.rocksdb_max_log_files.to_string()); + line( + "RocksDB database max LOG file size", + &self.rocksdb_max_log_file_size.to_string(), + ); + line( + "RocksDB database optimize for spinning disks", + &self.rocksdb_optimize_for_spinning_disks.to_string(), + ); + line("RocksDB Direct-IO", &self.rocksdb_direct_io.to_string()); + line("RocksDB Parallelism Threads", &self.rocksdb_parallelism_threads.to_string()); + line("RocksDB Compression Algorithm", &self.rocksdb_compression_algo); + line("RocksDB Compression Level", &self.rocksdb_compression_level.to_string()); + line( + "RocksDB Bottommost Compression Level", + &self.rocksdb_bottommost_compression_level.to_string(), + ); + line( + "RocksDB Bottommost Level Compression", + &self.rocksdb_bottommost_compression.to_string(), + ); + line("RocksDB Recovery Mode", &self.rocksdb_recovery_mode.to_string()); + line("RocksDB Repair Mode", &self.rocksdb_repair.to_string()); + line("RocksDB Read-only Mode", &self.rocksdb_read_only.to_string()); + line( + "RocksDB Compaction Idle Priority", + &self.rocksdb_compaction_prio_idle.to_string(), + ); + line( + "RocksDB Compaction Idle IOPriority", + &self.rocksdb_compaction_ioprio_idle.to_string(), + ); + line("Media integrity checks on startup", &self.media_startup_check.to_string()); + line("Media compatibility filesystem links", &self.media_compat_file_link.to_string()); + line("Prevent Media Downloads From", { + let mut lst = vec![]; + for domain in &self.prevent_media_downloads_from { + lst.push(domain.host()); + } + &lst.join(", ") + }); + line("Forbidden Remote Server Names (\"Global\" ACLs)", { + let mut lst = vec![]; + for domain in &self.forbidden_remote_server_names { + lst.push(domain.host()); + } + &lst.join(", ") + }); + line("Forbidden Remote Room Directory Server Names", { + let mut lst = vec![]; + for domain in &self.forbidden_remote_room_directory_server_names { + lst.push(domain.host()); + } + &lst.join(", ") + }); + line("Outbound Request IP Range Denylist", { + let mut lst = vec![]; + for item in self.ip_range_denylist.iter().cloned().enumerate() { + let (_, ip): (usize, String) = item; + lst.push(ip); + } + &lst.join(", ") + }); + line("Forbidden usernames", { + &self.forbidden_usernames.patterns().iter().join(", ") + }); + line("Forbidden room aliases", { + &self.forbidden_alias_names.patterns().iter().join(", ") + }); + line( + "URL preview domain contains allowlist", + &self.url_preview_domain_contains_allowlist.join(", "), + ); + line( + "URL preview domain explicit allowlist", + &self.url_preview_domain_explicit_allowlist.join(", "), + ); + line( + "URL preview domain explicit denylist", + &self.url_preview_domain_explicit_denylist.join(", "), + ); + line( + "URL preview URL contains allowlist", + &self.url_preview_url_contains_allowlist.join(", "), + ); + line("URL preview maximum spider size", &self.url_preview_max_spider_size.to_string()); + line("URL preview check root domain", &self.url_preview_check_root_domain.to_string()); + line( + "Allow check for updates / announcements check", + &self.allow_check_for_updates.to_string(), + ); + line("Enable netburst on startup", &self.startup_netburst.to_string()); + #[cfg(feature = "sentry_telemetry")] + line("Sentry.io reporting and tracing", &self.sentry.to_string()); + #[cfg(feature = "sentry_telemetry")] + line("Sentry.io send server_name in logs", &self.sentry_send_server_name.to_string()); + #[cfg(feature = "sentry_telemetry")] + line("Sentry.io tracing sample rate", &self.sentry_traces_sample_rate.to_string()); + line("Sentry.io attach stacktrace", &self.sentry_attach_stacktrace.to_string()); + line("Sentry.io send panics", &self.sentry_send_panic.to_string()); + line("Sentry.io send errors", &self.sentry_send_error.to_string()); + line( + "Well-known server name", + self.well_known + .server + .as_ref() + .map_or("", |server| server.as_str()), + ); + line( + "Well-known client URL", + self.well_known + .client + .as_ref() + .map_or("", |url| url.as_str()), + ); + line( + "Well-known support email", + self.well_known + .support_email + .as_ref() + .map_or("", |str| str.as_ref()), + ); + line( + "Well-known support Matrix ID", + self.well_known + .support_mxid + .as_ref() + .map_or("", |mxid| mxid.as_str()), + ); + line( + "Well-known support role", + self.well_known + .support_role + .as_ref() + .map_or("", |role| role.as_str()), + ); + line( + "Well-known support page/URL", + self.well_known + .support_page + .as_ref() + .map_or("", |url| url.as_str()), + ); + line("Enable the tokio-console", &self.tokio_console.to_string()); - for line in lines.into_iter().enumerate() { - writeln!(msg, "{}: {}", line.1 .0, line.1 .1).expect("should be able to write to string buffer"); - } - - write!(f, "{msg}") + Ok(()) } }