rune/
character.rs
1use crate::core::{
3 gc::Context,
4 object::{Gc, Object, OptionalFlag, int_to_char},
5};
6use anyhow::Result;
7use rune_macros::defun;
8
9#[defun]
10fn unibyte_string(bytes: &[Gc<i64>]) -> Result<Vec<u8>> {
11 let unibyte: Result<Vec<u8>, _> = bytes.iter().map(|x| u8::try_from(x.untag())).collect();
12 Ok(unibyte?)
13}
14
15#[defun]
16fn max_char(unicode: OptionalFlag) -> usize {
17 if unicode.is_some() { std::char::MAX as usize } else { 0x3F_FFFF }
18}
19
20#[defun]
21fn characterp(obj: Object) -> bool {
22 char::try_from(obj).is_ok()
23}
24
25#[defun]
26fn string(characters: &[Gc<i64>]) -> Result<String> {
27 let string: Result<_, _> = characters.iter().map(|x| int_to_char(x.untag())).collect();
28 Ok(string?)
29}
30
31#[defun]
32fn make_string<'ob>(
33 length: usize,
34 init: usize,
35 multibyte: OptionalFlag,
36 cx: &'ob Context,
37) -> Result<Object<'ob>> {
38 if multibyte.is_some() {
39 let chr = int_to_char(i64::try_from(init)?)?;
40 let size = chr.len_utf8();
41 let mut string = cx.string_with_capacity(length * size);
42 for _ in 0..length {
43 string.push(chr);
44 }
45 Ok(cx.add(string))
46 } else {
47 let chr = u8::try_from(init)?;
48 let string: Vec<_> = (0..length).map(|_| chr).collect();
49 Ok(cx.add(string))
50 }
51}