summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2021-08-14 09:49:17 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2021-09-07 17:32:20 +0100
commit4436b7ee28b0318a96d98833d85d712c8a18850d (patch)
treeca8c124284b7585b310fa4340d6a63be498ccba6 /src
parent70461d3af84d1f5363df67f2f50f10b9dce86812 (diff)
downloadsubplot-4436b7ee28b0318a96d98833d85d712c8a18850d.tar.gz
bindings: Parse polyglot bindings
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'src')
-rw-r--r--src/bindings.rs62
1 files changed, 50 insertions, 12 deletions
diff --git a/src/bindings.rs b/src/bindings.rs
index 5b8d013..9282155 100644
--- a/src/bindings.rs
+++ b/src/bindings.rs
@@ -10,6 +10,7 @@ use serde_aux::prelude::*;
use std::collections::HashMap;
use std::fmt::Debug;
+use std::ops::Deref;
use std::path::Path;
use std::str::FromStr;
use std::sync::Arc;
@@ -206,8 +207,8 @@ impl Binding {
}
/// Retrieve a particular implementation by name
- pub fn step_impl(&self, template: &str) -> Option<Arc<BindingImpl>> {
- self.impls.get(template).cloned()
+ pub fn step_impl(&self, _template: &str) -> Option<Arc<BindingImpl>> {
+ self.impls.values().next().cloned()
}
/// Return the compiled regular expression for the pattern of the
@@ -399,12 +400,33 @@ impl Default for Bindings {
}
#[derive(Debug, Deserialize)]
+struct ParsedImpl {
+ function: String,
+ cleanup: Option<String>,
+}
+
+#[derive(Debug, Deserialize)]
+#[serde(transparent)]
+struct ParsedImplWrapper {
+ #[serde(deserialize_with = "deserialize_struct_case_insensitive")]
+ pimpl: ParsedImpl,
+}
+
+impl Deref for ParsedImplWrapper {
+ type Target = ParsedImpl;
+
+ fn deref(&self) -> &Self::Target {
+ &self.pimpl
+ }
+}
+
+#[derive(Debug, Deserialize)]
struct ParsedBinding {
given: Option<String>,
when: Option<String>,
then: Option<String>,
- function: String,
- cleanup: Option<String>,
+ #[serde(default, rename = "impl")]
+ impls: HashMap<String, ParsedImplWrapper>,
regex: Option<bool>,
#[serde(default)]
case_sensitive: bool,
@@ -549,7 +571,9 @@ fn from_hashmap(parsed: &ParsedBinding) -> Result<Binding> {
let mut ret = Binding::new(kind, &pattern, parsed.case_sensitive, types)?;
event!(Level::TRACE, "Binding parsed OK");
- ret.add_impl("", &parsed.function, parsed.cleanup.as_deref());
+ for (template, pimpl) in &parsed.impls {
+ ret.add_impl(template, &pimpl.function, pimpl.cleanup.as_deref());
+ }
Ok(ret)
}
@@ -589,16 +613,26 @@ mod test_bindings {
fn adds_from_yaml() {
let yaml = "
- GIVEN: I am Tomjon
- function: set_name
+ impl:
+ python:
+ function: set_name
- when: I declare myself king
- Function: declare_king
+ impl:
+ python:
+ Function: declare_king
- tHEn: there is applause
- function: check_for_applause
+ impl:
+ python:
+ function: check_for_applause
- given: you are alice
- function: other_name
+ impl:
+ python:
+ function: other_name
case_sensitive: true
- then: the total is {total}
- function: check_total
+ impl:
+ python:
+ function: check_total
types:
total: word
";
@@ -619,7 +653,9 @@ mod test_bindings {
let yaml = "
- Given: I am Tomjon
wheN: I am indeed Tomjon
- FUNCTION: set_name
+ impl:
+ python:
+ FUNCTION: set_name
";
match Bindings::new().add_from_yaml(yaml) {
Ok(_) => unreachable!(),
@@ -632,7 +668,9 @@ mod test_bindings {
fn typemap_must_match_pattern() {
let yaml = "
- then: you are {age:word} years old
- function: check_age
+ impl:
+ python:
+ function: check_age
types:
age: number
";