scratch_test_value/conversions/
from_components.rs1#[cfg(feature = "serde_json")]
2use crate::SNumber;
3use crate::{ARc, SValue};
4
5impl std::str::FromStr for SValue {
6 type Err = std::convert::Infallible;
7 fn from_str(s: &str) -> Result<Self, Self::Err> {
8 Ok(if let Ok(int) = s.parse() {
9 Self::Int(int)
10 } else if let Ok(float) = s.parse() {
11 if s.contains(".") || float < (i64::MIN as f64) || (i64::MAX as f64) < float {
12 Self::Float(float)
13 } else if let Ok(int) = s.parse() {
14 Self::Int(int)
15 } else {
16 Self::Text(s.into())
17 }
18 } else if s == "true" {
19 Self::Bool(true)
20 } else if s == "false" {
21 Self::Bool(false)
22 } else {
23 Self::Text(s.into())
24 })
25 }
26}
27
28impl From<String> for SValue {
29 fn from(value: String) -> Self {
30 Self::Text(value.into())
31 }
32}
33
34impl<'a> From<&'a str> for SValue {
35 fn from(value: &'a str) -> Self {
36 Self::Text(value.into())
37 }
38}
39
40impl From<ARc<str>> for SValue {
41 fn from(value: ARc<str>) -> Self {
42 Self::Text(value)
43 }
44}
45impl From<i64> for SValue {
46 fn from(value: i64) -> Self {
47 Self::Int(value)
48 }
49}
50impl From<f64> for SValue {
51 fn from(value: f64) -> Self {
52 Self::Float(value)
53 }
54}
55
56#[cfg(feature = "serde_json")]
57impl From<serde_json::Number> for SValue {
58 fn from(value: serde_json::Number) -> SValue {
59 SNumber::from(value).into()
60 }
61}
62#[cfg(feature = "serde_json")]
63impl From<serde_json::Number> for SNumber {
64 fn from(value: serde_json::Number) -> SNumber {
65 if let Some(n) = value.as_f64() {
66 Self::Float(n)
67 } else if let Some(n) = value.as_i64() {
68 Self::Int(n)
69 } else if let Some(n) = value.as_u64() {
70 if let Ok(i) = n.try_into() {
71 Self::Int(i)
72 } else {
73 Self::Float(n as f64)
74 }
75 } else {
76 Self::Int(0)
77 }
78 }
79}
80
81#[cfg(feature = "serde_json")]
82#[derive(Debug, PartialEq, Eq, Clone, thiserror::Error)]
83#[error("json value can't be converted into Scratch value (object/array?): {0}")]
84pub struct JsonValueNoSValue(pub serde_json::Value);
85
86#[cfg(feature = "serde_json")]
87impl TryFrom<serde_json::Value> for SValue {
88 type Error = JsonValueNoSValue;
89
90 fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
91 let initial = if let Some(num) = value.as_number() {
92 SValue::from(num.clone())
94 } else if let Some(boo) = value.as_bool() {
95 SValue::Bool(boo)
96 } else if let Some(tex) = value.as_str() {
97 SValue::Text(tex.into())
98 } else {
99 return Err(JsonValueNoSValue(value));
100 };
101 Ok(initial)
102 }
103}