use std::sync::Arc;
use arcstr::{literal, ArcStr};
use imbl::vector;
use crate::{model::{Graph, LibFunc, Param}, runtime::{instruction::Instructions, instructions::map::{ANY_MAP, APPEND_MAP, AT_MAP, AT_REF_MAP, CLEAR_MAP, CONTAINS_MAP, EMPTY_MAP, FIRST_MAP, FIRST_REF_MAP, GET_MAP, GET_REF_MAP, INSERT_MAP, KEYS_MAP, LAST_MAP, LAST_REF_MAP, LEN_MAP, POP_FIRST_MAP, POP_LAST_MAP, REMOVE_MAP, VALUES_MAP, VALUES_REF_MAP}, NumT, Type}};
pub(self) const MAP_LIB: ArcStr = literal!("Map");
pub fn insert_map_lib(graph: &mut Graph) {
graph.insert_libfunc(map_append());
graph.insert_libfunc(map_clear());
graph.insert_libfunc(map_contains());
graph.insert_libfunc(map_first());
graph.insert_libfunc(map_last());
graph.insert_libfunc(map_get());
graph.insert_libfunc(map_insert());
graph.insert_libfunc(map_empty());
graph.insert_libfunc(map_any());
graph.insert_libfunc(map_keys());
graph.insert_libfunc(map_values());
graph.insert_libfunc(map_len());
graph.insert_libfunc(map_at());
graph.insert_libfunc(map_pop_first());
graph.insert_libfunc(map_pop_last());
graph.insert_libfunc(map_remove());
}
fn map_append() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "append".into(),
is_async: false,
docs: r#"# Map.append(this: map, other: map) -> void
Append the items of another map onto this map.
```rust
const map = {"a": 1};
map.append({"b": 2});
assert_eq(map, {"a": 1, "b": 2});
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None },
Param { name: "other".into(), param_type: Type::Map, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|_as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
instructions.push(APPEND_MAP.clone());
Ok(instructions)
})
}
}
fn map_clear() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "clear".into(),
is_async: false,
docs: r#"# Map.clear(this: map) -> void
Clear this map of all items.
```rust
const map = {"a": 1};
map.clear();
assert(map.empty());
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|_as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
instructions.push(CLEAR_MAP.clone());
Ok(instructions)
})
}
}
fn map_contains() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "contains".into(),
is_async: false,
docs: r#"# Map.contains(this: map, key: unknown) -> bool
Returns true if this map contains a key that equals the given value.
```rust
const map = {"a": 1};
assert(map.contains("a"));
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None },
Param { name: "key".into(), param_type: Type::Void, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|_as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
instructions.push(CONTAINS_MAP.clone());
Ok(instructions)
})
}
}
fn map_first() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "first".into(),
is_async: false,
docs: r#"# Map.first(this: map) -> (unknown, unknown)
Return the first key-value pair in this ordered map, or null if the map is empty. Optionally return the value as a reference with the '&' operator.
```rust
const map = {"a": 1};
assert_eq(map.first(), ("a", 1));
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
if as_ref {
instructions.push(FIRST_REF_MAP.clone());
} else {
instructions.push(FIRST_MAP.clone());
}
Ok(instructions)
})
}
}
fn map_last() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "last".into(),
is_async: false,
docs: r#"# Map.last(this: map) -> (unknown, unknown)
Return the last key-value pair in this ordered map, or null if the map is empty. Optionally return the value as a reference with the '&' operator.
```rust
const map = {"a": 1, "b": 3};
assert_eq(map.last(), ("b", 3));
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
if as_ref {
instructions.push(LAST_REF_MAP.clone());
} else {
instructions.push(LAST_MAP.clone());
}
Ok(instructions)
})
}
}
fn map_get() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "get".into(),
is_async: false,
docs: r#"# Map.get(this: map, key: unknown) -> unknown
Return a value for the given key in this map, optionally by reference.
```rust
const map = {"a": 1};
assert_eq(map.get("a"), 1);
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None },
Param { name: "key".into(), param_type: Type::Void, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
if as_ref {
instructions.push(GET_REF_MAP.clone());
} else {
instructions.push(GET_MAP.clone());
}
Ok(instructions)
})
}
}
fn map_insert() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "insert".into(),
is_async: false,
docs: r#"# Map.insert(this: map, key: unknown, value: unknown) -> unknown
Insert a key-value pair into this map, returning the old value if the key was already present, or null otherwise.
```rust
const map = {"a": 1};
assert_eq(map.insert("a", 3), 1);
assert_eq(map, {"a": 3});
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None },
Param { name: "key".into(), param_type: Type::Void, default: None },
Param { name: "value".into(), param_type: Type::Void, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|_as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
instructions.push(INSERT_MAP.clone());
Ok(instructions)
})
}
}
fn map_empty() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "empty".into(),
is_async: false,
docs: r#"# Map.empty(this: map) -> bool
Is this map empty?
```rust
const map = map();
assert(map.empty());
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|_as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
instructions.push(EMPTY_MAP.clone());
Ok(instructions)
})
}
}
fn map_any() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "any".into(),
is_async: false,
docs: r#"# Map.any(this: map) -> bool
Does this map contain any key-value pairs?
```rust
const map = map();
assert_not(map.any());
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|_as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
instructions.push(ANY_MAP.clone());
Ok(instructions)
})
}
}
fn map_keys() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "keys".into(),
is_async: false,
docs: r#"# Map.keys(this: map) -> set
A set of this map's keys.
```rust
const map = {"a": 1, "b": 2};
assert_eq(map.keys(), {"a", "b"});
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|_as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
instructions.push(KEYS_MAP.clone());
Ok(instructions)
})
}
}
fn map_values() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "values".into(),
is_async: false,
docs: r#"# Map.values(this: map) -> list
A list of this map's values.
```rust
const map = {"a": 1, "b": 2};
assert_eq(map.values(), [1, 2]);
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
if as_ref {
instructions.push(VALUES_REF_MAP.clone());
} else {
instructions.push(VALUES_MAP.clone());
}
Ok(instructions)
})
}
}
fn map_len() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "len".into(),
is_async: false,
docs: r#"# Map.len(this: map) -> int
The number of key-value pairs in this map.
```rust
const map = {"a": 1, "b": 2};
assert_eq(map.len(), 2);
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|_as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
instructions.push(LEN_MAP.clone());
Ok(instructions)
})
}
}
fn map_at() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "at".into(),
is_async: false,
docs: r#"# Map.at(this: map, index: int) -> (unknown, unknown)
The key-value pair at the given index in this sorted map.
```rust
const map = {"a": 1, "b": 2};
assert_eq(map.at(1), ("b", 2));
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None },
Param { name: "index".into(), param_type: Type::Num(NumT::Int), default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
if as_ref {
instructions.push(AT_REF_MAP.clone());
} else {
instructions.push(AT_MAP.clone());
}
Ok(instructions)
})
}
}
fn map_pop_first() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "pop_first".into(),
is_async: false,
docs: r#"# Map.pop_first(this: map) -> (unknown, unknown)
Remove the smallest key-value pair from this map and return it.
```rust
const map = {"a": 1, "b": 2};
assert_eq(map.pop_first(), ("a", 1));
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|_as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
instructions.push(POP_FIRST_MAP.clone());
Ok(instructions)
})
}
}
fn map_pop_last() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "pop_last".into(),
is_async: false,
docs: r#"# Map.pop_last(this: map) -> (unknown, unknown)
Remove the largest key-value pair from this map and return it.
```rust
const map = {"a": 1, "b": 2};
assert_eq(map.pop_last(), ("b", 2));
```"#.into(),params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|_as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
instructions.push(POP_LAST_MAP.clone());
Ok(instructions)
})
}
}
fn map_remove() -> LibFunc {
LibFunc {
library: MAP_LIB.clone(),
name: "remove".into(),
is_async: false,
docs: r#"# Map.remove(this: map, key: unknown) -> unknown
Remove the value with the given key and return it, or null if the key isn't present.
```rust
const map = {"a": 1, "b": 2};
assert_eq(map.remove("b"), 2);
assert_eq(map, {"a": 1});
```"#.into(),
params: vector![
Param { name: "map".into(), param_type: Type::Map, default: None },
Param { name: "key".into(), param_type: Type::Void, default: None }
],
return_type: None,
unbounded_args: false,
args_to_symbol_table: false,
func: Arc::new(|_as_ref, _arg_count, _env, _graph| {
let mut instructions = Instructions::default();
instructions.push(REMOVE_MAP.clone());
Ok(instructions)
})
}
}