summaryrefslogtreecommitdiff
path: root/src/templatespec.rs
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-04-22 08:58:33 +0300
committerLars Wirzenius <liw@liw.fi>2020-04-22 10:50:01 +0300
commite50ca0c984173ce8d84d6a4092096753512ccf26 (patch)
tree40d3066d06750681201579bbc5ca623c3708c615 /src/templatespec.rs
parent364ab272087f94625df0af1ec53ccb5be8003eb8 (diff)
downloadsubplot-e50ca0c984173ce8d84d6a4092096753512ccf26.tar.gz
Change: get Python template from templates/python/template.{yaml.py}
All the language specific details are now in template.yaml, including the command for how to run the generated test program.
Diffstat (limited to 'src/templatespec.rs')
-rw-r--r--src/templatespec.rs88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/templatespec.rs b/src/templatespec.rs
new file mode 100644
index 0000000..77191a6
--- /dev/null
+++ b/src/templatespec.rs
@@ -0,0 +1,88 @@
+use crate::Result;
+use crate::SubplotError;
+
+use serde::Deserialize;
+use serde_yaml;
+
+use std::fs::File;
+use std::io::Read;
+use std::path::{Path, PathBuf};
+
+/// A template specification.
+///
+/// Contains the information codegen needs to use a template for
+/// generating a test program. The names and types of fields match the
+/// files in the `templates/.../template.yaml` files.
+#[derive(Debug, Deserialize)]
+pub struct TemplateSpec {
+ template: PathBuf,
+ run: Option<String>,
+}
+
+impl TemplateSpec {
+ // Create a new TemplateSpec from YAML text.
+ fn from_yaml(yaml: &str) -> Result<TemplateSpec> {
+ Ok(serde_yaml::from_str(yaml)?)
+ }
+
+ // Create a new TemplateSpec.
+ fn new(basedir: &Path, template: &Path, run: Option<&str>) -> TemplateSpec {
+ TemplateSpec {
+ template: basedir.to_path_buf().join(template),
+ run: match run {
+ Some(x) => Some(x.to_string()),
+ None => None,
+ },
+ }
+ }
+
+ /// Read a template.yaml file and create the corresponding TemplateSpec.
+ pub fn from_file(filename: &Path) -> Result<TemplateSpec> {
+ let mut f = File::open(filename)?;
+ let mut yaml = String::new();
+ f.read_to_string(&mut yaml)?;
+ let spec = TemplateSpec::from_yaml(&yaml)?;
+ let dirname = match filename.parent() {
+ Some(x) => x,
+ None => {
+ return Err(SubplotError::NoTemplateSpecDirectory(
+ filename.to_path_buf(),
+ ))
+ }
+ };
+ Ok(TemplateSpec::new(
+ &dirname,
+ spec.template_filename(),
+ spec.run(),
+ ))
+ }
+
+ /// Return the name of the template file.
+ pub fn template_filename(&self) -> &Path {
+ &self.template
+ }
+
+ /// Return command to run the generated test program, if specified.
+ ///
+ /// The name of the test program gets appended.
+ pub fn run(&self) -> Option<&str> {
+ match &self.run {
+ Some(run) => Some(&run),
+ None => None,
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::TemplateSpec;
+
+ #[test]
+ fn new_from_yaml() {
+ let yaml = "
+template: template.py
+";
+ let spec = TemplateSpec::from_yaml(yaml).unwrap();
+ assert_eq!(spec.template_filename().to_str().unwrap(), "template.py");
+ }
+}