// ============================================================
// Typed value convenience accessors
// ============================================================

///|
/// Read a Bool from a generic value.
pub fn Value::as_bool(self : Value) -> Bool? {
  match self {
    Value::Bool(value) => Some(value)
    _ => None
  }
}

///|
/// Read an Int from a generic value.
pub fn Value::as_int(self : Value) -> Int? {
  match self {
    Value::Int(value) => Some(value)
    _ => None
  }
}

///|
/// Read a Double from a generic value.
pub fn Value::as_double(self : Value) -> Double? {
  match self {
    Value::Double(value) => Some(value)
    _ => None
  }
}

///|
/// Read a String from a generic value.
pub fn Value::as_string(self : Value) -> String? {
  match self {
    Value::Str(value) => Some(value)
    _ => None
  }
}

///|
/// Read an integer or return a caller-provided default.
pub fn Blackboard::get_int_or(
  self : Blackboard,
  key : String,
  fallback : Int,
) -> Int {
  self.get_int(key).unwrap_or(fallback)
}

///|
/// Read a Boolean or return a caller-provided default.
pub fn Blackboard::get_bool_or(
  self : Blackboard,
  key : String,
  fallback : Bool,
) -> Bool {
  self.get_bool(key).unwrap_or(fallback)
}

///|
/// Read a Double or return a caller-provided default.
pub fn Blackboard::get_double_or(
  self : Blackboard,
  key : String,
  fallback : Double,
) -> Double {
  self.get_double(key).unwrap_or(fallback)
}

///|
/// Read a String or return a caller-provided default.
pub fn Blackboard::get_string_or(
  self : Blackboard,
  key : String,
  fallback : String,
) -> String {
  self.get_string(key).unwrap_or(fallback)
}

///|
/// Copy one value from a source blackboard when its type matches.
pub fn copy_value(
  source : Blackboard,
  target : Blackboard,
  key : String,
) -> Bool {
  match source.get_value(key) {
    None => false
    Some(value) => {
      target.set_value(key, value)
      true
    }
  }
}

///|
/// Copy many named values and return the number found.
pub fn copy_values(
  source : Blackboard,
  target : Blackboard,
  keys : Array[String],
) -> Int {
  let mut copied = 0
  for key in keys {
    if copy_value(source, target, key) {
      copied = copied + 1
    }
  }
  copied
}