1use std::ops::Deref;
4
5use facet_core::{OxPtrConst, OxPtrUninit, ParseError, PtrConst, TryFromOutcome, VTableIndirect};
6
7#[derive(Debug, Clone, PartialEq, Eq, Default, Hash)]
12pub struct RawMarkup(pub String);
13
14unsafe fn display_raw_markup(
15 source: OxPtrConst,
16 f: &mut core::fmt::Formatter<'_>,
17) -> Option<core::fmt::Result> {
18 let rm = unsafe { source.get::<RawMarkup>() };
19 Some(write!(f, "{}", rm.0))
20}
21
22unsafe fn try_from_raw_markup(
23 target: OxPtrUninit,
24 src_shape: &'static facet_core::Shape,
25 src: PtrConst,
26) -> TryFromOutcome {
27 if src_shape.id == <&str as facet_core::Facet>::SHAPE.id {
29 let s: &str = unsafe { src.get::<&str>() };
30 unsafe { target.put(RawMarkup(s.to_owned())) };
31 TryFromOutcome::Converted
32 }
33 else if src_shape.id == <String as facet_core::Facet>::SHAPE.id {
35 let s = unsafe { src.read::<String>() };
36 unsafe { target.put(RawMarkup(s)) };
37 TryFromOutcome::Converted
38 } else {
39 TryFromOutcome::Unsupported
40 }
41}
42
43unsafe fn parse_raw_markup(s: &str, target: OxPtrUninit) -> Option<Result<(), ParseError>> {
44 unsafe { target.put(RawMarkup(s.to_owned())) };
45 Some(Ok(()))
46}
47
48const RAW_MARKUP_VTABLE: VTableIndirect = VTableIndirect {
49 display: Some(display_raw_markup),
50 try_from: Some(try_from_raw_markup),
51 parse: Some(parse_raw_markup),
52 ..VTableIndirect::EMPTY
53};
54
55impl RawMarkup {
56 pub fn new(s: impl Into<String>) -> Self {
58 Self(s.into())
59 }
60
61 pub fn as_str(&self) -> &str {
63 &self.0
64 }
65
66 pub fn into_inner(self) -> String {
68 self.0
69 }
70}
71
72impl Deref for RawMarkup {
73 type Target = str;
74 fn deref(&self) -> &Self::Target {
75 &self.0
76 }
77}
78
79impl From<String> for RawMarkup {
80 fn from(s: String) -> Self {
81 Self(s)
82 }
83}
84
85impl From<&str> for RawMarkup {
86 fn from(s: &str) -> Self {
87 Self(s.to_owned())
88 }
89}
90
91impl std::fmt::Display for RawMarkup {
92 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93 self.0.fmt(f)
94 }
95}
96
97unsafe impl facet_core::Facet<'_> for RawMarkup {
99 const SHAPE: &'static facet_core::Shape = &const {
100 facet_core::ShapeBuilder::for_sized::<RawMarkup>("RawMarkup")
101 .def(facet_core::Def::Scalar)
102 .vtable_indirect(&RAW_MARKUP_VTABLE)
103 .inner(<String as facet_core::Facet>::SHAPE)
104 .build()
105 };
106}
107
108pub fn is_raw_markup(shape: &facet_core::Shape) -> bool {
110 shape.type_identifier == "RawMarkup"
112}