sim_lib_expr_tree/
projection.rs1use 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
10pub 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}