Skip to content

Commit

Permalink
feat: Improve settings macros to handle default (#13)
Browse files Browse the repository at this point in the history
Signed-off-by: Jeremy HERGAULT <[email protected]>
  • Loading branch information
reneca authored Oct 16, 2024
1 parent 5a07249 commit 2095efe
Show file tree
Hide file tree
Showing 8 changed files with 286 additions and 68 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ include = [

[workspace.dependencies]
prosa-utils = { version = "0.1.1", path = "prosa_utils" }
prosa-macros = { version = "0.1.1", path = "prosa_macros" }
prosa-macros = { version = "0.1.2", path = "prosa_macros" }
thiserror = "1"
aquamarine = "0.5"
bytes = "1"
Expand Down
47 changes: 45 additions & 2 deletions prosa/src/core/proc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,18 @@ pub use prosa_macros::proc_settings;
/// use prosa::core::proc::proc_settings;
///
/// #[proc_settings]
/// #[derive(Default, Debug)]
/// #[derive(Debug)]
/// pub struct MySettings {
/// my_param: Option<String>,
/// my_param: String,
/// }
///
/// #[proc_settings]
/// impl Default for MySettings {
/// fn default() -> Self {
/// MySettings {
/// my_param: "default param".into(),
/// }
/// }
/// }
/// ```
pub trait ProcSettings {
Expand Down Expand Up @@ -432,3 +441,37 @@ where
.unwrap();
}
}

#[cfg(test)]
mod tests {
use super::*;
use prosa_macros::proc_settings;
use serde::Serialize;

extern crate self as prosa;

#[test]
fn test_proc_settings() {
#[proc_settings]
#[derive(Debug, Serialize)]
struct TestProcSettings {
name: String,
}

#[proc_settings]
impl Default for TestProcSettings {
fn default() -> Self {
let _test_settings = TestProcSettings {
name: "test".into(),
};

TestProcSettings {
name: "test".into(),
}
}
}

let test_proc_settings = TestProcSettings::default();
assert_eq!("test", test_proc_settings.name);
}
}
86 changes: 77 additions & 9 deletions prosa/src/core/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,43 @@ pub use prosa_macros::settings;
/// Need to be implemented by the top settings layer of a ProSA
///
/// ```
/// use prosa::core::settings::{settings, Settings};
/// use serde::Serialize;
///
/// // My ProSA setting structure
/// #[settings]
/// #[derive(Debug, Serialize)]
/// struct MySettings {
/// test_val: String
/// }
///
/// #[settings]
/// impl Default for MySettings {
/// fn default() -> Self {
/// MySettings {
/// test_val: "test".into(),
/// }
/// }
/// }
///
/// assert_eq!("test", MySettings::default().test_val);
/// ```
///
/// is equivalent to
///
/// ```
/// use prosa::core::settings::Settings;
/// use prosa_utils::config::observability::Observability;
/// use prosa::core::settings::settings;
/// use serde::Serialize;
///
/// /// My ProSA setting structure
/// #[derive(Serialize)]
/// struct MySettings {
/// #[derive(Debug, Serialize)]
/// struct MySameSettings {
/// test_val: String,
/// name: Option<String>,
/// observability: Observability,
/// }
///
/// impl Settings for MySettings {
/// impl Settings for MySameSettings {
/// fn get_prosa_name(&self) -> String {
/// if let Some(name) = &self.name {
/// name.clone()
Expand All @@ -47,10 +71,17 @@ pub use prosa_macros::settings;
/// }
/// }
///
/// // Equivalent to
/// #[settings]
/// #[derive(Serialize)]
/// struct MySameSettings {}
/// impl Default for MySameSettings {
/// fn default() -> Self {
/// MySameSettings {
/// test_val: "test".into(),
/// name: None,
/// observability: Observability::default(),
/// }
/// }
/// }
///
/// assert_eq!("test", MySameSettings::default().test_val);
/// ```
pub trait Settings: Serialize {
/// Getter of the ProSA running name
Expand Down Expand Up @@ -80,3 +111,40 @@ pub trait Settings: Serialize {
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use prosa_macros::settings;

extern crate self as prosa;

#[test]
fn test_settings() {
#[settings]
#[derive(Debug, Serialize)]
struct TestSettings {
name_test: String,
name_test2: String,
}

#[settings]
impl Default for TestSettings {
fn default() -> Self {
let _test_settings = TestSettings {
name_test: "test".into(),
name_test2: "test2".into(),
};

TestSettings {
name_test: "test".into(),
name_test2: "test2".into(),
}
}
}

let test_settings = TestSettings::default();
assert_eq!("test", test_settings.name_test);
assert_eq!("test2", test_settings.name_test2);
}
}
2 changes: 1 addition & 1 deletion prosa_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "prosa-macros"
version = "0.1.1"
version = "0.1.2"
authors.workspace = true
description = "ProSA macros"
homepage.workspace = true
Expand Down
32 changes: 17 additions & 15 deletions prosa_macros/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,22 +171,24 @@ fn add_struct_impl(mut item_impl: syn::ItemImpl) -> syn::parse::Result<syn::Item

/// Implementation of the procedural prosa_io macro
pub(crate) fn io_impl(item: syn::Item) -> syn::parse::Result<proc_macro2::TokenStream> {
if let syn::Item::Struct(item_struct) = item {
let struct_output = generate_struct(item_struct)?;
let struct_impl = generate_struct_impl(&struct_output)?;
Ok(quote! {
#struct_output
#struct_impl
})
} else if let syn::Item::Impl(item_impl) = item {
let impl_output = add_struct_impl(item_impl)?;
Ok(quote! {
#impl_output
})
} else {
Err(syn::Error::new(
match item {
syn::Item::Struct(item_struct) => {
let struct_output = generate_struct(item_struct)?;
let struct_impl = generate_struct_impl(&struct_output)?;
Ok(quote! {
#struct_output
#struct_impl
})
}
syn::Item::Impl(item_impl) => {
let impl_output = add_struct_impl(item_impl)?;
Ok(quote! {
#impl_output
})
}
_ => Err(syn::Error::new(
proc_macro2::Span::call_site(),
"expected struct or impl expression",
))
)),
}
}
1 change: 1 addition & 0 deletions prosa_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//! Base library to defines procedural macros
#![warn(missing_docs)]
#![deny(unreachable_pub)]

use proc_macro::TokenStream;
use quote::quote;
Expand Down
36 changes: 19 additions & 17 deletions prosa_macros/src/proc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,24 +261,26 @@ pub(crate) fn proc_impl(
let mut proc_args: ProcParams = std::default::Default::default();
proc_args.parse_attr_args(args)?;

if let syn::Item::Struct(item_struct) = item {
let struct_output = generate_struct(item_struct, &proc_args)?;
let struct_impl_bus_param = generate_struct_impl_bus_param(&struct_output)?;
let struct_impl_config = generate_struct_impl_config(&struct_output, &proc_args)?;
Ok(quote! {
#struct_output
#struct_impl_bus_param
#struct_impl_config
})
} else if let syn::Item::Impl(item_impl) = item {
let impl_output = add_struct_impl(item_impl)?;
Ok(quote! {
#impl_output
})
} else {
Err(syn::Error::new(
match item {
syn::Item::Struct(item_struct) => {
let struct_output = generate_struct(item_struct, &proc_args)?;
let struct_impl_bus_param = generate_struct_impl_bus_param(&struct_output)?;
let struct_impl_config = generate_struct_impl_config(&struct_output, &proc_args)?;
Ok(quote! {
#struct_output
#struct_impl_bus_param
#struct_impl_config
})
}
syn::Item::Impl(item_impl) => {
let impl_output = add_struct_impl(item_impl)?;
Ok(quote! {
#impl_output
})
}
_ => Err(syn::Error::new(
proc_macro2::Span::call_site(),
"expected struct or impl expression",
))
)),
}
}
Loading

0 comments on commit 2095efe

Please sign in to comment.