roan_engine/value/methods/
char.rs

1use crate::{
2    as_cast, native_function,
3    value::Value,
4    vm::native_fn::{NativeFunction, NativeFunctionParam},
5};
6
7native_function!(
8    fn __char_is_alphabetic(c) {
9        let c = as_cast!(c, Char);
10
11        Value::Bool(c.is_alphabetic())
12    }
13);
14
15native_function!(
16    fn __char_is_alphanumeric(c) {
17        let c = as_cast!(c, Char);
18
19        Value::Bool(c.is_alphanumeric())
20    }
21);
22
23native_function!(
24    fn __char_is_ascii(c) {
25        let c = as_cast!(c, Char);
26
27        Value::Bool(c.is_ascii())
28    }
29);
30
31native_function!(
32    fn __char_is_ascii_alphabetic(c) {
33        let c = as_cast!(c, Char);
34
35        Value::Bool(c.is_ascii_alphabetic())
36    }
37);
38
39native_function!(
40    fn __char_is_ascii_alphanumeric(c) {
41        let c = as_cast!(c, Char);
42
43        Value::Bool(c.is_ascii_alphanumeric())
44    }
45);
46
47native_function!(
48    fn __char_is_ascii_control(c) {
49        let c = as_cast!(c, Char);
50
51        Value::Bool(c.is_ascii_control())
52    }
53);
54
55native_function!(
56    fn __char_is_ascii_digit(c) {
57        let c = as_cast!(c, Char);
58
59        Value::Bool(c.is_ascii_digit())
60    }
61);
62
63native_function!(
64    fn __char_is_ascii_graphic(c) {
65        let c = as_cast!(c, Char);
66
67        Value::Bool(c.is_ascii_graphic())
68    }
69);
70
71native_function!(
72    fn __char_is_ascii_lowercase(c) {
73        let c = as_cast!(c, Char);
74
75        Value::Bool(c.is_ascii_lowercase())
76    }
77);
78
79native_function!(
80    fn __char_is_ascii_punctuation(c) {
81        let c = as_cast!(c, Char);
82
83        Value::Bool(c.is_ascii_punctuation())
84    }
85);
86
87native_function!(
88    fn __char_is_ascii_uppercase(c) {
89        let c = as_cast!(c, Char);
90
91        Value::Bool(c.is_ascii_uppercase())
92    }
93);
94
95native_function!(
96    fn __char_is_ascii_whitespace(c) {
97        let c = as_cast!(c, Char);
98
99        Value::Bool(c.is_ascii_whitespace())
100    }
101);
102
103native_function!(
104    fn __char_is_control(c) {
105        let c = as_cast!(c, Char);
106
107        Value::Bool(c.is_control())
108    }
109);
110
111native_function!(
112    fn __char_is_digit(c) {
113        let c = as_cast!(c, Char);
114
115        Value::Bool(c.is_digit(10))
116    }
117);
118
119native_function!(
120    fn __char_is_lowercase(c) {
121        let c = as_cast!(c, Char);
122
123        Value::Bool(c.is_lowercase())
124    }
125);
126
127native_function!(
128    fn __char_is_numeric(c) {
129        let c = as_cast!(c, Char);
130
131        Value::Bool(c.is_numeric())
132    }
133);
134
135native_function!(
136    fn __char_is_uppercase(c) {
137        let c = as_cast!(c, Char);
138
139        Value::Bool(c.is_uppercase())
140    }
141);
142
143native_function!(
144    fn __char_is_whitespace(c) {
145        let c = as_cast!(c, Char);
146
147        Value::Bool(c.is_whitespace())
148    }
149);
150
151native_function!(
152    fn __char_to_ascii_lowercase(c) {
153        let c = as_cast!(c, Char);
154
155        Value::Char(c.to_ascii_lowercase())
156    }
157);
158
159native_function!(
160    fn __char_to_ascii_uppercase(c) {
161        let c = as_cast!(c, Char);
162
163        Value::Char(c.to_ascii_uppercase())
164    }
165);
166
167native_function!(
168    fn __char_to_lowercase(c) {
169        let c = as_cast!(c, Char);
170
171        Value::Char(c.to_lowercase().next().unwrap())
172    }
173);
174
175native_function!(
176    fn __char_to_uppercase(c) {
177        let c = as_cast!(c, Char);
178
179        Value::Char(c.to_uppercase().next().unwrap())
180    }
181);
182
183native_function!(
184    fn __char_is_digit_in_base(c, base) {
185        let c = as_cast!(c, Char);
186        let base = as_cast!(base, Int);
187
188        Value::Bool(c.is_digit(base as u32))
189    }
190);
191
192native_function!(
193    fn __char_escape_default(c) {
194        let c = as_cast!(c, Char);
195
196        Value::String(c.escape_default().to_string().into())
197    }
198);
199
200native_function!(
201    fn __char_escape_unicode(c) {
202        let c = as_cast!(c, Char);
203
204        Value::String(c.escape_unicode().to_string().into())
205    }
206);
207
208native_function!(
209    fn __char_from_digit(digit, base) {
210        let digit = as_cast!(digit, Int);
211        let base = as_cast!(base, Int);
212
213        match char::from_digit(digit as u32, base as u32) {
214            Some(c) => Value::Char(c),
215            None => Value::Null
216        }
217    }
218);
219
220native_function!(
221    fn __char_len_utf8(c) {
222        let c = as_cast!(c, Char);
223
224        Value::Int(c.len_utf8() as i64)
225    }
226);
227
228native_function!(
229    fn __char_to_string(c) {
230        let c = as_cast!(c, Char);
231
232        Value::String(c.to_string().into())
233    }
234);
235
236native_function!(
237    fn __char_to_int(c) {
238        let c = as_cast!(c, Char);
239
240        Value::Int(c as i64)
241    }
242);
243
244#[cfg(test)]
245mod tests {
246    use super::*;
247    use crate::value::Value;
248
249    #[test]
250    fn test_char_is_alphabetic() {
251        let result = __char_is_alphabetic().call(vec![Value::Char('a')]).unwrap();
252
253        assert_eq!(result, Value::Bool(true));
254    }
255
256    #[test]
257    fn test_char_is_alphanumeric() {
258        let result = __char_is_alphanumeric()
259            .call(vec![Value::Char('a')])
260            .unwrap();
261
262        assert_eq!(result, Value::Bool(true));
263    }
264
265    #[test]
266    fn test_char_is_ascii() {
267        let result = __char_is_ascii().call(vec![Value::Char('a')]).unwrap();
268
269        assert_eq!(result, Value::Bool(true));
270    }
271
272    #[test]
273    fn test_char_is_ascii_alphabetic() {
274        let result = __char_is_ascii_alphabetic()
275            .call(vec![Value::Char('a')])
276            .unwrap();
277
278        assert_eq!(result, Value::Bool(true));
279    }
280
281    #[test]
282    fn test_char_is_ascii_alphanumeric() {
283        let result = __char_is_ascii_alphanumeric()
284            .call(vec![Value::Char('a')])
285            .unwrap();
286
287        assert_eq!(result, Value::Bool(true));
288    }
289
290    #[test]
291    fn test_char_is_ascii_control() {
292        let result = __char_is_ascii_control()
293            .call(vec![Value::Char('\n')])
294            .unwrap();
295
296        assert_eq!(result, Value::Bool(true));
297    }
298
299    #[test]
300    fn test_char_is_ascii_digit() {
301        let result = __char_is_ascii_digit()
302            .call(vec![Value::Char('1')])
303            .unwrap();
304
305        assert_eq!(result, Value::Bool(true));
306    }
307
308    #[test]
309    fn test_char_is_ascii_graphic() {
310        let result = __char_is_ascii_graphic()
311            .call(vec![Value::Char('a')])
312            .unwrap();
313
314        assert_eq!(result, Value::Bool(true));
315    }
316
317    #[test]
318    fn test_char_is_ascii_lowercase() {
319        let result = __char_is_ascii_lowercase()
320            .call(vec![Value::Char('a')])
321            .unwrap();
322
323        assert_eq!(result, Value::Bool(true));
324    }
325
326    #[test]
327    fn test_char_is_ascii_punctuation() {
328        let result = __char_is_ascii_punctuation()
329            .call(vec![Value::Char('!')])
330            .unwrap();
331
332        assert_eq!(result, Value::Bool(true));
333    }
334
335    #[test]
336    fn test_char_is_ascii_uppercase() {
337        let result = __char_is_ascii_uppercase()
338            .call(vec![Value::Char('A')])
339            .unwrap();
340
341        assert_eq!(result, Value::Bool(true));
342    }
343
344    #[test]
345    fn test_char_is_ascii_whitespace() {
346        let result = __char_is_ascii_whitespace()
347            .call(vec![Value::Char(' ')])
348            .unwrap();
349
350        assert_eq!(result, Value::Bool(true));
351    }
352
353    #[test]
354    fn test_char_is_control() {
355        let result = __char_is_control().call(vec![Value::Char('\n')]).unwrap();
356
357        assert_eq!(result, Value::Bool(true));
358    }
359
360    #[test]
361    fn test_char_is_digit() {
362        let result = __char_is_digit().call(vec![Value::Char('1')]).unwrap();
363
364        assert_eq!(result, Value::Bool(true));
365    }
366
367    #[test]
368    fn test_char_is_lowercase() {
369        let result = __char_is_lowercase().call(vec![Value::Char('a')]).unwrap();
370
371        assert_eq!(result, Value::Bool(true));
372    }
373
374    #[test]
375    fn test_char_is_numeric() {
376        let result = __char_is_numeric().call(vec![Value::Char('1')]).unwrap();
377
378        assert_eq!(result, Value::Bool(true));
379    }
380
381    #[test]
382    fn test_char_is_uppercase() {
383        let result = __char_is_uppercase().call(vec![Value::Char('A')]).unwrap();
384
385        assert_eq!(result, Value::Bool(true));
386    }
387
388    #[test]
389    fn test_char_is_whitespace() {
390        let result = __char_is_whitespace().call(vec![Value::Char(' ')]).unwrap();
391
392        assert_eq!(result, Value::Bool(true));
393    }
394
395    #[test]
396    fn test_char_to_ascii_lowercase() {
397        let result = __char_to_ascii_lowercase()
398            .call(vec![Value::Char('A')])
399            .unwrap();
400
401        assert_eq!(result, Value::Char('a'));
402    }
403
404    #[test]
405    fn test_char_to_ascii_uppercase() {
406        let result = __char_to_ascii_uppercase()
407            .call(vec![Value::Char('a')])
408            .unwrap();
409
410        assert_eq!(result, Value::Char('A'));
411    }
412
413    #[test]
414    fn test_char_to_lowercase() {
415        let result = __char_to_lowercase().call(vec![Value::Char('A')]).unwrap();
416
417        assert_eq!(result, Value::Char('a'));
418    }
419
420    #[test]
421    fn test_char_to_uppercase() {
422        let result = __char_to_uppercase().call(vec![Value::Char('a')]).unwrap();
423
424        assert_eq!(result, Value::Char('A'));
425    }
426
427    #[test]
428    fn test_char_is_digit_in_base() {
429        let result = __char_is_digit_in_base()
430            .call(vec![Value::Char('1'), Value::Int(10)])
431            .unwrap();
432
433        assert_eq!(result, Value::Bool(true));
434    }
435
436    #[test]
437    fn test_char_escape_default() {
438        let result = __char_escape_default()
439            .call(vec![Value::Char('\n')])
440            .unwrap();
441
442        assert_eq!(result, Value::String("\\n".into()));
443    }
444
445    #[test]
446    fn test_char_escape_unicode() {
447        let result = __char_escape_unicode()
448            .call(vec![Value::Char('a')])
449            .unwrap();
450
451        assert_eq!(result, Value::String("\\u{61}".into()));
452    }
453
454    #[test]
455    fn test_char_from_digit() {
456        let result = __char_from_digit()
457            .call(vec![Value::Int(1), Value::Int(10)])
458            .unwrap();
459
460        assert_eq!(result, Value::Char('1'));
461    }
462
463    #[test]
464    fn test_char_len_utf8() {
465        let result = __char_len_utf8().call(vec![Value::Char('a')]).unwrap();
466
467        assert_eq!(result, Value::Int(1));
468    }
469
470    #[test]
471    fn test_char_is_ascii_non_ascii() {
472        let result = __char_is_ascii().call(vec![Value::Char('é')]).unwrap();
473        assert_eq!(result, Value::Bool(false));
474    }
475
476    #[test]
477    fn test_char_is_ascii_lowercase_non_ascii() {
478        let result = __char_is_ascii_lowercase()
479            .call(vec![Value::Char('é')])
480            .unwrap();
481        assert_eq!(result, Value::Bool(false));
482    }
483
484    #[test]
485    fn test_char_is_ascii_uppercase_non_ascii() {
486        let result = __char_is_ascii_uppercase()
487            .call(vec![Value::Char('É')])
488            .unwrap();
489        assert_eq!(result, Value::Bool(false));
490    }
491
492    #[test]
493    fn test_char_from_digit_invalid() {
494        let result = __char_from_digit()
495            .call(vec![Value::Int(16), Value::Int(10)]) // 16 is invalid in base 10
496            .unwrap();
497
498        assert_eq!(result, Value::Null);
499    }
500
501    #[test]
502    fn test_char_is_digit_in_base_invalid_base() {
503        let result = __char_is_digit_in_base()
504            .call(vec![Value::Char('A'), Value::Int(10)]) // 'A' is not a digit in base 10
505            .unwrap();
506
507        assert_eq!(result, Value::Bool(false));
508    }
509
510    #[test]
511    fn test_char_len_utf8_emoji() {
512        let result = __char_len_utf8().call(vec![Value::Char('😊')]).unwrap();
513        assert_eq!(result, Value::Int(4)); // UTF-8 length of emoji
514    }
515}