skia_safe/interop/
strings.rs

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("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.iter().map(String::from_str).collect())
62    }
63}
64
65#[test]
66fn test_strings() {
67    let strings = ["Hello", "World"];
68    let strings = Strings::from_strs(&strings);
69    assert_eq!(strings[0].as_str(), "Hello");
70    assert_eq!(strings[1].as_str(), "World");
71}