serde_json_borrow/
owned.rs1use std::io;
2use std::ops::Deref;
3
4use crate::Value;
5
6#[derive(Clone, Debug, Eq, PartialEq, Hash)]
11pub struct OwnedValue {
12 _data: String,
14 value: Value<'static>,
15}
16
17impl OwnedValue {
18 pub fn from_slice(data: &[u8]) -> io::Result<Self> {
20 let data = String::from_utf8(data.to_vec())
21 .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8"))?;
22 Self::from_string(data)
23 }
24
25 #[allow(clippy::should_implement_trait)]
29 pub fn from_str(json_str: &str) -> io::Result<Self> {
30 let json_str = json_str.to_string();
31 Self::from_string(json_str)
32 }
33
34 pub fn from_string(json_str: String) -> io::Result<Self> {
36 let value: Value = serde_json::from_str(&json_str)?;
37 let value = unsafe { extend_lifetime(value) };
38 Ok(Self {
39 _data: json_str,
40 value,
41 })
42 }
43
44 pub fn parse_from(json_str: String) -> io::Result<Self> {
46 Self::from_string(json_str)
47 }
48
49 pub fn get_value(&self) -> &Value<'_> {
51 &self.value
52 }
53}
54
55impl Deref for OwnedValue {
56 type Target = Value<'static>;
57
58 fn deref(&self) -> &Self::Target {
59 &self.value
60 }
61}
62
63unsafe fn extend_lifetime<'b>(r: Value<'b>) -> Value<'static> {
64 std::mem::transmute::<Value<'b>, Value<'static>>(r)
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
73 fn test_deref_access() {
74 let raw_json = r#"{"name": "John", "age": 30}"#;
75 let owned_value = OwnedValue::from_string(raw_json.to_string()).unwrap();
76
77 assert_eq!(owned_value.get("name"), &Value::Str("John".into()));
78 assert_eq!(owned_value.get("age"), &Value::Number(30_u64.into()));
79 }
80
81 #[test]
83 fn test_deref_clone() {
84 let raw_json = r#"{"name": "John", "age": 30}"#;
85 let owned_value = OwnedValue::from_string(raw_json.to_string()).unwrap();
86 let owned_value = owned_value.clone();
87
88 assert_eq!(owned_value.get("name"), &Value::Str("John".into()));
89 assert_eq!(owned_value.get("age"), &Value::Number(30_u64.into()));
90 }
91}