diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2021-08-14 09:49:17 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2021-09-07 17:32:20 +0100 |
commit | 4436b7ee28b0318a96d98833d85d712c8a18850d (patch) | |
tree | ca8c124284b7585b310fa4340d6a63be498ccba6 /src/bindings.rs | |
parent | 70461d3af84d1f5363df67f2f50f10b9dce86812 (diff) | |
download | subplot-4436b7ee28b0318a96d98833d85d712c8a18850d.tar.gz |
bindings: Parse polyglot bindings
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'src/bindings.rs')
-rw-r--r-- | src/bindings.rs | 62 |
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 "; |