sb3_decoder/structs/block/
input.rs1use std::collections::HashMap;
4
5use crate::{decoder::{RawBlock, RawBlockInput}, error::DecodeError, structs::{Block, Value}};
6
7#[derive(Debug, Clone, PartialEq)]
9pub enum InputValue {
10 Literal(Value),
12
13 Color(u8, u8, u8),
15
16 Broadcast(String),
18
19 Variable(String),
21
22 List(String),
24
25 Block(Box<Block>),
27}
28
29#[derive(Debug, Clone, PartialEq)]
33pub struct BlockInput {
34 pub shadow: bool,
36
37 pub value: InputValue,
39}
40
41impl BlockInput {
42 pub fn new(raw: RawBlockInput, blocks: &HashMap<String, RawBlock>) -> Result<Self, DecodeError> {
45 let shadow = match raw.shadow {
46 1 | 3 => true,
47 2 => false,
48 _ => unreachable!("Invalid shadow value: {}", raw.shadow),
49 };
50
51 let value = match raw.kind {
52 0 => {
53 let block_id = raw
55 .value
56 .as_str()
57 .ok_or_else(|| DecodeError::InvalidData("Expected a string".to_string()))?;
58 InputValue::Block(Box::new(Block::new(block_id, blocks)?))
59 }
60 4..=8 => {
61 InputValue::Literal(Value::from(raw.value.clone()))
63 }
64 9 => {
65 let hex_str = raw
67 .value
68 .as_str()
69 .ok_or_else(|| DecodeError::InvalidData("Expected a string".to_string()))?;
70 if !hex_str.starts_with('#') || hex_str.len() != 7 {
71 return Err(DecodeError::InvalidData(format!(
72 "Invalid hex color string: {}",
73 hex_str
74 )));
75 }
76 let r = u8::from_str_radix(&hex_str[1..3], 16).map_err(|_| {
77 DecodeError::InvalidData(format!("Invalid red component in hex color: {}", hex_str))
78 })?;
79 let g = u8::from_str_radix(&hex_str[3..5], 16).map_err(|_| {
80 DecodeError::InvalidData(format!("Invalid green component in hex color: {}", hex_str))
81 })?;
82 let b = u8::from_str_radix(&hex_str[5..7], 16).map_err(|_| {
83 DecodeError::InvalidData(format!("Invalid blue component in hex color: {}", hex_str))
84 })?;
85 InputValue::Color(r, g, b)
86 }
87 10 => {
88 let string = raw
90 .value
91 .as_str()
92 .ok_or_else(|| DecodeError::InvalidData("Expected a string".to_string()))?;
93 InputValue::Literal(Value::String(string.to_string()))
94 }
95 11 => {
96 let broadcast_name = raw
98 .value
99 .as_str()
100 .ok_or_else(|| DecodeError::InvalidData("Expected a string".to_string()))?;
101 InputValue::Broadcast(broadcast_name.to_string())
102 }
103 12 => {
104 let var_name = raw
106 .value
107 .as_str()
108 .ok_or_else(|| DecodeError::InvalidData("Expected a string".to_string()))?;
109 InputValue::Variable(var_name.to_string())
110 }
111 13 => {
112 let list_name = raw
114 .value
115 .as_str()
116 .ok_or_else(|| DecodeError::InvalidData("Expected a string".to_string()))?;
117 InputValue::List(list_name.to_string())
118 }
119 _ => {
120 return Err(DecodeError::InvalidData(format!(
121 "Unknown kind value: {}",
122 raw.kind
123 )))
124 }
125 };
126
127 Ok(BlockInput { shadow, value })
128 }
129}