Skip to main content

sim_lib_expr_tree/
projection.rs

1use std::sync::Arc;
2
3use sim_kernel::{Cx, Factory, Ref, Result, Symbol, Value, card::Card};
4
5use crate::{
6    operation::{OperationSpec, operation_specs},
7    shape::{argument_shape, result_shape},
8};
9
10/// Projects one browseable Card for every stable expression-tree operation.
11pub fn operation_cards(cx: &mut Cx) -> Result<Vec<Value>> {
12    let contracts = operation_specs()
13        .into_iter()
14        .map(|spec| {
15            (
16                spec,
17                argument_shape(spec.name, spec.min_args, spec.max_args, spec.args_detail),
18                result_shape(spec.name, spec.result_detail),
19            )
20        })
21        .collect::<Vec<_>>();
22    cards_for_contracts(cx.factory(), &contracts)
23}
24
25pub(crate) fn cards_for_contracts(
26    factory: &dyn Factory,
27    contracts: &[(OperationSpec, Value, Value)],
28) -> Result<Vec<Value>> {
29    contracts
30        .iter()
31        .map(|(spec, args_shape, result_shape)| {
32            operation_card(factory, *spec, args_shape.clone(), result_shape.clone())
33        })
34        .collect()
35}
36
37fn operation_card(
38    factory: &dyn Factory,
39    spec: OperationSpec,
40    args_shape: Value,
41    result_shape: Value,
42) -> Result<Value> {
43    let subject = Ref::Symbol(spec.symbol());
44    let entries = vec![
45        (field("subject"), factory.symbol(spec.symbol())?),
46        (
47            field("kind"),
48            factory.symbol(Symbol::qualified("expr-tree", "operation"))?,
49        ),
50        (
51            field("help"),
52            factory.string(format!(
53                "expr-tree/{}: {}; result: {}",
54                spec.name, spec.args_detail, spec.result_detail
55            ))?,
56        ),
57        (field("args"), args_shape),
58        (field("result"), result_shape),
59        (field("tests"), factory.list(Vec::new())?),
60        (
61            field("ops"),
62            factory.list(vec![factory.symbol(spec.symbol())?])?,
63        ),
64        (
65            field("requires"),
66            factory.list(vec![factory.symbol(Symbol::qualified(
67                "capability",
68                spec.capability.name().as_str(),
69            ))?])?,
70        ),
71        (field("see-also"), factory.list(Vec::new())?),
72        (field("shape-known"), factory.bool(true)?),
73    ];
74    factory.opaque(Arc::new(Card::new(subject, entries)))
75}
76
77fn field(name: &str) -> Symbol {
78    Symbol::new(name.to_owned())
79}