chiark / gitweb /
config, wip parsing
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 24 Jul 2021 12:32:31 +0000 (13:32 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 24 Jul 2021 12:32:31 +0000 (13:32 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/config.rs

index b06b25d51a311dffe75e2603ff68283252e83118..9b0f18411344c355b67dcaca87ba1bf34df695de 100644 (file)
@@ -25,14 +25,12 @@ pub struct CidrString(pub String);
 
 #[derive(hippotat_macros::ResolveConfig)]
 pub struct InstanceConfig {
-/*
   // Exceptional settings
-  #[special(special_name, SKL::ServerName)] pub server: String,
-  pub                                           secret: String, // xxx newytpe
-  #[special(special_ipif, SKL::Ordinary)]   pub ipif:   String,
+  #[special(special_server, SKL::ServerName)] pub server: ServerName,
+  pub                                             secret: String, //xxx newytpe
+  #[special(special_ipif, SKL::Ordinary)]     pub ipif:   String,
 
   // Capped settings:
-*/
   #[limited]    pub max_batch_down:               u32,
   #[limited]    pub max_queue_time:               Duration,
   #[limited]    pub http_timeout:                 Duration,
@@ -81,6 +79,7 @@ pub struct Config {
 }
 
 static OUTSIDE_SECTION: &str = "[";
+static SPECIAL_SERVER_SECTION: &str = "SERVER";
 
 #[derive(Default,Debug)]
 struct Aggregate {
@@ -264,6 +263,7 @@ struct ResolveContext<'c> {
   link: &'c LinkName,
   end: LinkEnd,
   all_sections: Vec<SectionName>,
+  special_server_section: SectionName,
 }
 
 trait Parseable: Sized {
@@ -324,6 +324,12 @@ enum SectionKindList {
 }
 use SectionKindList as SKL;
 
+impl SectionName {
+  fn special_server_section() -> Self { SN::Server(ServerName(
+    SPECIAL_SERVER_SECTION.into()
+  )) }
+}
+
 impl SectionKindList {
   fn contains(self, s: &SectionName) -> bool {
     match self {
@@ -343,17 +349,17 @@ impl SectionKindList {
 
       SKL::ServerName     => matches!(s, SN::Common)
                            | matches!(s, SN::Server(ServerName(name))
-                                         if name == "SERVER"),
+                                         if name == SPECIAL_SERVER_SECTION),
     }
   }
 }
 
 impl<'c> ResolveContext<'c> {
-  fn first_of_raw(&self, key: &'static str, sections: SectionKindList)
-                  -> Option<&'c RawVal> {
-    for section in self.all_sections.iter()
-      .filter(|s| sections.contains(s))
-    {
+  fn lookup_raw<'n, S>(&self, key: &'static str, sections: S)
+                       -> Option<&'c RawVal>
+  where S: Iterator<Item=&'n SectionName>
+  {
+    for section in sections {
       if let Some(raw) = self.agg.sections
         .get(section)
         .and_then(|vars: &SectionMap| vars.get(key))
@@ -364,6 +370,15 @@ impl<'c> ResolveContext<'c> {
     None
   }
 
+  fn first_of_raw(&self, key: &'static str, sections: SectionKindList)
+                  -> Option<&'c RawVal> {
+    self.lookup_raw(
+      key,
+      self.all_sections.iter()
+        .filter(|s| sections.contains(s))
+    )
+  }
+
   #[throws(AE)]
   fn first_of<T>(&self, key: &'static str, sections: SectionKindList)
                  -> Option<T>
@@ -420,9 +435,7 @@ impl<'c> ResolveContext<'c> {
   }
 
   #[throws(AE)]
-  pub fn special_ipif<T>(&self, key: &'static str) -> T
-  where T: Parseable + Default
-  {
+  pub fn special_ipif(&self, key: &'static str) -> String {
     match self.end {
       LinkEnd::Client => self.ordinary(key)?,
       LinkEnd::Server => {
@@ -431,6 +444,19 @@ impl<'c> ResolveContext<'c> {
       },
     }
   }
+
+  #[throws(AE)]
+  pub fn special_server(&self, key: &'static str) -> ServerName {
+    let raw = match self.lookup_raw(
+      "server",
+      [ &SectionName::Common, &self.special_server_section ].iter().cloned()
+    ) {
+      Some(RawVal { val: Some(ref got),.. }) => got,
+      Some(RawVal { val: None,.. }) => throw!(anyhow!("value needed")),
+      None => SPECIAL_SERVER_SECTION,
+    };
+    ServerName(raw.into())
+  }
 }
 
 /*
@@ -478,5 +504,6 @@ pub fn read() {
       SN::ServerLimit(link.server.clone()),
       SN::GlobalLimit,
     ],
+    special_server_section: SN::special_server_section(),
   };
 }