1
// Inspired by David Tolnay's serde-rs
2
// https://github.com/serde-rs/json/blob/master/src/raw.rs
3
// Licensed under either of Apache License, Version 2.0 or MIT license at your option.
4

            
5
use std::{fmt, ops::Range};
6

            
7
use serde::{de, ser, Deserialize, Serialize};
8

            
9
use crate::{
10
    error::{Error, SpannedResult},
11
    options::Options,
12
};
13

            
14
// NOTE: Keep synchronised with fuzz/arbitrary::typed_data::RAW_VALUE_TOKEN
15
pub(crate) const RAW_VALUE_TOKEN: &str = "$ron::private::RawValue";
16

            
17
#[allow(clippy::module_name_repetitions)]
18
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
19
#[repr(transparent)]
20
pub struct RawValue {
21
    ron: str,
22
}
23

            
24
#[allow(unsafe_code)]
25
impl RawValue {
26
22194
    fn from_borrowed_str(ron: &str) -> &Self {
27
22194
        // Safety: RawValue is a transparent newtype around str
28
22194
        unsafe { &*(ron as *const str as *const RawValue) }
29
22194
    }
30

            
31
16714
    fn from_boxed_str(ron: Box<str>) -> Box<Self> {
32
16714
        // Safety: RawValue is a transparent newtype around str
33
16714
        unsafe { std::mem::transmute::<Box<str>, Box<RawValue>>(ron) }
34
16714
    }
35

            
36
3836
    fn into_boxed_str(raw_value: Box<Self>) -> Box<str> {
37
3836
        // Safety: RawValue is a transparent newtype around str
38
3836
        unsafe { std::mem::transmute::<Box<RawValue>, Box<str>>(raw_value) }
39
3836
    }
40

            
41
    #[allow(clippy::expect_used)]
42
7124
    fn trim_range(ron: &str) -> Range<usize> {
43
7124
        fn trim_range_inner(ron: &str) -> Result<Range<usize>, Error> {
44
7124
            let mut deserializer = crate::Deserializer::from_str(ron).map_err(Error::from)?;
45

            
46
7124
            deserializer.parser.skip_ws()?;
47
7124
            let start_offset = ron.len() - deserializer.parser.src().len();
48
7124

            
49
7124
            let _ = serde::de::IgnoredAny::deserialize(&mut deserializer)?;
50

            
51
7124
            deserializer.parser.skip_ws()?;
52
7124
            let end_offset = deserializer.parser.pre_ws_src().len();
53
7124

            
54
7124
            Ok(start_offset..(ron.len() - end_offset))
55
7124
        }
56

            
57
7124
        trim_range_inner(ron).expect("RawValue must contain valid ron")
58
7124
    }
59
}
60

            
61
impl Clone for Box<RawValue> {
62
3288
    fn clone(&self) -> Self {
63
3288
        (**self).to_owned()
64
3288
    }
65
}
66

            
67
impl ToOwned for RawValue {
68
    type Owned = Box<RawValue>;
69

            
70
4384
    fn to_owned(&self) -> Self::Owned {
71
4384
        RawValue::from_boxed_str(self.ron.to_owned().into_boxed_str())
72
4384
    }
73
}
74

            
75
impl fmt::Debug for RawValue {
76
822
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
77
822
        f.debug_tuple("RawValue")
78
822
            .field(&format_args!("{}", &self.ron))
79
822
            .finish()
80
822
    }
81
}
82

            
83
impl fmt::Display for RawValue {
84
274
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85
274
        f.write_str(&self.ron)
86
274
    }
87
}
88

            
89
impl RawValue {
90
    /// Get the inner raw RON string, which is guaranteed to contain valid RON.
91
    #[must_use]
92
12878
    pub fn get_ron(&self) -> &str {
93
12878
        &self.ron
94
12878
    }
95

            
96
    /// Helper function to validate a RON string and turn it into a
97
    /// [`RawValue`].
98
9590
    pub fn from_ron(ron: &str) -> SpannedResult<&Self> {
99
9590
        let mut deserializer = crate::Deserializer::from_str(ron)?;
100

            
101
        // raw values can be used everywhere but extensions cannot
102
9590
        if !deserializer.extensions().is_empty() {
103
548
            return Err(deserializer.span_error(Error::Message(String::from(
104
548
                "ron::value::RawValue cannot enable extensions",
105
548
            ))));
106
9042
        }
107
9042

            
108
9042
        let _ = <&Self>::deserialize(&mut deserializer).map_err(|e| deserializer.span_error(e))?;
109

            
110
7946
        deserializer.end().map_err(|e| deserializer.span_error(e))?;
111

            
112
7672
        Ok(Self::from_borrowed_str(ron))
113
9590
    }
114

            
115
    /// Helper function to validate a RON string and turn it into a
116
    /// [`RawValue`].
117
2740
    pub fn from_boxed_ron(ron: Box<str>) -> SpannedResult<Box<Self>> {
118
2740
        match Self::from_ron(&ron) {
119
2192
            Ok(_) => Ok(Self::from_boxed_str(ron)),
120
548
            Err(err) => Err(err),
121
        }
122
2740
    }
123

            
124
    /// Helper function to deserialize the inner RON string into `T`.
125
8
    pub fn into_rust<'de, T: Deserialize<'de>>(&'de self) -> SpannedResult<T> {
126
8
        Options::default().from_str(&self.ron)
127
8
    }
128

            
129
    /// Helper function to serialize `value` into a RON string.
130
8
    pub fn from_rust<T: Serialize>(value: &T) -> Result<Box<Self>, Error> {
131
8
        let ron = Options::default().to_string(value)?;
132

            
133
8
        Ok(RawValue::from_boxed_str(ron.into_boxed_str()))
134
8
    }
135
}
136

            
137
impl RawValue {
138
    #[must_use]
139
    /// Trims any leadning and trailing whitespace off the raw RON string,
140
    /// including whitespace characters and comments.
141
3562
    pub fn trim(&self) -> &Self {
142
3562
        Self::from_borrowed_str(&self.ron[RawValue::trim_range(&self.ron)])
143
3562
    }
144

            
145
    #[must_use]
146
    #[allow(unsafe_code)]
147
    /// Trims any leadning and trailing whitespace off the boxed raw RON string,
148
    /// including whitespace characters and comments.
149
3562
    pub fn trim_boxed(self: Box<Self>) -> Box<Self> {
150
3562
        let trim_range = RawValue::trim_range(&self.ron);
151
3562
        let mut boxed_ron = RawValue::into_boxed_str(self).into_string();
152
3562
        // SAFETY: ron[trim_range] is a valid str, so draining everything
153
3562
        //         before and after leaves a valid str
154
3562
        unsafe {
155
3562
            boxed_ron.as_mut_vec().drain(trim_range.end..);
156
3562
            boxed_ron.as_mut_vec().drain(0..trim_range.start);
157
3562
        }
158
3562
        RawValue::from_boxed_str(boxed_ron.into_boxed_str())
159
3562
    }
160
}
161

            
162
impl From<Box<RawValue>> for Box<str> {
163
274
    fn from(raw_value: Box<RawValue>) -> Self {
164
274
        RawValue::into_boxed_str(raw_value)
165
274
    }
166
}
167

            
168
impl Serialize for RawValue {
169
88
    fn serialize<S: ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
170
88
        serializer.serialize_newtype_struct(RAW_VALUE_TOKEN, &self.ron)
171
88
    }
172
}
173

            
174
impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue {
175
12890
    fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
176
        struct ReferenceVisitor;
177

            
178
        impl<'de> de::Visitor<'de> for ReferenceVisitor {
179
            type Value = &'de RawValue;
180

            
181
548
            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
182
548
                // This error message only shows up with foreign Deserializers
183
548
                write!(formatter, "any valid borrowed RON-value-string")
184
548
            }
185

            
186
10964
            fn visit_borrowed_str<E: de::Error>(self, ron: &'de str) -> Result<Self::Value, E> {
187
10964
                match Options::default().from_str::<de::IgnoredAny>(ron) {
188
10960
                    Ok(_) => Ok(RawValue::from_borrowed_str(ron)),
189
4
                    Err(err) => Err(de::Error::custom(format!(
190
4
                        "invalid RON value at {}: {}",
191
4
                        err.position, err.code
192
4
                    ))),
193
                }
194
10964
            }
195

            
196
8
            fn visit_newtype_struct<D: de::Deserializer<'de>>(
197
8
                self,
198
8
                deserializer: D,
199
8
            ) -> Result<Self::Value, D::Error> {
200
8
                deserializer.deserialize_str(self)
201
8
            }
202
        }
203

            
204
12890
        deserializer.deserialize_newtype_struct(RAW_VALUE_TOKEN, ReferenceVisitor)
205
12890
    }
206
}
207

            
208
impl<'de> Deserialize<'de> for Box<RawValue> {
209
120
    fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
210
        struct BoxedVisitor;
211

            
212
        impl<'de> de::Visitor<'de> for BoxedVisitor {
213
            type Value = Box<RawValue>;
214

            
215
1644
            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
216
1644
                // This error message only shows up with foreign Deserializers
217
1644
                write!(formatter, "any valid RON-value-string")
218
1644
            }
219

            
220
88
            fn visit_str<E: de::Error>(self, ron: &str) -> Result<Self::Value, E> {
221
88
                match Options::default().from_str::<de::IgnoredAny>(ron) {
222
84
                    Ok(_) => Ok(RawValue::from_boxed_str(ron.to_owned().into_boxed_str())),
223
4
                    Err(err) => Err(de::Error::custom(format!(
224
4
                        "invalid RON value at {}: {}",
225
4
                        err.position, err.code
226
4
                    ))),
227
                }
228
88
            }
229

            
230
8
            fn visit_string<E: de::Error>(self, ron: String) -> Result<Self::Value, E> {
231
8
                match Options::default().from_str::<de::IgnoredAny>(&ron) {
232
4
                    Ok(_) => Ok(RawValue::from_boxed_str(ron.into_boxed_str())),
233
4
                    Err(err) => Err(de::Error::custom(format!(
234
4
                        "invalid RON value at {}: {}",
235
4
                        err.position, err.code
236
4
                    ))),
237
                }
238
8
            }
239

            
240
32
            fn visit_newtype_struct<D: de::Deserializer<'de>>(
241
32
                self,
242
32
                deserializer: D,
243
32
            ) -> Result<Self::Value, D::Error> {
244
32
                deserializer.deserialize_string(self)
245
32
            }
246
        }
247

            
248
120
        deserializer.deserialize_newtype_struct(RAW_VALUE_TOKEN, BoxedVisitor)
249
120
    }
250
}