chiark / gitweb /
print config value
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 25 Sep 2022 18:57:23 +0000 (19:57 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 25 Sep 2022 18:57:23 +0000 (19:57 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
macros/macros.rs
server/server.rs
src/config.rs
src/prelude.rs

index 1a158a7d10824e063a94c9189bad2ab19b61299d..22b778dd662bd724e4ce02f687f047e6794ec312 100644 (file)
@@ -83,6 +83,8 @@ pub fn resolve(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
   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);
@@ -109,6 +111,9 @@ pub fn resolve(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
             #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();
@@ -135,8 +140,6 @@ pub fn resolve(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
         *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));
 
@@ -147,9 +150,6 @@ pub fn resolve(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
     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);
@@ -169,14 +169,6 @@ pub fn resolve(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
           #( #output )*
         })
       }
-
-      pub fn inspect_key(&self, field: &'_ str)
-                         -> Option<&dyn InspectableConfigValue> {
-        Some(match field {
-          #( #inspects )*
-          _ => return None,
-        })
-      }
     }
 
     #[derive(Debug)]
@@ -188,6 +180,14 @@ pub fn resolve(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
       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,
+        })
+      }
     }
   };
 
index 02af6f8292142901baf1be6765a3e99fccc7087c..05796d06bf5bde08a481e7a8e1ec74b649b82ee6 100644 (file)
@@ -24,6 +24,10 @@ pub struct Opts {
   /// 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;
@@ -123,7 +127,7 @@ pub async fn route_packet(global: &Global,
 
 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
@@ -145,6 +149,15 @@ async fn async_main(opts: Opts, daemon: Option<Daemoniser>) {
   {
     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();
index f3dfe4907eb2f7232ec3926e75c45de564320d2c..90f2296145e345811f3f43b3ca12bf72b33af3fb 100644 (file)
@@ -88,10 +88,6 @@ pub struct Opts {
   /// 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 {
@@ -121,6 +117,13 @@ macro_rules! impl_inspectable_config_value {
   };
 }
 
+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 }
index 35e012ebdf7b670856ceb310a7dbb21f147110ad..a692d06942134dd8a13a66ae25b1c4157def8415 100644 (file)
@@ -56,7 +56,7 @@ pub use eyre::WrapErr;
 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;