How To
foreign-variables
Foreign Variables are the variables that are not defined in any module but whose value can be defined by application (like FASTN). It’s value is populated by application during interpreter’s runtime.
Motivation Behind Foreign Variables
If application wants to provide value to any data variable at runtime, so they can use foreign variables.
It can be used to fetch data provided by application.
Resolving Foreign Variable In Application
let mut s = ftd::interpret(name, source)?; loop { ftd::Interpreter::StuckOnImport { module, state: mut st, } => { let source = if module.eq("fastn/time") { st.add_foreign_variable_prefix(module.as_str()); "".to_string() } else { lib.get_with_result(module.as_str(), &st.tdoc(&mut Default::default()))? }; s = st.continue_after_import(module.as_str(), source.as_str())?; } ftd::Interpreter::StuckOnForeignVariable { variable, state } => { let value = resolve_foreign_variable(variable.as_str(), name)?; s = state.continue_after_variable(variable.as_str(), value)? } } fn resolve_foreign_variable(variable: &str, doc_name: &str) -> ftd::p1::Result<ftd::Value> { match variable.strip_prefix("fastn/time#") { Some("now-str") => Ok(ftd::Value::String { text: std::str::from_utf8( std::process::Command::new("date") .output() .expect("failed to execute process") .stdout .as_slice(), ) .unwrap() .to_string(), source: ftd::TextSource::Header, }), _ => ftd::e2(format!("{} not found", variable).as_str(), doc_name, 0), } }
fastn/time.now-str
foo.ftd
-- import: fastn/time -- ftd.text: $time.now-str
The -- import: fastn/time
statement exposes foreign variable fastn/time.now-str
which returns the current date and time as a string.
The output looks something like this
Mon Jun 13 15:08:18 IST 2022