chiark / gitweb /
otter(1): Break out BundleForUpload
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 20 May 2021 13:23:13 +0000 (14:23 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 20 May 2021 13:23:13 +0000 (14:23 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/bin/otter.rs

index 5c7d2751d1a69301a7da41146785f5acba4508ac..d0745dfd05ceb89d49a52d3b6141e38983b066cb 100644 (file)
@@ -1506,28 +1506,18 @@ mod alter_game_adhoc {
 
 //---------- upload-bundle ----------
 
-mod upload_bundle {
-  use super::*;
-
-  #[derive(Default,Debug)]
-  struct Args {
-    bundle_file: String,
-  }
-
-  fn subargs(sa: &mut Args) -> ArgumentParser {
-    use argparse::*;
-    let mut ap = ArgumentParser::new();
-    ap.refer(&mut sa.bundle_file).required()
-      .add_argument("BUNDLE",Store,"bundle file");
-    ap
-  }
+struct BundleForUpload {
+  f: BufReader<File>,
+  size: usize,
+  hash: bundles::Hash,
+  kind: bundles::Kind,
+}
 
+impl BundleForUpload {
   #[throws(AE)]
-  fn call(_sc: &Subcommand, ma: MainOpts, args: Vec<String>) {
-    let args = parse_args::<Args,_>(args, &subargs, &ok_id, None);
-    let mut chan = ma.access_game()?;
-    let f = File::open(&args.bundle_file)
-      .with_context(|| args.bundle_file.clone())
+  fn prepare(file: &str) -> Self {
+    let f = File::open(file.clone())
+      .with_context(|| file.to_owned())
       .context("open bundle file")?;
     let size = f
       .metadata().context("fstat bundle file")?
@@ -1536,20 +1526,55 @@ mod upload_bundle {
     let mut f = BufReader::new(f);
     let hash = bundles::DigestWrite::of(&mut f)
       .context("read bundle file (for hash)")?;
+    let hash = bundles::Hash(hash.into());
     let kind = bundles::Kind::only();
     f.rewind().context("rewind bundle file")?;
+    BundleForUpload { f, size, hash, kind }
+  }
+
+  #[throws(AE)]
+  fn upload(self, ma: &MainOpts, chan: &mut MgmtChannelForGame,
+            progress: &mut dyn termprogress::Reporter)
+            -> bundles::Id {
+    let BundleForUpload { mut f, size, hash, kind } = self;
     let cmd = MC::UploadBundle {
       size,
       game: ma.instance(),
-      hash: bundles::Hash(hash.into()), kind,
+      hash, kind,
       progress: MgmtChannel::PROGRESS,
     };
-    let mut progress = termprogress::new();
     let resp = chan.cmd_withbulk(&cmd, &mut f, &mut io::sink(),
                                  &mut *progress)?;
     if_let!{ MR::Bundle { bundle } = resp;
              else throw!(anyhow!("unexpected {:?}", &resp)) };
     progress.clear();
+    bundle
+  }
+}
+
+mod upload_bundle {
+  use super::*;
+
+  #[derive(Default,Debug)]
+  struct Args {
+    bundle_file: String,
+  }
+
+  fn subargs(sa: &mut Args) -> ArgumentParser {
+    use argparse::*;
+    let mut ap = ArgumentParser::new();
+    ap.refer(&mut sa.bundle_file).required()
+      .add_argument("BUNDLE",Store,"bundle file");
+    ap
+  }
+
+  #[throws(AE)]
+  fn call(_sc: &Subcommand, ma: MainOpts, args: Vec<String>) {
+    let args = parse_args::<Args,_>(args, &subargs, &ok_id, None);
+    let mut chan = ma.access_game()?;
+    let mut progress = termprogress::new();
+    let for_upload = BundleForUpload::prepare(&args.bundle_file)?;
+    let bundle = for_upload.upload(&ma, &mut chan, &mut *progress)?;
     println!("{}", bundle);
   }