ptest: Add `list` command

The `list` command will show what tests are available.

Signed-off-by: David Brown <david.brown@linaro.org>
diff --git a/ptest/src/main.rs b/ptest/src/main.rs
index adec579..e0e41a9 100644
--- a/ptest/src/main.rs
+++ b/ptest/src/main.rs
@@ -40,10 +40,6 @@
 
     let args = Cli::parse();
 
-    match args.command {
-        Commands::Run => (),
-    }
-
     let workflow_text = fs::read_to_string(&args.workflow)?;
     let workflow = YamlLoader::load_from_str(&workflow_text)?;
 
@@ -52,6 +48,14 @@
 
     let matrix = Matrix::from_yaml(&workflow);
 
+    match args.command {
+        Commands::List => {
+            matrix.show();
+            return Ok(());
+        }
+        Commands::Run => (),
+    }
+
     let mut children = vec![];
     let state = State::new(matrix.envs.len());
     let st2 = state.clone();
@@ -100,6 +104,8 @@
 enum Commands {
     /// Runs the tests.
     Run,
+    /// List available tests.
+    List,
 }
 
 /// State, for printing status.
@@ -246,6 +252,13 @@
             envs,
         }
     }
+
+    /// Print out all of the feature sets.
+    fn show(&self) {
+        for (i, feature) in self.envs.iter().enumerate() {
+            println!("{:3}. {}", i, feature.simple_textual());
+        }
+    }
 }
 
 impl FeatureSet {
@@ -304,6 +317,18 @@
 
         buf
     }
+
+    /// Generate a simpler textual representation, without showing the environment.
+    fn simple_textual(&self) -> String {
+        use std::fmt::Write;
+
+        let mut buf = String::new();
+        for v in &self.values {
+            write!(&mut buf, " {}", v).unwrap();
+        }
+
+        buf
+    }
 }
 
 fn lookup_matrix(y: &Yaml) -> Option<&Vec<Yaml>> {