facet_core/impls_alloc/
string.rs1use crate::{Def, Facet, Shape, Type, UserType, ValueVTable, value_vtable};
2use alloc::string::ToString;
3
4#[cfg(feature = "alloc")]
5unsafe impl Facet<'_> for alloc::string::String {
6 const VTABLE: &'static ValueVTable = &const {
7 let mut vtable = value_vtable!(alloc::string::String, |f, _opts| write!(
8 f,
9 "{}",
10 Self::SHAPE.type_identifier
11 ));
12
13 let vtable_sized = vtable.sized_mut().unwrap();
14 vtable_sized.parse = || {
15 Some(|s, target| {
16 Ok(unsafe { target.put(s.to_string()) })
18 })
19 };
20
21 vtable
22 };
23
24 const SHAPE: &'static Shape = &const {
25 Shape::builder_for_sized::<Self>()
26 .def(Def::Scalar)
27 .type_identifier("String")
28 .ty(Type::User(UserType::Opaque))
29 .build()
30 };
31}
32
33unsafe impl<'a> Facet<'a> for alloc::borrow::Cow<'a, str> {
34 const VTABLE: &'static ValueVTable = &const {
35 value_vtable!(alloc::borrow::Cow<'_, str>, |f, _opts| write!(
36 f,
37 "Cow<'_, str>"
38 ))
39 };
40
41 const SHAPE: &'static Shape = &const {
42 Shape::builder_for_sized::<Self>()
43 .def(Def::Scalar)
44 .type_identifier("Cow")
45 .ty(Type::User(UserType::Opaque))
46 .build()
47 };
48}
49
50#[cfg(test)]
51mod tests {
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.sized().unwrap().parse)().unwrap();
71
72 let layout = shape.layout.sized_layout().unwrap();
74 let ptr = unsafe { alloc::alloc::alloc(layout) };
75 let uninit = PtrUninit::new(ptr);
76
77 let result = unsafe { parse_fn("hello world", uninit) };
79 assert!(result.is_ok());
80
81 let ptr_mut = result.unwrap();
83 let parsed = unsafe { ptr_mut.get::<String>() };
84 assert_eq!(parsed, &String::from("hello world"));
85
86 unsafe {
88 ptr_mut.drop_in_place::<String>();
89 alloc::alloc::dealloc(ptr, layout);
90 }
91 }
92}