Skip to main content

scratch_test_model/attrs/
expression.rs

1use crate::{
2    attrs::{List, Variable},
3    aux::constants,
4    blocks::ExprOrCmpBlockKind,
5};
6use svalue::SValue;
7
8use crate::attrs::{ParseJsonBlockAttribute, RefBlock};
9
10#[derive(Debug, PartialEq, Clone)]
11pub enum Expression {
12    Var(Variable),
13    Blo(RefBlock<ExprOrCmpBlockKind>),
14    Lit(SValue),
15    Lis(List),
16}
17
18impl ParseJsonBlockAttribute for Expression {
19    fn parse_json_block_attr_without_expecting_shadow<'a>(
20        all_target_blocks: crate::_exports::JsonBlocks<'a>,
21        attribute_value: &'a serde_json::Value,
22    ) -> Result<Self, crate::aux::errors::AttributeContentError<'a>>
23    where
24        Self: Sized,
25    {
26        if let Some(array) = attribute_value.as_array() {
27            if let Some(code) = array.first().and_then(|x| x.as_u64()) {
28                if (constants::MATH_NUM_PRIMITIVE == code
29                    || constants::INTEGER_NUM_PRIMITIVE == code
30                    || constants::POSITIVE_NUM_PRIMITIVE == code
31                    || constants::WHOLE_NUM_PRIMITIVE == code
32                    || constants::ANGLE_NUM_PRIMITIVE == code)
33                    && let Some(value) = array.get(1)
34                {
35                    if let Some(number) = value.as_number() {
36                        return Ok(Expression::Lit(number.clone().into()));
37                    } else if let Some(string) = value.as_str() {
38                        return Ok(Expression::Lit(SValue::Text(string.into())));
39                    }
40                }
41                if constants::TEXT_PRIMITIVE == code
42                    && let Some(arr) = array.get(1)
43                    && let Some(value) = arr
44                        .as_str()
45                        .map(|s| s.to_string())
46                        .or_else(|| arr.as_number().map(|s| s.to_string()))
47                        .or_else(|| arr.as_bool().map(|s| s.to_string()))
48                {
49                    return Ok(Expression::Lit(SValue::Text(value.into())));
50                }
51                if constants::VAR_PRIMITIVE == code {
52                    return Variable::parse_json_block_attr_without_expecting_shadow(
53                        all_target_blocks,
54                        attribute_value,
55                    )
56                    .map(Expression::Var);
57                }
58                if constants::LIST_PRIMITIVE == code {
59                    return List::parse_json_block_attr_without_expecting_shadow(
60                        all_target_blocks,
61                        attribute_value,
62                    )
63                    .map(Expression::Lis);
64                }
65            }
66            Err(crate::aux::errors::AttributeContentError::Other(
67                "invalid value for expression",
68            ))
69        } else if attribute_value.as_str().is_some() {
70            RefBlock::parse_json_block_attr_without_expecting_shadow(
71                all_target_blocks,
72                attribute_value,
73            )
74            .map(Self::Blo)
75        } else {
76            Err(super::AttributeContentError::ExpectedArray {
77                value: attribute_value,
78                specified_length: None,
79            })
80        }
81    }
82}