Skip to content
This repository was archived by the owner on Sep 10, 2024. It is now read-only.

Commit 8e7bb26

Browse files
committed
Simplify ConfigurationSection trait & skip default values when serializing
This removes the `test` and `generate` methods from the `ConfigurationSection` trait, as they did not really had a reason to exist in the trait itself.
1 parent fc7489c commit 8e7bb26

18 files changed

+306
-404
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/config/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ workspace = true
1414
[dependencies]
1515
tokio = { version = "1.36.0", features = ["fs", "rt"] }
1616
tracing.workspace = true
17-
async-trait.workspace = true
1817

1918
thiserror.workspace = true
2019
anyhow.workspace = true

crates/config/src/sections/branding.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use async_trait::async_trait;
16-
use rand::Rng;
1715
use schemars::JsonSchema;
1816
use serde::{Deserialize, Serialize};
1917
use url::Url;
@@ -24,38 +22,42 @@ use crate::ConfigurationSection;
2422
#[derive(Clone, Debug, Deserialize, JsonSchema, Serialize, Default)]
2523
pub struct BrandingConfig {
2624
/// A human-readable name. Defaults to the server's address.
25+
#[serde(skip_serializing_if = "Option::is_none")]
2726
pub service_name: Option<String>,
2827

2928
/// Link to a privacy policy, displayed in the footer of web pages and
3029
/// emails. It is also advertised to clients through the `op_policy_uri`
3130
/// OIDC provider metadata.
31+
#[serde(skip_serializing_if = "Option::is_none")]
3232
pub policy_uri: Option<Url>,
3333

3434
/// Link to a terms of service document, displayed in the footer of web
3535
/// pages and emails. It is also advertised to clients through the
3636
/// `op_tos_uri` OIDC provider metadata.
37+
#[serde(skip_serializing_if = "Option::is_none")]
3738
pub tos_uri: Option<Url>,
3839

3940
/// Legal imprint, displayed in the footer in the footer of web pages and
4041
/// emails.
42+
#[serde(skip_serializing_if = "Option::is_none")]
4143
pub imprint: Option<String>,
4244

4345
/// Logo displayed in some web pages.
46+
#[serde(skip_serializing_if = "Option::is_none")]
4447
pub logo_uri: Option<Url>,
4548
}
4649

47-
#[async_trait]
48-
impl ConfigurationSection for BrandingConfig {
49-
const PATH: Option<&'static str> = Some("branding");
50-
51-
async fn generate<R>(_rng: R) -> anyhow::Result<Self>
52-
where
53-
R: Rng + Send,
54-
{
55-
Ok(Self::default())
50+
impl BrandingConfig {
51+
/// Returns true if the configuration is the default one
52+
pub(crate) fn is_default(&self) -> bool {
53+
self.service_name.is_none()
54+
&& self.policy_uri.is_none()
55+
&& self.tos_uri.is_none()
56+
&& self.imprint.is_none()
57+
&& self.logo_uri.is_none()
5658
}
59+
}
5760

58-
fn test() -> Self {
59-
Self::default()
60-
}
61+
impl ConfigurationSection for BrandingConfig {
62+
const PATH: Option<&'static str> = Some("branding");
6163
}

crates/config/src/sections/clients.rs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@
1414

1515
use std::ops::Deref;
1616

17-
use async_trait::async_trait;
1817
use figment::Figment;
1918
use mas_iana::oauth::OAuthClientAuthenticationMethod;
2019
use mas_jose::jwk::PublicJsonWebKeySet;
21-
use rand::Rng;
2220
use schemars::JsonSchema;
2321
use serde::{de::Error, Deserialize, Serialize};
2422
use ulid::Ulid;
@@ -211,6 +209,13 @@ impl ClientConfig {
211209
#[serde(transparent)]
212210
pub struct ClientsConfig(#[schemars(with = "Vec::<ClientConfig>")] Vec<ClientConfig>);
213211

212+
impl ClientsConfig {
213+
/// Returns true if all fields are at their default values
214+
pub(crate) fn is_default(&self) -> bool {
215+
self.0.is_empty()
216+
}
217+
}
218+
214219
impl Deref for ClientsConfig {
215220
type Target = Vec<ClientConfig>;
216221

@@ -228,17 +233,9 @@ impl IntoIterator for ClientsConfig {
228233
}
229234
}
230235

231-
#[async_trait]
232236
impl ConfigurationSection for ClientsConfig {
233237
const PATH: Option<&'static str> = Some("clients");
234238

235-
async fn generate<R>(_rng: R) -> anyhow::Result<Self>
236-
where
237-
R: Rng + Send,
238-
{
239-
Ok(Self::default())
240-
}
241-
242239
fn validate(&self, figment: &Figment) -> Result<(), figment::error::Error> {
243240
for (index, client) in self.0.iter().enumerate() {
244241
client.validate().map_err(|mut err| {
@@ -253,10 +250,6 @@ impl ConfigurationSection for ClientsConfig {
253250

254251
Ok(())
255252
}
256-
257-
fn test() -> Self {
258-
Self::default()
259-
}
260253
}
261254

262255
#[cfg(test)]

crates/config/src/sections/database.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414

1515
use std::{num::NonZeroU32, time::Duration};
1616

17-
use async_trait::async_trait;
1817
use camino::Utf8PathBuf;
19-
use rand::Rng;
2018
use schemars::JsonSchema;
2119
use serde::{Deserialize, Serialize};
2220
use serde_with::serde_as;
@@ -150,17 +148,9 @@ pub struct DatabaseConfig {
150148
pub max_lifetime: Option<Duration>,
151149
}
152150

153-
#[async_trait]
154151
impl ConfigurationSection for DatabaseConfig {
155152
const PATH: Option<&'static str> = Some("database");
156153

157-
async fn generate<R>(_rng: R) -> anyhow::Result<Self>
158-
where
159-
R: Rng + Send,
160-
{
161-
Ok(Self::default())
162-
}
163-
164154
fn validate(&self, figment: &figment::Figment) -> Result<(), figment::error::Error> {
165155
let metadata = figment.find_metadata(Self::PATH.unwrap());
166156

@@ -185,10 +175,6 @@ impl ConfigurationSection for DatabaseConfig {
185175

186176
Ok(())
187177
}
188-
189-
fn test() -> Self {
190-
Self::default()
191-
}
192178
}
193179

194180
#[cfg(test)]

crates/config/src/sections/email.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
use std::num::NonZeroU16;
1818

19-
use async_trait::async_trait;
20-
use rand::Rng;
2119
use schemars::JsonSchema;
2220
use serde::{de::Error, Deserialize, Serialize};
2321

@@ -181,17 +179,9 @@ impl Default for EmailConfig {
181179
}
182180
}
183181

184-
#[async_trait]
185182
impl ConfigurationSection for EmailConfig {
186183
const PATH: Option<&'static str> = Some("email");
187184

188-
async fn generate<R>(_rng: R) -> anyhow::Result<Self>
189-
where
190-
R: Rng + Send,
191-
{
192-
Ok(Self::default())
193-
}
194-
195185
fn validate(&self, figment: &figment::Figment) -> Result<(), figment::error::Error> {
196186
let metadata = figment.find_metadata(Self::PATH.unwrap());
197187

@@ -283,8 +273,4 @@ impl ConfigurationSection for EmailConfig {
283273

284274
Ok(())
285275
}
286-
287-
fn test() -> Self {
288-
Self::default()
289-
}
290276
}

crates/config/src/sections/experimental.rs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use async_trait::async_trait;
1615
use chrono::Duration;
17-
use rand::Rng;
1816
use schemars::JsonSchema;
1917
use serde::{Deserialize, Serialize};
2018
use serde_with::serde_as;
@@ -25,6 +23,10 @@ fn default_token_ttl() -> Duration {
2523
Duration::microseconds(5 * 60 * 1000 * 1000)
2624
}
2725

26+
fn is_default_token_ttl(value: &Duration) -> bool {
27+
*value == default_token_ttl()
28+
}
29+
2830
/// Configuration sections for experimental options
2931
///
3032
/// Do not change these options unless you know what you are doing.
@@ -33,14 +35,20 @@ fn default_token_ttl() -> Duration {
3335
pub struct ExperimentalConfig {
3436
/// Time-to-live of access tokens in seconds. Defaults to 5 minutes.
3537
#[schemars(with = "u64", range(min = 60, max = 86400))]
36-
#[serde(default = "default_token_ttl")]
38+
#[serde(
39+
default = "default_token_ttl",
40+
skip_serializing_if = "is_default_token_ttl"
41+
)]
3742
#[serde_as(as = "serde_with::DurationSeconds<i64>")]
3843
pub access_token_ttl: Duration,
3944

4045
/// Time-to-live of compatibility access tokens in seconds. Defaults to 5
4146
/// minutes.
4247
#[schemars(with = "u64", range(min = 60, max = 86400))]
43-
#[serde(default = "default_token_ttl")]
48+
#[serde(
49+
default = "default_token_ttl",
50+
skip_serializing_if = "is_default_token_ttl"
51+
)]
4452
#[serde_as(as = "serde_with::DurationSeconds<i64>")]
4553
pub compat_token_ttl: Duration,
4654
}
@@ -54,18 +62,12 @@ impl Default for ExperimentalConfig {
5462
}
5563
}
5664

57-
#[async_trait]
58-
impl ConfigurationSection for ExperimentalConfig {
59-
const PATH: Option<&'static str> = Some("experimental");
60-
61-
async fn generate<R>(_rng: R) -> anyhow::Result<Self>
62-
where
63-
R: Rng + Send,
64-
{
65-
Ok(Self::default())
65+
impl ExperimentalConfig {
66+
pub(crate) fn is_default(&self) -> bool {
67+
is_default_token_ttl(&self.access_token_ttl) && is_default_token_ttl(&self.compat_token_ttl)
6668
}
69+
}
6770

68-
fn test() -> Self {
69-
Self::default()
70-
}
71+
impl ConfigurationSection for ExperimentalConfig {
72+
const PATH: Option<&'static str> = Some("experimental");
7173
}

crates/config/src/sections/http.rs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@
1717
use std::{borrow::Cow, io::Cursor};
1818

1919
use anyhow::bail;
20-
use async_trait::async_trait;
2120
use camino::Utf8PathBuf;
2221
use ipnetwork::IpNetwork;
2322
use mas_keystore::PrivateKey;
24-
use rand::Rng;
2523
use rustls_pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
2624
use schemars::JsonSchema;
2725
use serde::{Deserialize, Serialize};
@@ -61,6 +59,10 @@ fn http_listener_assets_path_default() -> Utf8PathBuf {
6159
"./share/assets/".into()
6260
}
6361

62+
fn is_default_http_listener_assets_path(value: &Utf8PathBuf) -> bool {
63+
*value == http_listener_assets_path_default()
64+
}
65+
6466
fn default_trusted_proxies() -> Vec<IpNetwork> {
6567
vec![
6668
IpNetwork::new([192, 128, 0, 0].into(), 16).unwrap(),
@@ -302,7 +304,10 @@ pub enum Resource {
302304
/// Static files
303305
Assets {
304306
/// Path to the directory to serve.
305-
#[serde(default = "http_listener_assets_path_default")]
307+
#[serde(
308+
default = "http_listener_assets_path_default",
309+
skip_serializing_if = "is_default_http_listener_assets_path"
310+
)]
306311
#[schemars(with = "String")]
307312
path: Utf8PathBuf,
308313
},
@@ -356,6 +361,7 @@ pub struct HttpConfig {
356361
pub public_base: Url,
357362

358363
/// OIDC issuer URL. Defaults to `public_base` if not set.
364+
#[serde(skip_serializing_if = "Option::is_none")]
359365
pub issuer: Option<Url>,
360366
}
361367

@@ -401,17 +407,9 @@ impl Default for HttpConfig {
401407
}
402408
}
403409

404-
#[async_trait]
405410
impl ConfigurationSection for HttpConfig {
406411
const PATH: Option<&'static str> = Some("http");
407412

408-
async fn generate<R>(_rng: R) -> anyhow::Result<Self>
409-
where
410-
R: Rng + Send,
411-
{
412-
Ok(Self::default())
413-
}
414-
415413
fn validate(&self, figment: &figment::Figment) -> Result<(), figment::Error> {
416414
for (index, listener) in self.listeners.iter().enumerate() {
417415
let annotate = |mut error: figment::Error| {
@@ -473,8 +471,4 @@ impl ConfigurationSection for HttpConfig {
473471

474472
Ok(())
475473
}
476-
477-
fn test() -> Self {
478-
Self::default()
479-
}
480474
}

crates/config/src/sections/matrix.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use async_trait::async_trait;
1615
use rand::{
1716
distributions::{Alphanumeric, DistString},
1817
Rng,
@@ -48,22 +47,23 @@ pub struct MatrixConfig {
4847
pub endpoint: Url,
4948
}
5049

51-
#[async_trait]
5250
impl ConfigurationSection for MatrixConfig {
5351
const PATH: Option<&'static str> = Some("matrix");
52+
}
5453

55-
async fn generate<R>(mut rng: R) -> anyhow::Result<Self>
54+
impl MatrixConfig {
55+
pub(crate) fn generate<R>(mut rng: R) -> Self
5656
where
5757
R: Rng + Send,
5858
{
59-
Ok(Self {
59+
Self {
6060
homeserver: default_homeserver(),
6161
secret: Alphanumeric.sample_string(&mut rng, 32),
6262
endpoint: default_endpoint(),
63-
})
63+
}
6464
}
6565

66-
fn test() -> Self {
66+
pub(crate) fn test() -> Self {
6767
Self {
6868
homeserver: default_homeserver(),
6969
secret: "test".to_owned(),

0 commit comments

Comments
 (0)