1use crate::Error;
2use serde_json::{self, Map, Value};
3use std::collections::{hash_map::Entry, HashMap};
4use std::fs;
5use std::path::Path;
6
7#[derive(Debug, Clone)]
8pub struct Bindings {
9 bindings: HashMap<String, HashMap<String, String>>,
10}
11
12impl Bindings {
13 pub fn new(bindings: HashMap<String, HashMap<String, String>>) -> Bindings {
14 Self { bindings: bindings }
15 }
16
17 pub fn env(env: HashMap<String, String>) -> Bindings {
18 let mut bindings = HashMap::new();
19 bindings.insert("env".to_owned(), env);
20 Self::new(bindings)
21 }
22
23 pub fn empty() -> Bindings {
24 Self::new(HashMap::new())
25 }
26
27 pub fn from_json(v: &Value) -> Result<Bindings, Error> {
28 match v.as_object() {
29 Some(modules) => Self::parse_modules_json_obj(modules),
30 None => Err(Error::ParseJsonObjError)?,
31 }
32 }
33
34 pub fn from_str(s: &str) -> Result<Bindings, Error> {
35 let top: Value = serde_json::from_str(s)?;
36 Ok(Self::from_json(&top)?)
37 }
38
39 pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Bindings, Error> {
40 let contents = fs::read_to_string(path.as_ref())?;
41 Ok(Self::from_str(&contents)?)
42 }
43
44 pub fn extend(&mut self, other: &Bindings) -> Result<(), Error> {
45 for (modname, othermodbindings) in other.bindings.iter() {
46 match self.bindings.entry(modname.clone()) {
47 Entry::Occupied(mut e) => {
48 let existing = e.get_mut();
49 for (bindname, binding) in othermodbindings {
50 match existing.entry(bindname.clone()) {
51 Entry::Vacant(e) => {
52 e.insert(binding.clone());
53 }
54 Entry::Occupied(e) => {
55 if binding != e.get() {
56 Err(Error::RebindError {
57 key: e.key().to_owned(),
58 binding: binding.to_owned(),
59 attempt: e.get().to_owned(),
60 })?;
61 }
62 }
63 }
64 }
65 }
66 Entry::Vacant(e) => {
67 e.insert(othermodbindings.clone());
68 }
69 }
70 }
71 Ok(())
72 }
73
74 pub fn translate(&self, module: &str, symbol: &str) -> Result<&str, Error> {
75 match self.bindings.get(module) {
76 Some(m) => match m.get(symbol) {
77 Some(s) => Ok(s),
78 None => Err(Error::UnknownSymbol {
79 module: module.to_owned(),
80 symbol: symbol.to_owned(),
81 }),
82 },
83 None => Err(Error::UnknownModule {
84 module: module.to_owned(),
85 symbol: symbol.to_owned(),
86 }),
87 }
88 }
89
90 fn parse_modules_json_obj(m: &Map<String, Value>) -> Result<Self, Error> {
91 let mut res = HashMap::new();
92 for (modulename, values) in m {
93 match values.as_object() {
94 Some(methods) => {
95 let methodmap = Self::parse_methods_json_obj(methods)?;
96 res.insert(modulename.to_owned(), methodmap);
97 }
98 None => {
99 Err(Error::ParseError {
100 key: modulename.to_owned(),
101 value: values.to_string(),
102 })?;
103 }
104 }
105 }
106 Ok(Self::new(res))
107 }
108
109 fn parse_methods_json_obj(m: &Map<String, Value>) -> Result<HashMap<String, String>, Error> {
110 let mut res = HashMap::new();
111 for (method, i) in m {
112 match i.as_str() {
113 Some(importbinding) => {
114 res.insert(method.to_owned(), importbinding.to_owned());
115 }
116 None => {
117 Err(Error::ParseError {
118 key: method.to_owned(),
119 value: i.to_string(),
120 })?;
121 }
122 }
123 }
124 Ok(res)
125 }
126
127 pub fn to_string(&self) -> Result<String, Error> {
128 let s = serde_json::to_string(&self.to_json())?;
129 Ok(s)
130 }
131
132 pub fn to_json(&self) -> Value {
133 Value::from(self.serialize_modules_json_obj())
134 }
135
136 fn serialize_modules_json_obj(&self) -> Map<String, Value> {
137 let mut m = Map::new();
138 for (modulename, values) in self.bindings.iter() {
139 m.insert(
140 modulename.to_owned(),
141 Value::from(Self::serialize_methods_json_obj(values)),
142 );
143 }
144 m
145 }
146
147 fn serialize_methods_json_obj(methods: &HashMap<String, String>) -> Map<String, Value> {
148 let mut m = Map::new();
149 for (methodname, symbol) in methods.iter() {
150 m.insert(methodname.to_owned(), Value::from(symbol.to_owned()));
151 }
152 m
153 }
154}