From 7b03e09e2b94823374e9df10e7a4a4c3640e09fc Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Mon, 9 Mar 2026 13:15:21 +0000 Subject: [PATCH] generate table for defaults now all that needs to be done is setting the defaults, media, and authentication failures --- conduit-config/src/rate_limiting.rs | 44 ++++++++++++++++++++++++++-- conduit-macros/src/doc_generators.rs | 1 + xtask/src/generate_docs.rs | 29 +++++++++++++++--- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/conduit-config/src/rate_limiting.rs b/conduit-config/src/rate_limiting.rs index 20e343e5..cd562c7c 100644 --- a/conduit-config/src/rate_limiting.rs +++ b/conduit-config/src/rate_limiting.rs @@ -18,7 +18,8 @@ impl From for Config { } } -#[derive(Debug, Clone, Deserialize, Default)] +#[derive(Debug, Clone, Deserialize, Default, Copy)] +#[cfg_attr(feature = "doc-generators", derive(serde::Serialize))] #[serde(rename_all = "snake_case")] pub enum ConfigPreset { /// Default rate-limiting configuration, recommended for small private servers (i.e. single-user @@ -189,6 +190,18 @@ pub enum Restriction { Federation(FederationRestriction), } +impl From for Restriction { + fn from(value: ClientRestriction) -> Self { + Self::Client(value) + } +} + +impl From for Restriction { + fn from(value: FederationRestriction) -> Self { + Self::Federation(value) + } +} + #[cfg(feature = "doc-generators")] pub trait DocumentRestrictions: Sized { fn variant_doc_comments() -> Vec<(Self, String)>; @@ -395,6 +408,33 @@ pub enum Timeframe { PerDay(NonZeroU64), } +#[cfg(feature = "doc-generators")] +impl std::fmt::Display for Timeframe { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let value; + + let string = match self { + Self::PerSecond(v) => { + value = v; + "second" + } + Self::PerMinute(v) => { + value = v; + "minute" + } + Self::PerHour(v) => { + value = v; + "hour" + } + Self::PerDay(v) => { + value = v; + "day" + } + }; + write!(f, "{value} requests per {string}") + } +} + impl Timeframe { pub fn nano_gap(&self) -> u64 { match self { @@ -562,7 +602,7 @@ impl Config { } } - fn get_preset(preset: ConfigPreset) -> Self { + pub fn get_preset(preset: ConfigPreset) -> Self { match preset { //TODO: finish these ConfigPreset::PrivateSmall => Self { diff --git a/conduit-macros/src/doc_generators.rs b/conduit-macros/src/doc_generators.rs index c179581d..7d2ad01d 100644 --- a/conduit-macros/src/doc_generators.rs +++ b/conduit-macros/src/doc_generators.rs @@ -61,6 +61,7 @@ fn attrs_to_doc_comment(attrs: Vec) -> String { /// Produces the following function on said restriction: /// - `variant_doc_comments`, returning each variant and it's doc comment. +/// - `container_doc_comment`, returning each variant and it's doc comment. impl ToTokens for Restrictions { fn to_tokens(&self, tokens: &mut TokenStream2) { let Self { diff --git a/xtask/src/generate_docs.rs b/xtask/src/generate_docs.rs index 4e6236e6..2a816366 100644 --- a/xtask/src/generate_docs.rs +++ b/xtask/src/generate_docs.rs @@ -4,9 +4,16 @@ use std::{ }; use conduit_config::rate_limiting::{ - ClientRestriction, DocumentRestrictions, FederationRestriction, + ClientRestriction, Config, ConfigPreset, DocumentRestrictions, FederationRestriction, }; +const PRESETS: [ConfigPreset; 4] = [ + ConfigPreset::PrivateSmall, + ConfigPreset::PrivateMedium, + ConfigPreset::PublicMedium, + ConfigPreset::PublicLarge, +]; + pub fn run() { let mut markdown_text = String::new(); @@ -15,10 +22,24 @@ pub fn run() { markdown_text.push_str(&format!("{}\n", $restriction_kind::container_doc_comment())); for (restriction, comment) in $restriction_kind::variant_doc_comments() { markdown_text.push_str(&format!( - "##### `{}`\n{}\n", - restriction_to_string(&restriction), + "##### `{}`\n{}\n###### Defaults:\n| Preset | Global Timeframe | Global Burst Capacity | Target Timeframe | Target Burst Capacity |\n| --- | --- | --- | --- | --- |\n", + variant_to_string(&restriction), comment )); + + for preset in PRESETS { + let preset_config = Config::get_preset(preset); + let global = preset_config.global.get(&restriction.into()); + let target = preset_config.target.get(&restriction.into()); + markdown_text.push_str(&format!( + "| {} | {} | {} | {} | {} |\n", + variant_to_string(&preset), + global.timeframe, + global.burst_capacity, + target.timeframe, + target.burst_capacity, + )) + }; } }; } @@ -37,7 +58,7 @@ pub fn run() { file.write_all(markdown_text.as_bytes()).unwrap(); } -fn restriction_to_string(restriction: &T) -> String { +fn variant_to_string(restriction: &T) -> String { // Maybe there is a better way to convert it to snake_case without extra dependencies added // to Cargo.lock serde_json::to_string(restriction)