1use std::{mem, ptr, sync::Arc};
2
3use crate::{StorageExt, StorageExtStr, StorageVTable};
4
5fn as_ptr(addr: *const u8, _: usize) -> *const u8 {
8 addr
9}
10
11fn len(_: *const u8, len: usize) -> usize {
12 len
13}
14
15fn clone_str(addr: *const u8, len: usize) -> Option<(*const u8, usize)> {
16 let slice_ptr: *const [u8] = ptr::slice_from_raw_parts(addr, len);
17 let str_ptr = slice_ptr as *const str;
18 let arc = unsafe { Arc::from_raw(str_ptr) };
19 let arc2 = arc.clone();
20 mem::forget(arc);
21 mem::forget(arc2);
22
23 Some((addr, len))
24}
25
26fn drop_str(addr: *const u8, len: usize) {
27 let slice_ptr: *const [u8] = ptr::slice_from_raw_parts(addr, len);
28 let str_ptr = slice_ptr as *const str;
29 let arc = unsafe { Arc::from_raw(str_ptr) };
30 drop(arc);
31}
32
33const ARC_STR_VTABLE: StorageVTable = StorageVTable::new(as_ptr, len, clone_str, drop_str);
34
35unsafe impl StorageExt for Arc<str> {
38 fn create(self) -> (*const u8, usize, &'static StorageVTable) {
39 let ptr = Arc::into_raw(self) as *const [u8];
40
41 let addr = ptr.cast::<()>().cast::<u8>();
43 let len = ptr.len();
44 (addr, len, &ARC_STR_VTABLE)
45 }
46}
47
48unsafe impl StorageExtStr for Arc<str> {}
50
51#[cfg(test)]
52#[allow(unused_must_use)]
53mod tests {
54 use super::*;
55 use crate::{ByteString, Bytes, buf::Buf};
56
57 #[test]
63 fn test_arc_str() {
64 let test: Arc<str> = Arc::from("test".to_string());
65
66 let b = Bytes::from_ext(test.clone());
67 assert_eq!(&b, b"test");
68 assert_eq!(b.storage.capacity(), 4);
69 assert_eq!(Arc::strong_count(&test), 2);
70
71 let b2 = b.clone();
72 assert_eq!(&b2, b"test");
73 assert_eq!(Arc::strong_count(&test), 3);
74
75 drop(b2);
76 assert_eq!(&b, b"test");
77 assert_eq!(Arc::strong_count(&test), 2);
78
79 drop(b);
80 assert_eq!(Arc::strong_count(&test), 1);
81
82 let b = ByteString::from_ext(test.clone());
83 assert_eq!(&b, "test");
84 assert_eq!(Arc::strong_count(&test), 2);
85
86 drop(b);
87 assert_eq!(Arc::strong_count(&test), 1);
88
89 let mut b = Bytes::from_ext(test.clone());
90 assert_eq!(Arc::strong_count(&test), 2);
91 assert_eq!(b.get_u8(), b't');
92 assert_eq!(&b, b"est");
93 assert_eq!(Arc::strong_count(&test), 1);
94
95 let mut b = Bytes::from_ext(test.clone());
96 b.truncate(2);
97 assert_eq!(&b, b"te");
98 assert_eq!(Arc::strong_count(&test), 1);
99
100 let mut b = Bytes::from_ext(test.clone());
101 unsafe { b.storage.set_start(2) };
102 assert_eq!(&b, b"st");
103 assert_eq!(Arc::strong_count(&test), 1);
104
105 let mut b = Bytes::from_ext(test.clone());
106 unsafe { b.storage.set_end(2) };
107 assert_eq!(&b, b"te");
108 assert_eq!(Arc::strong_count(&test), 1);
109 }
110}