Skip to main content

scratch_test_model/attrs/
data.rs

1use crate::{
2    Id,
3    attrs::{AttributeContentError, ParseJsonBlockAttribute},
4    aux::constants,
5};
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, derive_getters::Getters)]
8#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
9#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct DataId<Kind> {
12    #[cfg_attr(feature = "utoipa", schema(ignore))]
13    kind: std::marker::PhantomData<Kind>,
14    name: String,
15    #[cfg_attr(feature = "utoipa", schema(value_type=String))]
16    id: Id,
17}
18impl<K> DataId<K> {
19    pub fn new(name: String, id: Id) -> Self {
20        Self {
21            kind: std::marker::PhantomData {},
22            name,
23            id,
24        }
25    }
26}
27
28#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
29#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
30#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32pub struct VariableKind;
33#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
34#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
35#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
36#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
37pub struct ListKind;
38
39pub type List = DataId<ListKind>;
40pub type Variable = DataId<VariableKind>;
41
42impl<Kind> ParseJsonBlockAttribute for DataId<Kind> {
43    fn parse_json_block_attr_without_expecting_shadow<'a>(
44        _all_target_blocks: crate::_exports::JsonBlocks<'a>,
45        attribute_value: &'a serde_json::Value,
46    ) -> Result<Self, crate::aux::errors::AttributeContentError<'a>>
47    where
48        Self: Sized,
49    {
50        if let Some(array) = attribute_value.as_array()
51            && array.len() == 2
52        {
53            Self::parse_at_offset(array, 0)
54        } else if let Some(array) = attribute_value.as_array()
55            && array.len() == 3
56            && let Some(constants::VAR_PRIMITIVE | constants::LIST_PRIMITIVE) =
57                array.first().and_then(|a| a.as_u64())
58        {
59            Self::parse_at_offset(array, 1)
60        } else {
61            Err(AttributeContentError::ExpectedArray {
62                value: attribute_value,
63                specified_length: Some(2),
64            })
65        }
66    }
67}
68
69impl<Kind> DataId<Kind> {
70    fn parse_at_offset<'a>(
71        array: &'a [serde_json::Value],
72        offset: usize,
73    ) -> Result<Self, crate::aux::errors::AttributeContentError<'a>> {
74        if let Some(name) = array.get(offset).and_then(|a| a.as_str())
75            && let Some(id) = array.get(1 + offset).and_then(|a| a.as_str())
76        {
77            Ok(Self {
78                id: id.into(),
79                name: name.into(),
80                kind: std::marker::PhantomData,
81            })
82        } else {
83            Err(AttributeContentError::Other(
84                "expected array with two strings for data (list/var) reference",
85            ))
86        }
87    }
88}