uni_core/primitives/
to_string.rs1use crate::compat::ToString;
4use crate::interpreter::Interpreter;
5use crate::value::{RuntimeError, Value};
6
7pub fn to_string_builtin(interp: &mut Interpreter) -> Result<(), RuntimeError> {
10 let value = interp.pop()?;
11
12 let string_result = value.to_string();
14 interp.push(Value::String(string_result.into()));
15
16 Ok(())
17}
18
19#[cfg(test)]
20mod tests {
21 use super::*;
22 use crate::value::Value;
23
24 fn setup_interpreter() -> Interpreter {
25 Interpreter::new()
26 }
27
28 #[test]
29 fn test_to_string_builtin_number() {
30 let mut interp = setup_interpreter();
31
32 interp.push(Value::Number(42.0));
33 to_string_builtin(&mut interp).unwrap();
34
35 let result = interp.pop().unwrap();
36 assert!(matches!(result, Value::String(s) if s.as_ref() == "42"));
37 }
38
39 #[test]
40 fn test_to_string_builtin_negative_number() {
41 let mut interp = setup_interpreter();
42
43 interp.push(Value::Number(-3.14));
44 to_string_builtin(&mut interp).unwrap();
45
46 let result = interp.pop().unwrap();
47 assert!(matches!(result, Value::String(s) if s.as_ref() == "-3.14"));
48 }
49
50 #[test]
51 fn test_to_string_builtin_boolean() {
52 let mut interp = setup_interpreter();
53
54 interp.push(Value::Boolean(true));
55 to_string_builtin(&mut interp).unwrap();
56
57 let result = interp.pop().unwrap();
58 assert!(matches!(result, Value::String(s) if s.as_ref() == "true"));
59
60 interp.push(Value::Boolean(false));
61 to_string_builtin(&mut interp).unwrap();
62
63 let result = interp.pop().unwrap();
64 assert!(matches!(result, Value::String(s) if s.as_ref() == "false"));
65 }
66
67 #[test]
68 fn test_to_string_builtin_string() {
69 let mut interp = setup_interpreter();
70
71 interp.push(Value::String("hello".into()));
73 to_string_builtin(&mut interp).unwrap();
74
75 let result = interp.pop().unwrap();
76 assert!(matches!(result, Value::String(s) if s.as_ref() == "\"hello\""));
77 }
78
79 #[test]
80 fn test_to_string_builtin_atom() {
81 let mut interp = setup_interpreter();
82
83 let atom = interp.intern_atom("test");
84 interp.push(Value::Atom(atom));
85 to_string_builtin(&mut interp).unwrap();
86
87 let result = interp.pop().unwrap();
88 assert!(matches!(result, Value::String(s) if s.as_ref() == "test"));
89 }
90
91 #[test]
92 fn test_to_string_builtin_quoted_atom() {
93 let mut interp = setup_interpreter();
94
95 let quoted_atom = interp.intern_atom("quoted");
96 interp.push(Value::QuotedAtom(quoted_atom));
97 to_string_builtin(&mut interp).unwrap();
98
99 let result = interp.pop().unwrap();
100 assert!(matches!(result, Value::String(s) if s.as_ref() == "'quoted"));
101 }
102
103 #[test]
104 fn test_to_string_builtin_null() {
105 let mut interp = setup_interpreter();
106
107 interp.push(Value::Null);
108 to_string_builtin(&mut interp).unwrap();
109
110 let result = interp.pop().unwrap();
111 assert!(matches!(result, Value::String(s) if s.as_ref() == "null"));
112 }
113
114 #[test]
115 fn test_to_string_builtin_empty_list() {
116 let mut interp = setup_interpreter();
117
118 interp.push(Value::Nil);
119 to_string_builtin(&mut interp).unwrap();
120
121 let result = interp.pop().unwrap();
122 assert!(matches!(result, Value::String(s) if s.as_ref() == "[]"));
123 }
124
125 #[test]
126 fn test_to_string_builtin_list() {
127 let mut interp = setup_interpreter();
128
129 let list = interp.make_list(vec![
131 Value::Number(1.0),
132 Value::Number(2.0),
133 Value::Number(3.0),
134 ]);
135 interp.push(list);
136 to_string_builtin(&mut interp).unwrap();
137
138 let result = interp.pop().unwrap();
139 assert!(matches!(result, Value::String(s) if s.as_ref() == "[1 2 3]"));
140 }
141
142 #[test]
143 fn test_to_string_builtin_mixed_list() {
144 let mut interp = setup_interpreter();
145
146 let mixed_list = interp.make_list(vec![
148 Value::String("hello".into()),
149 Value::Number(42.0),
150 Value::Boolean(true),
151 ]);
152 interp.push(mixed_list);
153 to_string_builtin(&mut interp).unwrap();
154
155 let result = interp.pop().unwrap();
156 assert!(matches!(result, Value::String(s) if s.as_ref() == "[\"hello\" 42 true]"));
157 }
158
159 #[test]
160 fn test_to_string_builtin_array() {
161 let mut interp = setup_interpreter();
162
163 let array = interp.make_array(vec![Value::Number(1.0), Value::Number(2.0)]);
164 interp.push(array);
165 to_string_builtin(&mut interp).unwrap();
166
167 let result = interp.pop().unwrap();
168 assert!(matches!(result, Value::String(s) if s.as_ref() == "#[1 2]"));
169 }
170
171 #[test]
172 fn test_to_string_builtin_stack_underflow() {
173 let mut interp = setup_interpreter();
174
175 let result = to_string_builtin(&mut interp);
177 assert!(matches!(result, Err(RuntimeError::StackUnderflow)));
178 }
179}