1use crate::{
2 interop::{FromStrs, String},
3 prelude::*,
4};
5use skia_bindings::{self as sb, SkStrings};
6use std::{fmt, ops::Index};
7
8pub type Strings = Handle<SkStrings>;
9unsafe_send_sync!(Strings);
10
11impl NativeDrop for SkStrings {
12 fn drop(&mut self) {
13 unsafe {
14 sb::C_SkStrings_destruct(self);
15 }
16 }
17}
18
19impl fmt::Debug for Strings {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 f.debug_tuple(name:"Strings").field(&self.as_slice()).finish()
22 }
23}
24
25impl Handle<SkStrings> {
26 /// Constructs a native Strings array from a slice of SkStrings by moving them.
27 pub fn new(mut strings: Vec<String>) -> Self {
28 Strings::construct(|s| unsafe {
29 sb::C_SkStrings_construct(s, strings.native_mut().as_mut_ptr(), strings.len())
30 })
31 }
32
33 pub fn is_empty(&self) -> bool {
34 self.len() == 0
35 }
36
37 pub fn len(&self) -> usize {
38 let mut count = 0;
39 unsafe {
40 sb::C_SkStrings_ptr_count(self.native(), &mut count);
41 }
42 count
43 }
44
45 pub fn as_slice(&self) -> &[String] {
46 let mut count = 0;
47 let ptr = unsafe { sb::C_SkStrings_ptr_count(self.native(), &mut count) };
48 unsafe { safer::from_raw_parts(ptr as *const String, count) }
49 }
50}
51
52impl Index<usize> for Strings {
53 type Output = String;
54 fn index(&self, index: usize) -> &Self::Output {
55 &self.as_slice()[index]
56 }
57}
58
59impl FromStrs for Strings {
60 fn from_strs(strings: &[impl AsRef<str>]) -> Self {
61 Strings::new(strings:strings.iter().map(String::from_str).collect())
62 }
63}
64
65#[test]
66fn test_strings() {
67 let strings: [&str; 2] = ["Hello", "World"];
68 let strings: Handle = Strings::from_strs(&strings);
69 assert_eq!(strings[0].as_str(), "Hello");
70 assert_eq!(strings[1].as_str(), "World");
71}
72