Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 2 additions & 35 deletions foundations-macros/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;
use syn::{
Attribute, Expr, ExprLit, Field, Fields, Ident, Item, ItemEnum, ItemStruct, Lit, LitStr, Meta,
MetaNameValue, Path, Type, parse_macro_input, parse_quote,
MetaNameValue, Path, parse_macro_input, parse_quote,
};

const ERR_NOT_STRUCT_OR_ENUM: &str = "Settings should be either structure or enum.";
Expand Down Expand Up @@ -265,18 +265,9 @@ fn impl_settings_trait_for_field(
let mut impl_for_field = quote_spanned! { span=>
let mut key = parent_key.to_vec();
key.push(#name_str.into());
#crate_path::settings::Settings::add_docs(&self.#name, &key, docs);
};

// foundations#150: `[T; 0]` used to impl Settings for `T: !Default`, but this
// is not possible anymore. We thus can't call `Settings::add_docs` for such
// fields, but it was a noop anyway.
// TODO(lblocher): Remove this compatibility hack with the next major release
if !is_array_zst(&field.ty) {
impl_for_field.append_all(quote_spanned! { span =>
#crate_path::settings::Settings::add_docs(&self.#name, &key, docs);
});
}

if !docs.is_empty() {
impl_for_field.append_all(quote! {
docs.insert(key, &[#(#docs,)*][..]);
Expand Down Expand Up @@ -319,30 +310,6 @@ fn extract_doc_comments(attrs: &[Attribute]) -> Vec<LitStr> {
comments
}

/// Returns whether `ty` is exactly `[T; 0]` (for some T)
fn is_array_zst(ty: &Type) -> bool {
let Type::Array(array) = ty else {
return false;
};

let mut expr = &array.len;
while let Expr::Cast(cast) = expr {
expr = &cast.expr;
}

let Expr::Lit(ExprLit {
lit: Lit::Int(len_lit),
..
}) = expr
else {
return false;
};
len_lit
.base10_parse::<usize>()
.map(|len| len == 0)
.unwrap_or(false)
}

/// Returns whether `attrs` contains `serde(flatten)`.
fn is_serde_flattened(attrs: &[Attribute]) -> bool {
matches!(
Expand Down
6 changes: 3 additions & 3 deletions foundations/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ const USE_CONFIG_OPT_ID: &str = "config";
/// Additional arguments can be added via `custom_args` argument of the [`Cli::new`] function.
///
/// [`Settings`]: crate::settings::Settings
pub struct Cli<S: Settings> {
pub struct Cli<S> {
/// Parsed service settings.
pub settings: S,

/// Parsed service arguments.
pub arg_matches: ArgMatches,
}

impl<S: Settings> Cli<S> {
impl<S: Settings + Default> Cli<S> {
/// Bootstraps a new command line interface (CLI) for the service.
///
/// `custom_args` argument can be used to add extra service-specific arguments to the CLI.
Expand Down Expand Up @@ -116,7 +116,7 @@ fn get_arg_matches(
})
}

fn get_settings<S: Settings>(arg_matches: &ArgMatches) -> BootstrapResult<S> {
fn get_settings<S: Settings + Default>(arg_matches: &ArgMatches) -> BootstrapResult<S> {
if let Some(path) = arg_matches.get_one::<String>(GENERATE_CONFIG_OPT_ID) {
let settings = S::default();

Expand Down
24 changes: 16 additions & 8 deletions foundations/src/settings/basic_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::ops::Range;
use std::path::PathBuf;
use std::rc::Rc;
use std::sync::Arc;
use std::time::Duration;
use std::time::{Duration, SystemTime};

macro_rules! impl_noop {
( $( $impl_desc:tt )* ) => {
Expand All @@ -30,7 +30,8 @@ macro_rules! impl_noop {
}

impl_noop!(<T> Settings for PhantomData<T> where T: 'static);
impl_noop!(<Idx> Settings for Range<Idx> where Idx: Debug + Serialize + DeserializeOwned + Clone + Default + 'static);
impl_noop!(<T> Settings for [T; 0] where T: Debug + Clone + 'static);
impl_noop!(<Idx> Settings for Range<Idx> where Idx: Debug + Serialize + DeserializeOwned + Clone + 'static);
impl_noop!(<T> Settings for Reverse<T> where T: Settings);
impl_noop!(<T> Settings for Wrapping<T> where T: Settings);

Expand All @@ -39,7 +40,7 @@ macro_rules! impl_for_num {
( $( $Ty:ty )* ) => { $(
impl_noop!(Settings for $Ty);
impl_noop!(Settings for Saturating<$Ty>);
impl_noop!(Settings for Option<NonZero<$Ty>>);
impl_noop!(Settings for NonZero<$Ty>);
)* };
}

Expand All @@ -64,7 +65,14 @@ impl_for_non_generic! {
CString,
OsString,
Duration,
PathBuf
SystemTime,
PathBuf,
std::net::IpAddr,
std::net::Ipv4Addr,
std::net::Ipv6Addr,
std::net::SocketAddr,
std::net::SocketAddrV4,
std::net::SocketAddrV6
}

macro_rules! impl_for_ref {
Expand Down Expand Up @@ -120,10 +128,10 @@ macro_rules! impl_for_array {
}

impl_for_array! {
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32
}

impl<T: Settings> Settings for Option<T> {
Expand Down
2 changes: 1 addition & 1 deletion foundations/src/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ pub use foundations_macros::settings;
/// [`settings`] macro.
///
/// [`settings`]: crate::settings::settings
pub trait Settings: Default + Clone + Serialize + DeserializeOwned + Debug + 'static {
pub trait Settings: Clone + Serialize + DeserializeOwned + Debug + 'static {
/// Add Rust doc comments for the settings fields.
///
/// Docs for each field need to be added to the provided hashmap with the key consisting of the
Expand Down
Loading