Skip to main content

scratch_test_model/attrs/
mod.rs

1mod broadcast_id;
2mod color;
3pub(crate) mod data;
4pub mod dropdowns;
5mod expression;
6mod string_helper;
7
8pub use crate::aux::do_for_attrs::{DoForAttrs, DoForAttrsStrategy};
9pub use color::Color;
10
11pub use data::{DataId, List, ListKind, Variable, VariableKind};
12
13pub use dropdowns::{AnyDropdownOf, DirectDropdownOf, DropdownMenuOf};
14
15pub use crate::scopes::block_wrapper::Position;
16
17use either::Either;
18pub use expression::Expression;
19pub(crate) use string_helper::StringAtArrayPosZero;
20
21pub use broadcast_id::BroadcastId;
22
23use crate::attrs::string_helper::OnlyString;
24pub use crate::aux::errors::{AttributeContentError, AttributeParseError};
25pub(crate) use crate::aux::parse_attr::ParseJsonBlockAttribute;
26
27pub use dropdowns::{ExpressionRef, RoundDirectDropdownOf, RoundDropdownMenuOf};
28
29#[derive(Debug, PartialEq, Clone, derive_more::Deref)]
30pub struct ArgumentReporterName(StringAtArrayPosZero);
31
32impl ParseJsonBlockAttribute for ArgumentReporterName {
33    fn parse_json_block_attr_without_expecting_shadow<'a>(
34        all_target_blocks: crate::_exports::JsonBlocks<'a>,
35        attribute_value: &'a serde_json::Value,
36    ) -> Result<Self, crate::aux::errors::AttributeContentError<'a>>
37    where
38        Self: Sized,
39    {
40        StringAtArrayPosZero::parse_json_block_attr_without_expecting_shadow(
41            all_target_blocks,
42            attribute_value,
43        )
44        .map(Self)
45    }
46}
47
48impl<FirstTry, SecondTry> ParseJsonBlockAttribute for Either<FirstTry, SecondTry>
49where
50    FirstTry: ParseJsonBlockAttribute,
51    SecondTry: ParseJsonBlockAttribute,
52{
53    fn parse_json_block_attr_without_expecting_shadow<'a>(
54        all_target_blocks: crate::_exports::JsonBlocks<'a>,
55        attribute_value: &'a serde_json::Value,
56    ) -> Result<Self, crate::aux::errors::AttributeContentError<'a>>
57    where
58        Self: Sized,
59    {
60        let first = FirstTry::parse_json_block_attr_without_expecting_shadow(
61            all_target_blocks,
62            attribute_value,
63        )
64        .map(Self::Left);
65        match first {
66            Ok(f) => Ok(f),
67            Err(first_err) => {
68                let second = SecondTry::parse_json_block_attr_without_expecting_shadow(
69                    all_target_blocks,
70                    attribute_value,
71                )
72                .map(Self::Right);
73                second.map_err(|second_err| AttributeContentError::BothEitherFailed {
74                    first_err: Box::new(first_err),
75                    second_err: Box::new(second_err),
76                })
77            }
78        }
79    }
80}
81
82#[derive(derive_more::Debug, PartialEq, Clone)]
83#[debug("RefBlock({id:?})")]
84pub struct RefBlock<T> {
85    id: crate::Id,
86    phantom: std::marker::PhantomData<T>,
87}
88impl<T> RefBlock<T> {
89    pub fn o_id(&self) -> crate::Id {
90        self.id.clone()
91    }
92    pub fn id(&self) -> &crate::Id {
93        &self.id
94    }
95}
96
97impl<T> ParseJsonBlockAttribute for RefBlock<T> {
98    fn parse_json_block_attr_without_expecting_shadow<'a>(
99        all_target_blocks: crate::_exports::JsonBlocks<'a>,
100        attribute_value: &'a serde_json::Value,
101    ) -> Result<Self, crate::aux::errors::AttributeContentError<'a>>
102    where
103        Self: Sized,
104    {
105        let value = OnlyString::parse_json_block_attr_without_expecting_shadow(
106            all_target_blocks,
107            attribute_value,
108        );
109        value.map(|value: OnlyString| RefBlock {
110            id: value.take().into(),
111            phantom: std::marker::PhantomData,
112        })
113    }
114}
115
116#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
117pub struct ProcedureArgumentId(pub(crate) crate::Id);
118
119impl ProcedureArgumentId {
120    // not a block id but similar pattern
121    pub fn id(&self) -> &svalue::ARc<str> {
122        &self.0
123    }
124}
125
126impl ParseJsonBlockAttribute for ProcedureArgumentId {
127    fn parse_json_block_attr_without_expecting_shadow<'a>(
128        all_target_blocks: crate::_exports::JsonBlocks<'a>,
129        attribute_value: &'a serde_json::Value,
130    ) -> Result<Self, crate::aux::errors::AttributeContentError<'a>>
131    where
132        Self: Sized,
133    {
134        let value = OnlyString::parse_json_block_attr_without_expecting_shadow(
135            all_target_blocks,
136            attribute_value,
137        );
138        value.map(|value: OnlyString| ProcedureArgumentId(value.take().into()))
139    }
140}
141
142pub type KeyboardKey = svalue::ARc<str>;
143
144/// A field that has type `Option<T>` can be missing from the attribute
145/// set. In this case, the parsed value will be `None`.
146/// Otherwise `T`s parser will continue.
147///
148/// This also includes that the value could be the JSON `null`.
149impl<T: ParseJsonBlockAttribute> ParseJsonBlockAttribute for Option<T> {
150    fn mandatory_attr_missing_fallback(
151        _all_target_blocks: crate::aux::JsonBlocks<'_>,
152        _location: crate::aux::AttrLocation,
153        _key: &'static str,
154    ) -> Option<Self>
155    where
156        Self: Sized,
157    {
158        Some(None)
159    }
160
161    fn parse_json_block_attr_without_expecting_shadow<'a>(
162        all_target_blocks: crate::_exports::JsonBlocks<'a>,
163        attribute_value: &'a serde_json::Value,
164    ) -> Result<Self, crate::aux::errors::AttributeContentError<'a>>
165    where
166        Self: Sized,
167    {
168        if attribute_value.is_null() {
169            return Ok(None);
170        }
171        T::parse_json_block_attr_without_expecting_shadow(all_target_blocks, attribute_value)
172            .map(Some)
173    }
174}