///|
/// Environment Bindings
/// Platform-agnostic interface for environment variables and bindings
///|
/// Environment trait for platform-specific bindings
/// Implement this trait for your platform (Cloudflare, Deno, etc.)
pub(open) trait Env {
/// Get an environment variable
get_var(Self, String) -> String?
/// Get a binding by name (KV, D1, R2, etc.)
get_binding(Self, String) -> Json?
}
///|
/// Empty environment (no bindings)
pub(all) struct EmptyEnv {}
///|
pub fn EmptyEnv::new() -> EmptyEnv {
EmptyEnv::{ }
}
///|
pub impl Env for EmptyEnv with get_var(_self, _name) {
None
}
///|
pub impl Env for EmptyEnv with get_binding(_self, _name) {
None
}
///|
/// Map-based environment (for testing and simple use cases)
pub(all) struct MapEnv {
vars : Map[String, String]
bindings : Map[String, Json]
}
///|
pub fn MapEnv::new() -> MapEnv {
{ vars: {}, bindings: {} }
}
///|
pub fn MapEnv::with_var(self : MapEnv, name : String, value : String) -> MapEnv {
self.vars.set(name, value)
self
}
///|
pub fn MapEnv::with_binding(
self : MapEnv,
name : String,
value : Json,
) -> MapEnv {
self.bindings.set(name, value)
self
}
///|
pub impl Env for MapEnv with get_var(self, name) {
self.vars.get(name)
}
///|
pub impl Env for MapEnv with get_binding(self, name) {
self.bindings.get(name)
}
///|
/// Typed variables storage
/// Uses Json for flexible storage with runtime type checking
pub(all) struct Variables {
data : Map[String, Json]
}
///|
pub fn Variables::new() -> Variables {
{ data: {} }
}
///|
/// Set a string variable
pub fn Variables::set_string(
self : Variables,
key : String,
value : String,
) -> Unit {
self.data.set(key, Json::string(value))
}
///|
/// Get a string variable
pub fn Variables::get_string(self : Variables, key : String) -> String? {
match self.data.get(key) {
Some(String(s)) => Some(s)
_ => None
}
}
///|
/// Set a number variable
pub fn Variables::set_number(
self : Variables,
key : String,
value : Double,
) -> Unit {
self.data.set(key, Json::number(value))
}
///|
/// Get a number variable
pub fn Variables::get_number(self : Variables, key : String) -> Double? {
match self.data.get(key) {
Some(Number(n, ..)) => Some(n)
_ => None
}
}
///|
/// Set a boolean variable
pub fn Variables::set_bool(
self : Variables,
key : String,
value : Bool,
) -> Unit {
self.data.set(key, Json::boolean(value))
}
///|
/// Get a boolean variable
pub fn Variables::get_bool(self : Variables, key : String) -> Bool? {
match self.data.get(key) {
Some(True) => Some(true)
Some(False) => Some(false)
_ => None
}
}
///|
/// Set a JSON variable
pub fn Variables::set_json(
self : Variables,
key : String,
value : Json,
) -> Unit {
self.data.set(key, value)
}
///|
/// Get a JSON variable
pub fn Variables::get_json(self : Variables, key : String) -> Json? {
self.data.get(key)
}
///|
/// Check if variable exists
pub fn Variables::has(self : Variables, key : String) -> Bool {
self.data.contains(key)
}
///|
/// Remove a variable
pub fn Variables::remove(self : Variables, key : String) -> Unit {
self.data.remove(key)
}
///|
/// Get all keys
pub fn Variables::keys(self : Variables) -> Array[String] {
let result : Array[String] = []
for key, _ in self.data {
result.push(key)
}
result
}