alox_48/value/
from.rs

1// Copyright (c) 2024 Lily Lyons
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
7use crate::Instance;
8
9use super::{Object, RbHash, RbString, Symbol, Userdata, Value};
10
11impl Value {
12    /// Convert a symbol into a value.
13    #[must_use]
14    pub fn from_symbol(symbol: String) -> Self {
15        Self::Symbol(symbol.into())
16    }
17}
18
19impl<T> From<Option<T>> for Value
20where
21    T: Into<Value>,
22{
23    fn from(value: Option<T>) -> Self {
24        match value {
25            Some(v) => v.into(),
26            None => Self::Nil,
27        }
28    }
29}
30
31impl From<String> for Value {
32    fn from(value: String) -> Self {
33        // FIXME should these use instance?
34        Value::String(RbString {
35            data: value.into_bytes(),
36        })
37    }
38}
39
40impl From<&str> for Value {
41    fn from(value: &str) -> Self {
42        Value::String(RbString {
43            data: value.to_string().into_bytes(),
44        })
45    }
46}
47
48impl From<RbString> for Value {
49    fn from(value: RbString) -> Self {
50        Self::String(value)
51    }
52}
53
54impl From<Symbol> for Value {
55    fn from(value: Symbol) -> Self {
56        Self::Symbol(value)
57    }
58}
59
60impl From<bool> for Value {
61    fn from(value: bool) -> Self {
62        Self::Bool(value)
63    }
64}
65
66impl From<f64> for Value {
67    fn from(value: f64) -> Self {
68        Self::Float(value)
69    }
70}
71
72impl From<i32> for Value {
73    fn from(value: i32) -> Self {
74        Self::Integer(value)
75    }
76}
77
78impl From<RbHash> for Value {
79    fn from(value: RbHash) -> Self {
80        Self::Hash(value)
81    }
82}
83
84impl<T> From<Vec<T>> for Value
85where
86    T: Into<Value>,
87{
88    fn from(value: Vec<T>) -> Self {
89        Self::Array(value.into_iter().map(Into::into).collect())
90    }
91}
92
93impl TryInto<String> for Value {
94    type Error = Self;
95
96    fn try_into(self) -> Result<String, Self::Error> {
97        self.into_string()
98            .map(|str| str.to_string_lossy().into_owned())
99    }
100}
101
102impl TryInto<RbString> for Value {
103    type Error = Self;
104
105    fn try_into(self) -> Result<RbString, Self::Error> {
106        self.into_string()
107    }
108}
109
110impl TryInto<i32> for Value {
111    type Error = Self;
112
113    fn try_into(self) -> Result<i32, Self::Error> {
114        self.into_integer()
115    }
116}
117
118impl TryInto<f64> for Value {
119    type Error = Self;
120
121    fn try_into(self) -> Result<f64, Self::Error> {
122        self.into_float()
123    }
124}
125
126impl TryInto<Object> for Value {
127    type Error = Self;
128
129    fn try_into(self) -> Result<Object, Self::Error> {
130        self.into_object()
131    }
132}
133
134impl TryInto<Userdata> for Value {
135    type Error = Self;
136
137    fn try_into(self) -> Result<Userdata, Self::Error> {
138        self.into_userdata()
139    }
140}
141
142impl From<Value> for bool {
143    fn from(value: Value) -> Self {
144        match value {
145            Value::Nil => false,
146            Value::Bool(b) => b,
147            _ => true,
148        }
149    }
150}
151
152impl<T> From<Instance<T>> for Value
153where
154    T: Into<Value>,
155{
156    fn from(instance: Instance<T>) -> Self {
157        let value = Box::new(instance.value.into());
158        Value::Instance(Instance {
159            value,
160            fields: instance.fields,
161        })
162    }
163}