1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use cesu8::from_cesu8;
use error::{Error, Result};
use ffi;
use std::slice;
use std::string::String as StdString;
use types::Ref;
#[derive(Clone, Debug)]
pub struct String<'ducc>(pub(crate) Ref<'ducc>);
impl<'ducc> String<'ducc> {
pub fn to_string(&self) -> Result<StdString> {
match from_cesu8(self.as_bytes()) {
Ok(string) => Ok(string.into_owned()),
Err(_) => Err(Error::from_js_conversion("string", "String"))
}
}
pub fn as_bytes(&self) -> &[u8] {
let with_nul = self.as_bytes_with_nul();
&with_nul[..with_nul.len() - 1]
}
pub fn as_bytes_with_nul(&self) -> &[u8] {
unsafe {
let ducc = self.0.ducc;
let ctx = ducc.ctx;
assert_stack!(ctx, 0, {
ducc.push_ref(&self.0);
assert!(ffi::duk_is_string(ctx, -1) != 0);
let mut len = 0;
let data = ffi::duk_get_lstring(ctx, -1, &mut len);
assert!(!data.is_null());
let bytes = slice::from_raw_parts(data as *const u8, len + 1 as usize);
assert!(bytes[bytes.len() - 1] == 0);
ffi::duk_pop(ctx);
bytes
})
}
}
}
impl<'ducc> AsRef<[u8]> for String<'ducc> {
fn as_ref(&self) -> &[u8] {
self.as_bytes()
}
}
impl<'ducc, T: AsRef<[u8]>> PartialEq<T> for String<'ducc> {
fn eq(&self, other: &T) -> bool {
self.as_bytes() == other.as_ref()
}
}