1use std::fmt;
27use std::ops::Deref;
28
29use serde::{Deserialize, Serialize};
30
31use crate::value::Value;
32
33#[derive(Clone, PartialEq, Eq, Hash)]
42pub struct Hybrid<T> {
43 value: T,
44}
45
46impl<T> Hybrid<T> {
47 pub fn new(value: T) -> Self {
49 Self { value }
50 }
51
52 pub fn into_inner(self) -> T {
54 self.value
55 }
56}
57
58impl<T: Default> Default for Hybrid<T> {
59 fn default() -> Self {
60 Self {
61 value: T::default(),
62 }
63 }
64}
65
66impl<T> Deref for Hybrid<T> {
67 type Target = T;
68
69 fn deref(&self) -> &T {
70 &self.value
71 }
72}
73
74impl<T: fmt::Debug> fmt::Debug for Hybrid<T> {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 self.value.fmt(f)
77 }
78}
79
80impl<T: fmt::Display> fmt::Display for Hybrid<T> {
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 self.value.fmt(f)
83 }
84}
85
86impl<T: Serialize> Serialize for Hybrid<T> {
87 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
88 self.value.serialize(serializer)
89 }
90}
91
92impl<'de, T: Deserialize<'de>> Deserialize<'de> for Hybrid<T> {
93 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
94 T::deserialize(deserializer).map(Hybrid::new)
95 }
96}
97
98impl<T: Into<Value>> From<Hybrid<T>> for Value {
99 fn from(h: Hybrid<T>) -> Self {
100 h.value.into()
101 }
102}
103
104impl<T: Clone + Into<Value>> From<&Hybrid<T>> for Value {
105 fn from(h: &Hybrid<T>) -> Self {
106 h.value.clone().into()
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 #[test]
115 fn test_hybrid_deref() {
116 let h = Hybrid::new("hello".to_string());
117 assert_eq!(h.as_str(), "hello");
118 assert_eq!(&*h, "hello");
119 }
120
121 #[test]
122 fn test_hybrid_default() {
123 let h: Hybrid<String> = Hybrid::default();
124 assert_eq!(&*h, "");
125 }
126
127 #[test]
128 fn test_hybrid_display() {
129 let h = Hybrid::new(42);
130 assert_eq!(format!("{}", h), "42");
131 }
132
133 #[test]
134 fn test_hybrid_into_value() {
135 let h = Hybrid::new("test".to_string());
136 let v: Value = h.into();
137 assert_eq!(v, Value::Text("test".to_string()));
138 }
139
140 #[test]
141 fn test_hybrid_serde_roundtrip() {
142 let h = Hybrid::new("hello".to_string());
143 let json = serde_json::to_string(&h).unwrap();
144 assert_eq!(json, "\"hello\"");
145 let back: Hybrid<String> = serde_json::from_str(&json).unwrap();
146 assert_eq!(&*back, "hello");
147 }
148}