swift_bridge/std_bridge/
string.rs

1//! The corresponding C and Swift code can be found in
2//! crates/swift-bridge-build/src/generate_core/rust_string.{c.h,swift}
3pub use self::ffi::*;
4
5#[swift_bridge_macro::bridge(swift_bridge_path = crate)]
6mod ffi {
7    extern "Rust" {
8        type RustString;
9
10        #[swift_bridge(init)]
11        fn new() -> RustString;
12
13        #[swift_bridge(init)]
14        fn new_with_str(str: &str) -> RustString;
15
16        fn len(&self) -> usize;
17
18        fn as_str(&self) -> &str;
19
20        fn trim(&self) -> &str;
21    }
22}
23
24#[doc(hidden)]
25pub struct RustString(pub String);
26
27#[doc(hidden)]
28#[repr(C)]
29pub struct RustStr {
30    pub start: *const u8,
31    pub len: usize,
32}
33
34impl RustString {
35    fn new() -> Self {
36        RustString("".to_string())
37    }
38
39    fn new_with_str(str: &str) -> Self {
40        RustString(str.to_string())
41    }
42
43    fn len(&self) -> usize {
44        self.0.len()
45    }
46
47    fn as_str(&self) -> &str {
48        self.0.as_str()
49    }
50
51    fn trim(&self) -> &str {
52        self.0.trim()
53    }
54}
55
56impl RustString {
57    /// Box::into_raw(Box::new(self))
58    pub fn box_into_raw(self) -> *mut RustString {
59        Box::into_raw(Box::new(self))
60    }
61}
62
63impl RustStr {
64    pub fn len(&self) -> usize {
65        self.len
66    }
67
68    // TODO: Think through these lifetimes and the implications of them...
69    pub fn to_str<'a>(self) -> &'a str {
70        let bytes = unsafe { std::slice::from_raw_parts(self.start, self.len) };
71        std::str::from_utf8(bytes).expect("Failed to convert RustStr to &str")
72    }
73
74    pub fn to_string(self) -> String {
75        self.to_str().to_string()
76    }
77
78    pub fn from_str(str: &str) -> Self {
79        RustStr {
80            start: str.as_ptr(),
81            len: str.len(),
82        }
83    }
84}
85
86impl PartialEq for RustStr {
87    fn eq(&self, other: &Self) -> bool {
88        unsafe {
89            std::slice::from_raw_parts(self.start, self.len)
90                == std::slice::from_raw_parts(other.start, other.len)
91        }
92    }
93}
94
95#[export_name = "__swift_bridge__$RustStr$partial_eq"]
96#[allow(non_snake_case)]
97pub extern "C" fn __swift_bridge__RustStr_partial_eq(lhs: RustStr, rhs: RustStr) -> bool {
98    lhs == rhs
99}