let mut output = vec![];
let mut global_fields = vec![];
let mut global_assignments = vec![];
+ let mut inspects = vec![];
for field in &fields.named {
//dbg!(field);
let fname = &field.ident.as_ref().unwrap();
output.push(quote!{
#fname: rctx. #method ( #fname_lit, #skl )?,
});
+ inspects.push(quote!{
+ #fname_lit => &self.#fname,
+ });
//eprintln!("{:?} method={:?} skl={:?}", field.ident, method, skl);
}
//dbg!(&output);
#( #output )*
})
}
+
+ pub fn inspect_key(&self, field: &'_ str)
+ -> Option<&dyn InspectableConfigValue> {
+ Some(match field {
+ #( #inspects )*
+ _ => return None,
+ })
+ }
}
#[derive(Debug)]
/// Additional config files or dirs, which can override the others
#[structopt(long, multiple=true, number_of_values=1)]
pub extra_config: Vec<PathBuf>,
+
+ /// Print configuration rather than running
+ #[structopt(long)]
+ pub print_config: bool,
+}
+
+pub trait InspectableConfigValue {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result;
+}
+#[macro_export]
+macro_rules! impl_inspectable_config_value {
+ { $t:ty as $trait:path } => {
+ impl InspectableConfigValue for $t {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ <Self as $trait>::fmt(self, f)
+ }
+ }
+ };
+
+ { Vec<$t:ty> } => {
+ impl InspectableConfigValue for Vec<$t> {
+ #[throws(fmt::Error)]
+ fn fmt(&self, f: &mut fmt::Formatter) {
+ let mut first = Some(());
+ for v in self.iter() {
+ if first.take().is_none() { write!(f, " ")?; }
+ InspectableConfigValue::fmt(v, f)?;
+ }
+ }
+ }
+ };
+}
+
+impl_inspectable_config_value!{ String as Display }
+impl_inspectable_config_value!{ u16 as Display }
+impl_inspectable_config_value!{ u32 as Display }
+impl_inspectable_config_value!{ hyper::Uri as Display }
+
+impl_inspectable_config_value!{ IpAddr as Display }
+impl_inspectable_config_value!{ ipnet::IpNet as Display }
+impl_inspectable_config_value!{ Vec<IpAddr> }
+impl_inspectable_config_value!{ Vec<ipnet::IpNet> }
+
+impl InspectableConfigValue for Duration {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let v = self.as_secs_f64();
+ Display::fmt(&v, f)
+ }
}
#[ext(pub)]
#[throws(fmt::Error)]
fn fmt(&self, f: &mut fmt::Formatter) { write!(f, "Secret(***)")? }
}
+impl_inspectable_config_value!{ Secret as Debug }
#[derive(Debug,Clone,Hash,Eq,PartialEq)]
pub enum SectionName {
pub use eyre::WrapErr;
pub use eyre::Error as AE;
-pub use crate::config::{self, InstanceConfig, u32Ext as _};
+pub use crate::config::{self, InspectableConfigValue, InstanceConfig};
+pub use crate::config::u32Ext as _;
+pub use crate::impl_inspectable_config_value;
pub use crate::ini;
pub use crate::ipif::Ipif;
pub use crate::multipart::{self, PartName, MetadataFieldIterator};