chiark / gitweb /
library listing: Provide for listing libs on the server side
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 15 May 2021 22:39:47 +0000 (23:39 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 15 May 2021 22:48:01 +0000 (23:48 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/cmdlistener.rs
src/commands.rs
src/mgmtchannel.rs
src/shapelib.rs

index a6036493609b0149fd203faf8fc8f8922642496e..9f29763a3030752c2e1c7fe1e6cbdcc76f2efe6c 100644 (file)
@@ -349,6 +349,25 @@ fn execute_and_respond<R,W>(cs: &mut CommandStreamData, cmd: MgmtCommand,
       Fine
     }
 
+    MC::LibraryListLibraries { game } => {
+      let (ag, gref) = start_access_game(&game)?;
+      let (libs, _auth) =
+        access_bundles(
+          cs,&ag,&gref, &[TP::UploadBundles],
+          &mut |ig, _| Ok(
+            ig.all_shapelibs()
+              .iter()
+              .map(|reg| reg.iter())
+              .flatten()
+              .map(|ll| ll.iter())
+              .flatten()
+              .map(|l| l.enquiry())
+              .collect::<Vec<shapelib::LibraryEnquiryData>>()
+          )
+        )?;
+      MR::Libraries(libs)
+    }
+
     MC::LibraryListByGlob { game, glob: spec } => {
       let (ag, gref) = start_access_game(&game)?;
       let (results, _auth) =
index 166b5d9ff6cbdee8f9f6d112074d295fb480e9c4..6c02d48cc55ebaa01974353ac08a26fbbccad3f4 100644 (file)
@@ -54,6 +54,9 @@ pub enum MgmtCommand {
     id: bundles::Id,
   },
 
+  LibraryListLibraries {
+    game: InstanceName,
+  },
   LibraryListByGlob {
     game: InstanceName,
     glob: shapelib::ItemSpec,
@@ -90,6 +93,7 @@ pub enum MgmtResponse {
   AlterGame { error: Option<MgmtError>, responses: Vec<MgmtGameResponse> },
   AccountsList(Vec<Arc<AccountName>>),
   GamesList(Vec<Arc<InstanceName>>),
+  Libraries(Vec<shapelib::LibraryEnquiryData>),
   LibraryItems(Vec<shapelib::ItemEnquiryData>),
   Bundles { bundles: MgmtBundleList },
 }
index ef41428de0a4770e8c69e277d90eff4c2ac8674f..0edb7470767b2919c0ec4bc88e012d63dc5b2b8f 100644 (file)
@@ -91,7 +91,7 @@ impl MgmtChannel {
     match &resp {
       Progress(_) => panic!(),
       Fine | AccountsList{..} | GamesList{..} |
-      LibraryItems(_) | Bundles{..} => { },
+      Libraries(_) | LibraryItems(_) | Bundles{..} => { },
       AlterGame { error: None, .. } => { },
       Error { error } => {
         Err(error.clone()).context(
index b0ef0898488eb50114f112efbb54714f83135304..c68cee13a5850d250c835c939c937c233a1f72af 100644 (file)
@@ -236,6 +236,23 @@ impl Display for ItemEnquiryData {
   }
 }
 
+#[derive(Debug,Clone,Serialize,Deserialize,Eq,PartialEq,Ord,PartialOrd)]
+pub struct LibraryEnquiryData {
+  pub libname: String,
+}
+impl Display for LibraryEnquiryData {
+  #[throws(fmt::Error)]
+  fn fmt(&self, f: &mut Formatter) {
+    if self.libname.chars().all(|c| {
+      c.is_alphanumeric() || c=='-' || c=='_' || c=='.'
+    }) {
+      Display::fmt(&self.libname, f)?;
+    } else {
+      Debug::fmt(&self.libname, f)?;
+    }
+  }
+}
+
 #[dyn_upcast]
 impl OutlineTrait for Item { delegate! { to self.outline {
   fn outline_path(&self, scale: f64) -> Result<Html, IE>;
@@ -354,6 +371,10 @@ impl Registry {
   pub fn clear(&mut self) {
     self.libs.clear()
   }
+
+  pub fn iter(&self) -> impl Iterator<Item=&[Contents]> {
+    self.libs.values().map(|v| v.as_slice())
+  }
 }
 
 pub struct AllRegistries<'ig> {
@@ -405,6 +426,11 @@ pub fn lib_name_list(ig: &Instance) -> Vec<String> {
 }
 
 impl<'ig> AllRegistries<'ig> {
+  pub fn all_libs(&self) -> impl Iterator<Item=&[Contents]> {
+    self.iter().map(|reg| &reg.libs).flatten().map(
+      |(_libname, lib)| lib.as_slice()
+    )
+  }
   pub fn lib_name_lookup(&self, libname: &str) -> Result<&[Contents], SpE> {
     for reg in self.iter() {
       if let Some(r) = reg.libs.get(libname) { return Ok(r) }
@@ -551,6 +577,12 @@ impl Contents {
     (Box::new(it), occultable)
   }
 
+  pub fn enquiry(&self) -> LibraryEnquiryData {
+    LibraryEnquiryData {
+      libname: self.libname.clone(),
+    }
+  }
+
   #[throws(MgmtError)]
   pub fn list_glob(&self, pat: &str) -> Vec<ItemEnquiryData> {
     let pat = glob::Pattern::new(pat).map_err(|pe| ME::BadGlob {