1use crate::prelude::*;
2use skia_bindings::{self as sb, SkString};
3use std::{fmt, str};
4
5pub type String = Handle<SkString>;
6unsafe_send_sync!(String);
7
8impl NativeDrop for SkString {
9 fn drop(&mut self) {
10 unsafe {
11 sb::C_SkString_destruct(self);
12 }
13 }
14}
15
16impl AsRef<str> for String {
17 fn as_ref(&self) -> &str {
18 self.as_str()
19 }
20}
21
22impl ToString for String {
23 fn to_string(&self) -> std::string::String {
24 self.as_str().into()
25 }
26}
27
28impl Default for String {
29 fn default() -> Self {
30 Self::from_str("")
31 }
32}
33
34impl fmt::Debug for String {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 self.as_str().fmt(f)
37 }
38}
39
40impl String {
41 #[allow(clippy::should_implement_trait)]
42 pub fn from_str(str: impl AsRef<str>) -> String {
43 let bytes: &[u8] = str.as_ref().as_bytes();
44 Handle::from_native_c(unsafe { SkString::new3(text:bytes.as_ptr() as _, bytes.len()) })
45 }
46
47 pub fn as_str(&self) -> &str {
48 self.native().as_str()
49 }
50}
51
52pub trait AsStr {
53 fn as_str(&self) -> &str;
54}
55
56impl AsStr for Handle<SkString> {
57 fn as_str(&self) -> &str {
58 self.native().as_str()
59 }
60}
61
62impl AsStr for SkString {
63 fn as_str(&self) -> &str {
64 let mut size: usize = 0;
65 let slice: &[u8] = unsafe {
66 let ptr: *const u8 = sb::C_SkString_c_str_size(self, &mut size) as *const u8;
67 safer::from_raw_parts(ptr, len:size)
68 };
69 std::str::from_utf8(slice).unwrap_or_default()
70 }
71}
72
73impl AsStr for sb::std_string_view {
74 fn as_str(&self) -> &str {
75 let slice: &[u8] = unsafe {
76 let mut size: usize = 0;
77 let ptr: *const u8 = sb::C_string_view_ptr_size(self, &mut size) as *const u8;
78 safer::from_raw_parts(ptr, len:size)
79 };
80 str::from_utf8(slice).unwrap_or_default()
81 }
82}
83
84impl AsStr for sb::std_string {
85 fn as_str(&self) -> &str {
86 let slice: &[u8] = unsafe {
87 let mut size: usize = 0;
88 let ptr: *const u8 = sb::C_string_ptr_size(self, &mut size) as *const u8;
89 safer::from_raw_parts(ptr, len:size)
90 };
91 str::from_utf8(slice).unwrap_or_default()
92 }
93}
94
95pub trait SetStr {
96 fn set_str(&mut self, str: impl AsRef<str>);
97}
98
99impl SetStr for Handle<SkString> {
100 fn set_str(&mut self, str: impl AsRef<str>) {
101 self.native_mut().set_str(str)
102 }
103}
104
105impl SetStr for SkString {
106 fn set_str(&mut self, str: impl AsRef<str>) {
107 let bytes: &[u8] = str.as_ref().as_bytes();
108 unsafe { self.set1(text:bytes.as_ptr() as _, bytes.len()) }
109 }
110}
111
112pub trait FromStrs {
113 fn from_strs(strings: &[impl AsRef<str>]) -> Self;
114}
115
116impl FromStrs for Vec<String> {
117 fn from_strs(strings: &[impl AsRef<str>]) -> Self {
118 stringsimpl Iterator>
119 .iter()
120 .map(|s: &impl AsRef| String::from_str(s.as_ref()))
121 .collect()
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use super::{SetStr, String};
128
129 #[test]
130 fn string_from_rust_and_back() {
131 let str = "Hello";
132 let string = String::from_str(str);
133 assert_eq!(str, string.as_str())
134 }
135
136 #[test]
137 fn set_string() {
138 let mut hello = String::from_str("Hello");
139 hello.set_str(String::from_str("World"));
140 assert_eq!("World", hello.as_str());
141 }
142}
143