for field in &fields.named {
//dbg!(field);
let fname = &field.ident.as_ref().unwrap();
+ let fname_string = fname.to_string();
+ let fname_lit = Literal::string( &fname_string );
let ty = &field.ty;
let fname_span = fname.span();
let skl = RefCell::new(None);
#fname: <#ty as ResolveGlobal>::resolve
(l.iter().map(|e| &e.#fname)),
));
+ inspects.push(quote!{
+ #fname_lit => &self.#fname,
+ });
continue;
}
method = attr.path.to_token_stream();
*skl.borrow_mut() = Some(get_path(tskl));
}
}
- let fname_string = fname.to_string();
- let fname_lit = Literal::string( &fname_string );
let skl = skl.into_inner()
.expect(&format!("SKL not specified! (field {})!", fname));
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)]
pub fn from(l: &[#top_ident]) -> #global { #global {
#( #global_assignments )*
} }
+
+ pub fn inspect_key(&self, field: &'_ str)
+ -> Option<&dyn InspectableConfigValue> {
+ Some(match field {
+ #( #inspects )*
+ _ => return None,
+ })
+ }
}
};
/// Daemonise
#[structopt(long)]
daemon: bool,
+
+ /// Print a config item, do not actually run
+ #[structopt(long)]
+ print_config: Option<String>,
}
pub const METADATA_MAX_LEN: usize = MAX_OVERHEAD;
fn main() {
let opts = Opts::from_args();
- let daemon = if opts.daemon {
+ let daemon = if opts.daemon && opts.print_config.is_none() {
Some(Daemoniser::phase1())
} else {
None
{
let global_config = config::InstanceConfigGlobal::from(&ics);
+ if let Some(key) = opts.print_config.as_ref() {
+ if let Some(inspectable) = global_config.inspect_key(key) {
+ println!("{}", DisplayInspectable(inspectable));
+ process::exit(0);
+ } else {
+ throw!(anyhow!("unknown config key {:?}", key));
+ }
+ }
+
let ipif = Ipif::start(&global_config.ipif, None)?;
let ics = ics.into_iter().map(Arc::new).collect_vec();
/// 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 {
};
}
+pub struct DisplayInspectable<'i>(pub &'i dyn InspectableConfigValue);
+impl<'i> Display for DisplayInspectable<'i> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ InspectableConfigValue::fmt(self.0, f)
+ }
+}
+
impl_inspectable_config_value!{ String as Display }
impl_inspectable_config_value!{ u16 as Display }
impl_inspectable_config_value!{ u32 as Display }
pub use eyre::Error as AE;
pub use crate::config::{self, InspectableConfigValue, InstanceConfig};
-pub use crate::config::u32Ext as _;
+pub use crate::config::{DisplayInspectable, u32Ext as _};
pub use crate::impl_inspectable_config_value;
pub use crate::ini;
pub use crate::ipif::Ipif;