1 | use crate::prelude::*; |
2 | use skia_bindings::{self as sb, SkString}; |
3 | use std::{fmt, str}; |
4 | |
5 | pub type String = Handle<SkString>; |
6 | unsafe_send_sync!(String); |
7 | |
8 | impl NativeDrop for SkString { |
9 | fn drop(&mut self) { |
10 | unsafe { |
11 | sb::C_SkString_destruct(self); |
12 | } |
13 | } |
14 | } |
15 | |
16 | impl AsRef<str> for String { |
17 | fn as_ref(&self) -> &str { |
18 | self.as_str() |
19 | } |
20 | } |
21 | |
22 | impl ToString for String { |
23 | fn to_string(&self) -> std::string::String { |
24 | self.as_str().into() |
25 | } |
26 | } |
27 | |
28 | impl Default for String { |
29 | fn default() -> Self { |
30 | Self::from_str("" ) |
31 | } |
32 | } |
33 | |
34 | impl fmt::Debug for String { |
35 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
36 | self.as_str().fmt(f) |
37 | } |
38 | } |
39 | |
40 | impl 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 | |
52 | pub trait AsStr { |
53 | fn as_str(&self) -> &str; |
54 | } |
55 | |
56 | impl AsStr for Handle<SkString> { |
57 | fn as_str(&self) -> &str { |
58 | self.native().as_str() |
59 | } |
60 | } |
61 | |
62 | impl 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 | |
73 | impl 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 | |
84 | impl 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 | |
95 | pub trait SetStr { |
96 | fn set_str(&mut self, str: impl AsRef<str>); |
97 | } |
98 | |
99 | impl SetStr for Handle<SkString> { |
100 | fn set_str(&mut self, str: impl AsRef<str>) { |
101 | self.native_mut().set_str(str) |
102 | } |
103 | } |
104 | |
105 | impl 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 | |
112 | pub trait FromStrs { |
113 | fn from_strs(strings: &[impl AsRef<str>]) -> Self; |
114 | } |
115 | |
116 | impl 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)] |
126 | mod 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 | |