///| Return a list/array with a new element inserted before index (length appends).
///|
/// Containers are copied; unchanged elements are shared.
pub fn Value::inserted(
self : Value,
index : Int32,
value : Value,
) -> Value raise ConfigError {
let items = match self {
ScalarArray(v) | List(v) => v
_ =>
raise failure(
"type_mismatch",
"expected array or list; actual " + self.kind(),
)
}
if index < 0 || index > items.length() {
raise failure(
"index_out_of_bounds", "insertion index must be between zero and length",
)
}
if self is ScalarArray(_) {
match value {
Group(_) | ScalarArray(_) | List(_) =>
raise failure("array_type", "array elements must be scalars")
_ => ()
}
if items.length() > 0 && items[0].kind() != value.kind() {
raise failure(
"array_type",
"expected " + items[0].kind() + "; actual " + value.kind(),
)
}
}
let output : Array[Value] = []
for i = 0; i < items.length(); i = i + 1 {
if i == index {
output.push(value)
}
output.push(items[i])
}
if index == items.length() {
output.push(value)
}
match self {
ScalarArray(_) => ScalarArray(output)
_ => List(output)
}
}
///|
/// Append a scalar to an array or any value to a list.
pub fn Value::appended(self : Value, value : Value) -> Value raise ConfigError {
let size = match self {
ScalarArray(v) | List(v) => v.length()
_ =>
raise failure(
"type_mismatch",
"expected array or list; actual " + self.kind(),
)
}
self.inserted(size, value)
}
///|
/// Remove an existing list/array element; remaining elements retain order.
pub fn Value::removed_at(
self : Value,
index : Int32,
) -> Value raise ConfigError {
ignore(self.at(index))
let items = match self {
ScalarArray(v) | List(v) => v
_ => raise failure("type_mismatch", "expected array or list")
}
let output : Array[Value] = []
for i = 0; i < items.length(); i = i + 1 {
if i != index {
output.push(items[i])
}
}
match self {
ScalarArray(_) => ScalarArray(output)
_ => List(output)
}
}