#[cfg(feature = "no_std")]
use alloc::{borrow::ToOwned, string::String, vec::Vec};
#[cfg(not(feature = "no_std"))]
use std::collections::BTreeMap;
#[cfg(feature = "no_std")]
use alloc::collections::BTreeMap;
use crate::error::BopError;
use crate::value::Value;
use crate::BopHost;
pub fn resolve_from_map<I, K, V>(entries: I) -> impl Fn(&str) -> Option<Result<String, BopError>>
where
I: IntoIterator<Item = (K, V)>,
K: Into<String>,
V: Into<String>,
{
let map: BTreeMap<String, String> = entries
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect();
move |name: &str| map.get(name).map(|s| Ok(s.clone()))
}
pub struct StringModuleHost {
pub prints: Vec<String>,
modules: BTreeMap<String, String>,
}
impl StringModuleHost {
pub fn new<I, K, V>(modules: I) -> Self
where
I: IntoIterator<Item = (K, V)>,
K: Into<String>,
V: Into<String>,
{
Self {
prints: Vec::new(),
modules: modules
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect(),
}
}
pub fn insert_module(&mut self, name: impl Into<String>, source: impl Into<String>) {
self.modules.insert(name.into(), source.into());
}
pub fn output(&self) -> String {
self.prints.join("\n")
}
}
impl BopHost for StringModuleHost {
fn call(&mut self, _name: &str, _args: &[Value], _line: u32) -> Option<Result<Value, BopError>> {
None
}
fn on_print(&mut self, message: &str) {
self.prints.push(message.to_owned());
}
fn resolve_module(&mut self, name: &str) -> Option<Result<String, BopError>> {
self.modules.get(name).map(|s| Ok(s.clone()))
}
}