sim_shape/primitives/combinators/
effectful.rs1use std::sync::Arc;
4
5use sim_kernel::{Cx, Expr, Result, ShapeId, Value, shape_is_subshape_of};
6
7use crate::base::{Shape, ShapeDoc, ShapeMatch};
8
9pub struct EffectfulShape {
15 inner: Arc<dyn Shape>,
16}
17
18impl EffectfulShape {
19 pub fn new(inner: Arc<dyn Shape>) -> Self {
21 Self { inner }
22 }
23
24 pub fn inner(&self) -> &Arc<dyn Shape> {
26 &self.inner
27 }
28}
29
30impl Shape for EffectfulShape {
31 fn id(&self) -> Option<ShapeId> {
32 None
33 }
34
35 fn is_effectful(&self) -> bool {
36 true
37 }
38
39 fn is_total(&self) -> bool {
40 self.inner.is_total()
41 }
42
43 fn is_subshape_of(&self, cx: &mut Cx, parent: &dyn Shape) -> Result<Option<bool>> {
44 let Some(parent) = parent.as_any().downcast_ref::<Self>() else {
45 return Ok(Some(false));
46 };
47 shape_is_subshape_of(cx, self.inner.as_ref(), parent.inner.as_ref()).map(Some)
48 }
49
50 fn check_value(&self, cx: &mut Cx, value: Value) -> Result<ShapeMatch> {
51 self.inner.check_value(cx, value)
52 }
53
54 fn check_expr(&self, cx: &mut Cx, expr: &Expr) -> Result<ShapeMatch> {
55 self.inner.check_expr(cx, expr)
56 }
57
58 fn describe(&self, cx: &mut Cx) -> Result<ShapeDoc> {
59 let inner = self.inner.describe(cx)?;
60 Ok(
61 ShapeDoc::new(format!("effectful {}", inner.name)).with_detail(
62 "effectful parse-time validation requires a trusted parser position".to_owned(),
63 ),
64 )
65 }
66}