facet_core/impls_alloc/
string.rs1use crate::{Def, Facet, Shape, Type, UserType, value_vtable};
2use alloc::string::ToString;
3
4#[cfg(feature = "alloc")]
5unsafe impl Facet<'_> for alloc::string::String {
6 const SHAPE: &'static Shape = &const {
7 Shape::builder_for_sized::<Self>()
8 .vtable({
9 let mut vtable = value_vtable!(alloc::string::String, |f, _opts| write!(
10 f,
11 "{}",
12 Self::SHAPE.type_identifier
13 ));
14
15 let vtable_sized = &mut vtable;
16 vtable_sized.parse = {
17 Some(|s, target| {
18 Ok(unsafe { target.put(s.to_string()) })
20 })
21 };
22
23 vtable
24 })
25 .def(Def::Scalar)
26 .type_identifier("String")
27 .ty(Type::User(UserType::Opaque))
28 .build()
29 };
30}
31
32unsafe impl<'a> Facet<'a> for alloc::borrow::Cow<'a, str> {
33 const SHAPE: &'static Shape = &const {
34 Shape::builder_for_sized::<Self>()
35 .vtable({
36 value_vtable!(alloc::borrow::Cow<'_, str>, |f, _opts| write!(
37 f,
38 "Cow<'_, str>"
39 ))
40 })
41 .def(Def::Scalar)
42 .type_identifier("Cow")
43 .ty(Type::User(UserType::Opaque))
44 .build()
45 };
46}
47
48#[cfg(test)]
49mod tests {
50 use core::ptr::NonNull;
51
52 use crate::Facet;
53 use crate::ptr::PtrUninit;
54 use alloc::string::String;
55
56 #[test]
57 fn test_string_has_parse() {
58 let shape = String::SHAPE;
60 assert!(
61 shape.vtable.has_parse(),
62 "String should have parse function"
63 );
64 }
65
66 #[test]
67 fn test_string_parse() {
68 let shape = String::SHAPE;
70 let parse_fn = shape.vtable.parse.unwrap();
71
72 let layout = shape.layout.sized_layout().unwrap();
74 let ptr = unsafe { alloc::alloc::alloc(layout) };
75 let Some(ptr) = NonNull::new(ptr) else {
76 alloc::alloc::handle_alloc_error(layout)
77 };
78 let uninit = PtrUninit::new(ptr);
79
80 let result = unsafe { parse_fn("hello world", uninit) };
82 assert!(result.is_ok());
83
84 let ptr_mut = result.unwrap();
86 let parsed = unsafe { ptr_mut.get::<String>() };
87 assert_eq!(parsed, &String::from("hello world"));
88
89 unsafe {
91 ptr_mut.drop_in_place::<String>();
92 alloc::alloc::dealloc(ptr.as_ptr(), layout);
93 }
94 }
95}