1use crate::prelude::*;
4use serde_tuple::{Deserialize_tuple, Serialize_tuple};
5use utils::{deserialize_json_str, serialize_json_str};
6
7#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
9#[serde(rename_all = "camelCase")]
10pub struct BlockNormal {
11 pub opcode: OpCode,
13
14 #[serde(default, skip_serializing_if = "Option::is_none")]
16 pub comment: Option<Uid>,
17
18 pub next: Option<Uid>,
20
21 pub parent: Option<Uid>,
26
27 pub inputs: StringHashMap<BlockInput>,
29
30 pub fields: StringHashMap<BlockField>,
32
33 pub shadow: bool,
35
36 pub top_level: bool,
38
39 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub mutation: Option<BlockMutation>,
43
44 #[serde(skip_serializing_if = "Option::is_none", default)]
46 pub x: Option<Number>,
47
48 #[serde(skip_serializing_if = "Option::is_none", default)]
50 pub y: Option<Number>,
51}
52
53#[derive(Debug, PartialEq, Clone, Deserialize_tuple, Serialize_tuple)]
55pub struct BlockVarListReporterTop {
56 pub kind: ListOrVariable,
57 pub name: Name,
59 pub id: Uid,
61 pub x: Number,
63 pub y: Number,
65}
66
67#[derive(Debug, PartialEq, Clone)]
68pub enum ListOrVariable {
69 Variable,
70 List,
71}
72
73#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
74#[serde(untagged)]
75pub enum Block {
76 Normal(BlockNormal),
77 VarList(BlockVarListReporterTop),
78}
79
80#[derive(Debug, Default, Clone, PartialEq)]
83pub struct BlockInput {
84 pub shadow: ShadowInputType,
86
87 pub inputs: Vec<Option<UidOrValue>>,
89}
90
91#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
94#[serde(untagged)]
95pub enum UidOrValue {
96 Uid(Uid),
98 Value(BlockInputValue),
100}
101
102#[derive(Debug, Clone, PartialEq)]
104pub enum BlockField {
105 WithId {
107 value: Value,
109
110 id: Option<Uid>,
114 },
115 NoId {
117 value: Value,
119 },
120}
121
122#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
124#[serde(rename_all = "camelCase")]
125pub struct BlockMutation {
126 pub tag_name: String,
130
131 pub children: Vec<Json>,
133
134 #[serde(flatten)]
136 pub mutation_enum: BlockMutationEnum,
137}
138
139#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
142#[serde(untagged)]
143pub enum BlockMutationEnum {
144 ProceduresPrototype {
146 proccode: String,
148
149 #[serde(
151 deserialize_with = "deserialize_json_str",
152 serialize_with = "serialize_json_str"
153 )]
154 argumentids: Vec<Uid>,
155
156 #[serde(
158 deserialize_with = "deserialize_json_str",
159 serialize_with = "serialize_json_str"
160 )]
161 argumentnames: Vec<Name>,
162
163 #[serde(
167 deserialize_with = "deserialize_json_str",
168 serialize_with = "serialize_json_str"
169 )]
170 argumentdefaults: Vec<ValueWithBool>,
171
172 #[serde(
174 deserialize_with = "deserialize_json_str",
175 serialize_with = "serialize_json_str"
176 )]
177 warp: Option<bool>,
178 },
179
180 ProceduresCall {
182 proccode: String,
184
185 #[serde(
187 deserialize_with = "deserialize_json_str",
188 serialize_with = "serialize_json_str"
189 )]
190 argumentids: Vec<Uid>,
191
192 #[serde(
194 deserialize_with = "deserialize_json_str",
195 serialize_with = "serialize_json_str"
196 )]
197 warp: Option<bool>,
198 },
199
200 ControlStop {
202 #[serde(
206 deserialize_with = "deserialize_json_str",
207 serialize_with = "serialize_json_str"
208 )]
209 hasnext: bool,
210 },
211}
212
213#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize_repr, Serialize_repr)]
225#[repr(u8)]
226pub enum ShadowInputType {
227 Shadow = 1,
229
230 #[default]
232 NoShadow = 2,
233
234 ShadowObscured = 3,
237}
238
239#[derive(Debug, Clone, PartialEq)]
241pub enum BlockInputValue {
242 Number {
244 value: Value,
246 },
247
248 PositiveNumber {
250 value: Value,
252 },
253
254 PositiveInteger {
256 value: Value,
258 },
259
260 Integer {
262 value: Value,
264 },
265
266 Angle {
268 value: Value,
270 },
271
272 Color {
274 value: Value,
276 },
277
278 String {
280 value: Value,
282 },
283
284 Broadcast {
286 name: Name,
288
289 id: Uid,
291 },
292
293 Variable {
295 name: Name,
297 id: Uid,
299 },
300
301 List {
303 name: Name,
305 id: Uid,
307 },
308}
309
310impl Default for BlockNormal {
311 fn default() -> Self {
313 BlockNormal {
314 opcode: OpCode::default(),
315 comment: None,
316 next: None,
317 parent: None,
318 inputs: StringHashMap::default(),
319 fields: StringHashMap::default(),
320 shadow: false,
321 top_level: true,
322 mutation: None,
323 x: Some(0.into()),
324 y: Some(0.into()),
325 }
326 }
327}
328
329macro_rules! list_or_variable_vistor_types {
332 ($($fn_name:ident, $ty:ty, $sign:ident, $unexpty:ty;)*) => {
333 $(
334 fn $fn_name<E>(self, v: $ty) -> Result<Self::Value, E>
335 where
336 E: serde::de::Error,
337 {
338 match v {
339 12 => Ok(ListOrVariable::Variable),
340 13 => Ok(ListOrVariable::List),
341 v => Err(E::invalid_value(
342 Unexpected::$sign(v as $unexpty),
343 &"12 for variable, 13 for list",
344 )),
345 }
346 }
347 )*
348 };
349}
350
351struct ListOrVariableVisitor;
352
353impl<'de> Visitor<'de> for ListOrVariableVisitor {
354 type Value = ListOrVariable;
355
356 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
357 formatter.write_str("12 for variable, 13 for list")
358 }
359
360 list_or_variable_vistor_types! {
361 visit_i8, i8, Signed, i64;
362 visit_i16, i16, Signed, i64;
363 visit_i32, i32, Signed, i64;
364 visit_i64, i64, Signed, i64;
365
366 visit_u8, u8, Unsigned, u64;
367 visit_u16, u16, Unsigned, u64;
368 visit_u32, u32, Unsigned, u64;
369 visit_u64, u64, Unsigned, u64;
370 }
371}
372
373impl<'de> Deserialize<'de> for ListOrVariable {
374 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
375 where
376 D: Deserializer<'de>,
377 {
378 deserializer.deserialize_i64(ListOrVariableVisitor)
379 }
380}
381
382impl Serialize for ListOrVariable {
383 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
384 where
385 S: Serializer,
386 {
387 serializer.serialize_i64(match self {
388 ListOrVariable::Variable => 12,
389 ListOrVariable::List => 13,
390 })
391 }
392}
393
394impl BlockInput {
395 fn size_hint(&self) -> usize {
397 1 + self.inputs.len()
398 }
399}
400
401struct BlockInputVisitor;
402
403impl<'de> Visitor<'de> for BlockInputVisitor {
404 type Value = BlockInput;
405
406 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
407 formatter.write_str("list that is a block input")
408 }
409
410 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
411 where
412 A: serde::de::SeqAccess<'de>,
413 {
414 use serde::de::Error;
415
416 let shadow = seq.next_element::<ShadowInputType>()?.ok_or_else(|| {
417 A::Error::invalid_length(0, &"Expected 2 or more elements for block input")
418 })?;
419
420 let mut inputs = vec![];
421 while let Some(v) = seq.next_element::<Option<UidOrValue>>()? {
422 inputs.push(v)
423 }
424
425 Ok(BlockInput { shadow, inputs })
426 }
427}
428
429impl<'de> Deserialize<'de> for BlockInput {
430 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
431 where
432 D: Deserializer<'de>,
433 {
434 deserializer.deserialize_seq(BlockInputVisitor)
435 }
436}
437
438impl Serialize for BlockInput {
439 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
440 where
441 S: Serializer,
442 {
443 use serde::ser::SerializeSeq;
444 let mut s = serializer.serialize_seq(Some(self.size_hint()))?;
445 s.serialize_element(&self.shadow)?;
446 for v in &self.inputs {
447 s.serialize_element(&v)?;
448 }
449 s.end()
450 }
451}
452
453impl BlockInputValue {
454 fn get_id(&self) -> u8 {
455 use BlockInputValue::*;
456
457 match self {
458 Number { value: _ } => 4,
459 PositiveNumber { value: _ } => 5,
460 PositiveInteger { value: _ } => 6,
461 Integer { value: _ } => 7,
462 Angle { value: _ } => 8,
463 Color { value: _ } => 9,
464 String { value: _ } => 10,
465 Broadcast { name: _, id: _ } => 11,
466 Variable { name: _, id: _ } => 12,
467 List { name: _, id: _ } => 13,
468 }
469 }
470
471 fn hint_size(&self) -> usize {
472 use BlockInputValue::*;
473
474 match self {
475 Number { value: _ } => 1,
476 PositiveNumber { value: _ } => 1,
477 PositiveInteger { value: _ } => 1,
478 Integer { value: _ } => 1,
479 Angle { value: _ } => 1,
480 Color { value: _ } => 1,
481 String { value: _ } => 1,
482 Broadcast { name: _, id: _ } => 2,
483 Variable { name: _, id: _ } => 2,
484 List { name: _, id: _ } => 2,
485 }
486 }
487}
488
489struct BlockInputValueVisitor;
490
491impl<'de> Visitor<'de> for BlockInputValueVisitor {
492 type Value = BlockInputValue;
493
494 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
495 formatter.write_str("list that is a block input value")
496 }
497
498 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
499 where
500 A: serde::de::SeqAccess<'de>,
501 {
502 use serde::de::Error;
503 use BlockInputValue::{
504 Angle, Broadcast, Color, Integer, List, Number as BlockInputNumber, PositiveInteger,
505 PositiveNumber, String, Variable,
506 };
507
508 fn seq_next_element_error<'de, T, A>(
509 seq: &mut A,
510 len: usize,
511 error: &str,
512 ) -> Result<T, A::Error>
513 where
514 A: serde::de::SeqAccess<'de>,
515 T: Deserialize<'de>,
516 {
517 seq.next_element::<T>()?
518 .ok_or_else(|| A::Error::invalid_length(len, &error))
519 }
520
521 let vtype: u8 = seq_next_element_error(
522 &mut seq,
523 0,
524 "Expecting 2 or more elements for block input value with any Id",
525 )?;
526
527 let value = seq_next_element_error(
528 &mut seq,
529 1,
530 "Expecting 2 or more elements for block input value with any Id",
531 )?;
532
533 let res = match vtype {
534 4 => BlockInputNumber { value },
535 5 => PositiveNumber { value },
536 6 => PositiveInteger { value },
537 7 => Integer { value },
538 8 => Angle { value },
539 9 => Color { value },
540 10 => String { value },
541 11 => {
542 let id = seq_next_element_error(
543 &mut seq,
544 3,
545 "Expecting 3 or more elements for block input value with Id 11",
546 )?;
547
548 let name = match value {
549 Value::Text(s) => s,
550 Value::Number(_) => {
551 return Err(A::Error::invalid_value(
552 serde::de::Unexpected::Other("number"),
553 &"a string",
554 ))
555 }
556 };
557
558 Broadcast { name, id }
559 }
560 12 => {
561 let id = seq_next_element_error(
562 &mut seq, 3,
563 "Expecting 3 or 5 or more elements for block input value with Id 12 - 13 inclusive"
564 )?;
565 let x = seq.next_element::<Number>()?;
566 let y = seq.next_element::<Number>()?;
567 let name = match value {
568 Value::Text(s) => s,
569 Value::Number(_) => {
570 return Err(A::Error::invalid_value(
571 serde::de::Unexpected::Other("number"),
572 &"a string",
573 ))
574 }
575 };
576 Variable { name, id }
577 }
578 13 => {
579 let id = seq_next_element_error(
580 &mut seq, 3,
581 "Expecting 3 or 5 or more elements for block input value with Id 12 - 13 inclusive"
582 )?;
583 let x = seq.next_element::<Number>()?;
584 let y = seq.next_element::<Number>()?;
585 let name = match value {
586 Value::Text(s) => s,
587 Value::Number(_) => {
588 return Err(A::Error::invalid_value(
589 serde::de::Unexpected::Other("number"),
590 &"a string",
591 ))
592 }
593 };
594 List { name, id }
595 }
596 v => {
597 return Err(A::Error::invalid_value(
598 serde::de::Unexpected::Unsigned(v.into()),
599 &"Expecting a type id between 4 - 13 inclusive",
600 ))
601 }
602 };
603
604 Ok(res)
605 }
606}
607
608impl<'de> Deserialize<'de> for BlockInputValue {
609 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
610 where
611 D: Deserializer<'de>,
612 {
613 deserializer.deserialize_seq(BlockInputValueVisitor)
614 }
615}
616
617impl Serialize for BlockInputValue {
618 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
619 where
620 S: Serializer,
621 {
622 use serde::ser::SerializeSeq;
623 use BlockInputValue::*;
624
625 let mut s = serializer.serialize_seq(Some(self.hint_size()))?;
626 s.serialize_element(&self.get_id())?;
627 match self {
628 Number { value }
629 | PositiveNumber { value }
630 | PositiveInteger { value }
631 | Integer { value }
632 | Angle { value }
633 | Color { value }
634 | String { value } => {
635 s.serialize_element(value)?;
636 }
637 Broadcast { name, id } => {
638 s.serialize_element(name)?;
639 s.serialize_element(id)?;
640 }
641 Variable { name, id } | List { name, id } => {
642 s.serialize_element(name)?;
643 s.serialize_element(id)?;
644 }
645 }
646 s.end()
647 }
648}
649
650impl BlockField {
651 #[inline(always)]
653 pub fn value(&self) -> &Value {
654 match self {
655 BlockField::WithId { value, id: _ } => value,
656 BlockField::NoId { value } => value,
657 }
658 }
659
660 #[inline(always)]
664 pub fn id(&self) -> Option<&Uid> {
665 match self {
666 BlockField::WithId { value: _, id } => id.as_ref(),
667 BlockField::NoId { value: _ } => None,
668 }
669 }
670}
671
672struct BlockFieldVisitor;
673
674impl<'de> Visitor<'de> for BlockFieldVisitor {
675 type Value = BlockField;
676
677 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
678 formatter.write_str("sequence of values that is a blockfield")
679 }
680
681 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
682 where
683 A: serde::de::SeqAccess<'de>,
684 {
685 use serde::de::Error;
686
687 let value = seq
688 .next_element::<Value>()?
689 .ok_or_else(|| A::Error::invalid_length(1, &"length 1 or 2 for BlockField"))?;
690 let id = seq.next_element::<Option<Uid>>()?;
691
692 Ok(match id {
693 Some(id) => BlockField::WithId { value, id },
694 None => BlockField::NoId { value },
695 })
696 }
697}
698
699impl<'de> Deserialize<'de> for BlockField {
700 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
701 where
702 D: Deserializer<'de>,
703 {
704 deserializer.deserialize_seq(BlockFieldVisitor)
705 }
706}
707
708impl Serialize for BlockField {
709 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
710 where
711 S: Serializer,
712 {
713 use serde::ser::SerializeSeq;
714
715 match self {
716 BlockField::WithId { value, id } => {
717 let mut seq = serializer.serialize_seq(Some(2))?;
718 seq.serialize_element(value)?;
719 seq.serialize_element(id)?;
720 seq.end()
721 }
722 BlockField::NoId { value } => {
723 let mut seq = serializer.serialize_seq(Some(1))?;
724 seq.serialize_element(value)?;
725 seq.end()
726 }
727 }
728 }
729}