scratch_test_model/attrs/
data.rs1use 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}