wp_model_core/model/data/
field_ref.rs1use crate::model::Field;
4use crate::model::data::storage::FieldStorage;
5use crate::model::{DataType, Value};
6
7#[derive(Clone, Copy)]
33pub struct FieldRef<'a> {
34 pub(crate) storage: &'a FieldStorage,
35}
36
37impl<'a> FieldRef<'a> {
38 #[inline]
40 pub fn get_name(&self) -> &'a str {
41 self.storage.get_name()
42 }
43
44 #[inline]
46 pub fn get_meta(&self) -> &'a DataType {
47 self.storage.as_field().get_meta()
48 }
49
50 #[inline]
52 pub fn get_value(&self) -> &'a Value {
53 self.storage.as_field().get_value()
54 }
55
56 pub fn to_owned(self) -> Field<Value> {
60 self.storage.clone().into_owned()
61 }
62
63 #[inline]
65 pub fn is_shared(&self) -> bool {
66 self.storage.is_shared()
67 }
68
69 #[inline]
71 pub fn has_name_override(&self) -> bool {
72 self.storage.cur_name.is_some()
73 }
74
75 #[inline]
79 pub fn shared_count(&self) -> Option<usize> {
80 self.storage.shared_count()
81 }
82}
83
84impl<'a> std::fmt::Debug for FieldRef<'a> {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 f.debug_struct("FieldRef")
89 .field("name", &self.get_name())
90 .field("meta", &self.get_meta())
91 .field("value", &self.get_value())
92 .field("is_shared", &self.is_shared())
93 .field("has_override", &self.has_name_override())
94 .finish()
95 }
96}
97
98impl<'a> std::fmt::Display for FieldRef<'a> {
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100 write!(f, "{}={:?}", self.get_name(), self.get_value())
101 }
102}
103
104impl<'a> PartialEq<Field<Value>> for FieldRef<'a> {
105 fn eq(&self, other: &Field<Value>) -> bool {
106 self.get_name() == other.get_name()
107 && self.get_meta() == other.get_meta()
108 && self.get_value() == other.get_value()
109 }
110}
111
112impl<'a, 'b> PartialEq<FieldRef<'b>> for FieldRef<'a> {
113 fn eq(&self, other: &FieldRef<'b>) -> bool {
114 self.get_name() == other.get_name()
115 && self.get_meta() == other.get_meta()
116 && self.get_value() == other.get_value()
117 }
118}
119
120impl<'a> PartialEq<FieldRef<'a>> for Field<Value> {
121 fn eq(&self, other: &FieldRef<'a>) -> bool {
122 other == self
123 }
124}
125
126#[cfg(test)]
129mod tests {
130 use super::*;
131 use std::sync::Arc;
132
133 #[test]
134 fn test_field_ref_respects_cur_name() {
135 let field = Field::new(DataType::Chars, "old_name", Value::from("value"));
136 let mut storage = FieldStorage::from_owned(field);
137 storage.set_name("new_name");
138
139 let field_ref = storage.field_ref();
140
141 assert_eq!(field_ref.get_name(), "new_name");
142 assert_eq!(field_ref.get_value(), &Value::from("value"));
143
144 assert_eq!(storage.as_field().get_name(), "old_name");
146 }
147
148 #[test]
149 fn test_field_ref_no_cur_name() {
150 let field = Field::new(DataType::Digit, "count", Value::from(42));
151 let storage = FieldStorage::from_owned(field);
152
153 let field_ref = storage.field_ref();
154
155 assert_eq!(field_ref.get_name(), "count");
156 assert_eq!(field_ref.get_value(), &Value::from(42));
157 assert!(!field_ref.has_name_override());
158 }
159
160 #[test]
161 fn test_field_ref_shared_zero_copy() {
162 let field = Arc::new(Field::new(DataType::Chars, "original", Value::from("data")));
163 let arc_count_before = Arc::strong_count(&field);
164
165 let mut storage = FieldStorage::from_shared(field.clone());
166 storage.set_name("renamed");
167
168 let field_ref = storage.field_ref();
170 assert_eq!(Arc::strong_count(&field), arc_count_before + 1);
171
172 assert_eq!(field_ref.get_name(), "renamed");
173 assert_eq!(field_ref.get_value(), &Value::from("data"));
174 assert!(field_ref.is_shared());
175 assert!(field_ref.has_name_override());
176 }
177
178 #[test]
179 fn test_field_ref_to_owned() {
180 let mut storage =
181 FieldStorage::from_owned(Field::new(DataType::Digit, "count", Value::from(42)));
182 storage.set_name("total");
183
184 let field_ref = storage.field_ref();
185 let owned = field_ref.to_owned();
186
187 assert_eq!(owned.get_name(), "total");
188 assert_eq!(owned.get_value(), &Value::from(42));
189 }
190
191 #[test]
192 fn test_field_ref_shared_count() {
193 let field = Arc::new(Field::new(DataType::Chars, "name", Value::from("test")));
194 let storage1 = FieldStorage::from_shared(field.clone());
195 let storage2 = FieldStorage::from_shared(field.clone());
196
197 assert_eq!(storage1.field_ref().shared_count(), Some(3));
198 assert_eq!(storage2.field_ref().shared_count(), Some(3));
199 }
200
201 #[test]
202 fn test_field_ref_owned_no_shared_count() {
203 let storage =
204 FieldStorage::from_owned(Field::new(DataType::Chars, "name", Value::from("test")));
205
206 assert_eq!(storage.field_ref().shared_count(), None);
207 }
208
209 #[test]
210 fn test_field_ref_equality() {
211 let field1 = Field::new(DataType::Chars, "name", Value::from("Alice"));
212 let storage1 = FieldStorage::from_owned(field1.clone());
213
214 let field2 = Field::new(DataType::Chars, "name", Value::from("Alice"));
215 let storage2 = FieldStorage::from_owned(field2.clone());
216
217 assert_eq!(storage1.field_ref(), storage2.field_ref());
218 assert_eq!(storage1.field_ref(), field1);
219 assert_eq!(field2, storage2.field_ref());
220 }
221
222 #[test]
223 fn test_field_ref_inequality_with_cur_name() {
224 let mut storage1 =
225 FieldStorage::from_owned(Field::new(DataType::Chars, "name", Value::from("Alice")));
226 storage1.set_name("renamed");
227
228 let storage2 =
229 FieldStorage::from_owned(Field::new(DataType::Chars, "name", Value::from("Alice")));
230
231 assert_ne!(storage1.field_ref(), storage2.field_ref());
232 }
233
234 #[test]
235 fn test_field_ref_debug() {
236 let mut storage =
237 FieldStorage::from_owned(Field::new(DataType::Chars, "test", Value::from("value")));
238 storage.set_name("renamed");
239
240 let debug = format!("{:?}", storage.field_ref());
241 assert!(debug.contains("renamed"));
242 assert!(debug.contains("Chars"));
243 assert!(debug.contains("has_override: true"));
244 }
245
246 #[test]
247 fn test_field_ref_display() {
248 let storage =
249 FieldStorage::from_owned(Field::new(DataType::Digit, "count", Value::from(42)));
250
251 let display = format!("{}", storage.field_ref());
252 assert_eq!(display, "count=Digit(42)");
253 }
254
255 #[test]
256 fn test_field_ref_copy() {
257 let storage =
258 FieldStorage::from_owned(Field::new(DataType::Chars, "name", Value::from("test")));
259
260 let ref1 = storage.field_ref();
261 let ref2 = ref1; assert_eq!(ref1.get_name(), ref2.get_name());
264 }
265}