yarnspinner_core/
internal_value.rs

1//! Adapted from <https://github.com/YarnSpinnerTool/YarnSpinner/blob/da39c7195107d8211f21c263e4084f773b84eaff/YarnSpinner/Value.cs>
2
3use crate::prelude::*;
4use crate::types::{Type, TypedValue as _};
5
6/// A value as it appears to the compiler. It has additional type checker information
7/// and may represent values not constructable by the user, like functions.
8///
9/// As a consumer, you should not be facing this type.
10///
11/// ## Implementation Notes
12///
13/// Corresponds to the internal `Value` class in the original C# implementation.
14#[derive(Debug, Clone, PartialEq)]
15#[cfg_attr(feature = "bevy", derive(Reflect))]
16#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
17#[cfg_attr(feature = "bevy", reflect(Debug, PartialEq))]
18#[cfg_attr(
19    all(feature = "bevy", feature = "serde"),
20    reflect(Serialize, Deserialize)
21)]
22pub struct InternalValue {
23    /// The proper Yarn type of this value according to the type checker.
24    pub r#type: Type,
25    /// The actual value. If [`InternalValue::type`] is [`Type::Function`], this is the return type.
26    pub raw_value: YarnValue,
27}
28
29macro_rules! impl_from {
30    ($($from_type:ty,)*) => {
31        $(
32            impl From<$from_type> for InternalValue {
33                fn from(value: $from_type) -> Self {
34                    Self {
35                        r#type: value.r#type(),
36                        raw_value: value.into(),
37                    }
38                }
39            }
40
41            impl TryFrom<InternalValue> for $from_type {
42                type Error = YarnValueCastError;
43
44                fn try_from(value: InternalValue) -> Result<Self, Self::Error> {
45                    value.raw_value.try_into()
46                }
47            }
48
49        )*
50    };
51}
52
53impl<T> From<&T> for InternalValue
54where
55    T: Copy,
56    InternalValue: From<T>,
57{
58    fn from(value: &T) -> Self {
59        Self::from(*value)
60    }
61}
62
63impl_from![
64    bool, f32, f64, i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, usize, isize,
65];
66
67// The macro above doesn't work for &str because it's trying to work with &&str
68
69impl From<&str> for InternalValue {
70    fn from(value: &str) -> Self {
71        Self {
72            r#type: value.r#type(),
73            raw_value: value.into(),
74        }
75    }
76}
77
78impl From<String> for InternalValue {
79    fn from(value: String) -> Self {
80        Self {
81            r#type: value.r#type(),
82            raw_value: value.into(),
83        }
84    }
85}
86
87impl From<InternalValue> for String {
88    fn from(value: InternalValue) -> Self {
89        value.raw_value.into()
90    }
91}
92
93impl From<YarnValue> for InternalValue {
94    fn from(value: YarnValue) -> Self {
95        Self {
96            r#type: value.r#type(),
97            raw_value: value,
98        }
99    }
100}
101
102impl From<InternalValue> for YarnValue {
103    fn from(value: InternalValue) -> Self {
104        value.raw_value
105    }
106}
107
108impl AsRef<YarnValue> for InternalValue {
109    fn as_ref(&self) -> &YarnValue {
110        &self.raw_value
111    }
112}
113
114impl AsMut<YarnValue> for InternalValue {
115    fn as_mut(&mut self) -> &mut YarnValue {
116        &mut self.raw_value
117    }
118}