1use alloc::boxed::Box;
8use core::fmt;
9use core::ops::Deref;
10
11pub trait DefaultInstance: Default + 'static {
53 fn default_instance() -> &'static Self;
55}
56
57pub struct MessageField<T: Default> {
81 inner: Option<Box<T>>,
82}
83
84impl<T: Default> MessageField<T> {
85 #[inline]
87 pub const fn none() -> Self {
88 Self { inner: None }
89 }
90
91 #[inline]
93 pub fn some(value: T) -> Self {
94 Self {
95 inner: Some(Box::new(value)),
96 }
97 }
98
99 #[inline]
101 pub fn from_box(value: Box<T>) -> Self {
102 Self { inner: Some(value) }
103 }
104
105 #[inline]
107 pub fn is_set(&self) -> bool {
108 self.inner.is_some()
109 }
110
111 #[inline]
113 pub fn is_unset(&self) -> bool {
114 self.inner.is_none()
115 }
116
117 #[inline]
119 pub fn as_option(&self) -> Option<&T> {
120 self.inner.as_deref()
121 }
122
123 #[inline]
125 pub fn as_option_mut(&mut self) -> Option<&mut T> {
126 self.inner.as_deref_mut()
127 }
128
129 #[inline]
131 pub fn take(&mut self) -> Option<T> {
132 self.inner.take().map(|b| *b)
133 }
134
135 #[inline]
137 pub fn get_or_insert_default(&mut self) -> &mut T {
138 self.inner.get_or_insert_default()
139 }
140
141 #[inline]
163 pub fn modify<F: FnOnce(&mut T)>(&mut self, f: F) {
164 f(self.get_or_insert_default());
165 }
166
167 #[inline]
172 pub fn into_option(self) -> Option<T> {
173 self.inner.map(|b| *b)
174 }
175
176 #[inline]
185 pub fn ok_or<E>(self, err: E) -> Result<T, E> {
186 match self.inner {
187 Some(b) => Ok(*b),
188 None => Err(err),
189 }
190 }
191
192 #[inline]
204 pub fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
205 match self.inner {
206 Some(b) => Ok(*b),
207 None => Err(err()),
208 }
209 }
210}
211
212impl<T: Default> Default for MessageField<T> {
213 #[inline]
214 fn default() -> Self {
215 Self::none()
216 }
217}
218
219impl<T: DefaultInstance> Deref for MessageField<T> {
220 type Target = T;
221
222 #[inline]
223 fn deref(&self) -> &T {
224 match &self.inner {
225 Some(value) => value,
226 None => T::default_instance(),
227 }
228 }
229}
230
231impl<T: Default + Clone> Clone for MessageField<T> {
232 fn clone(&self) -> Self {
233 Self {
234 inner: self.inner.clone(),
235 }
236 }
237}
238
239impl<T: DefaultInstance + PartialEq> PartialEq for MessageField<T> {
240 fn eq(&self, other: &Self) -> bool {
241 match (&self.inner, &other.inner) {
242 (Some(a), Some(b)) => a == b,
243 (None, None) => true,
244 (Some(a), None) => **a == *T::default_instance(),
247 (None, Some(b)) => *T::default_instance() == **b,
248 }
249 }
250}
251
252impl<T: DefaultInstance + Eq + PartialEq> Eq for MessageField<T> {}
253
254impl<T: Default + fmt::Debug> fmt::Debug for MessageField<T> {
255 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
256 match &self.inner {
257 Some(value) => f.debug_tuple("MessageField::Set").field(value).finish(),
258 None => f.write_str("MessageField::Unset"),
259 }
260 }
261}
262
263impl<T: Default> From<Option<T>> for MessageField<T> {
264 fn from(opt: Option<T>) -> Self {
265 match opt {
266 Some(v) => Self::some(v),
267 None => Self::none(),
268 }
269 }
270}
271
272impl<T: Default> From<T> for MessageField<T> {
273 fn from(value: T) -> Self {
274 Self::some(value)
275 }
276}
277
278#[cfg(feature = "json")]
279impl<T: Default + serde::Serialize> serde::Serialize for MessageField<T> {
280 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
281 match self.inner.as_deref() {
282 Some(v) => s.serialize_some(v),
283 None => s.serialize_none(),
284 }
285 }
286}
287
288#[cfg(feature = "json")]
289impl<'de, T: Default + serde::Deserialize<'de>> serde::Deserialize<'de> for MessageField<T> {
290 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
291 Option::<T>::deserialize(d).map(|opt| match opt {
292 Some(v) => Self::some(v),
293 None => Self::none(),
294 })
295 }
296}
297
298#[cfg(feature = "arbitrary")]
299impl<'a, T: Default + arbitrary::Arbitrary<'a>> arbitrary::Arbitrary<'a> for MessageField<T> {
300 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
301 Ok(if bool::arbitrary(u)? {
302 MessageField::some(T::arbitrary(u)?)
303 } else {
304 MessageField::none()
305 })
306 }
307}
308
309#[cfg(test)]
310mod tests {
311 use super::*;
312
313 #[derive(Clone, Debug, Default, PartialEq)]
314 struct Inner {
315 value: i32,
316 name: alloc::string::String,
317 }
318
319 impl DefaultInstance for Inner {
320 fn default_instance() -> &'static Self {
321 static VALUE: crate::__private::OnceBox<Inner> = crate::__private::OnceBox::new();
322 VALUE.get_or_init(|| alloc::boxed::Box::new(Inner::default()))
323 }
324 }
325
326 #[test]
327 fn test_unset_derefs_to_default() {
328 let field: MessageField<Inner> = MessageField::none();
329 assert!(!field.is_set());
330 assert_eq!(field.value, 0);
331 assert_eq!(field.name, "");
332 }
333
334 #[test]
335 fn test_set_derefs_to_value() {
336 let field = MessageField::some(Inner {
337 value: 42,
338 name: "hello".into(),
339 });
340 assert!(field.is_set());
341 assert_eq!(field.value, 42);
342 assert_eq!(field.name, "hello");
343 }
344
345 #[test]
346 fn test_get_or_insert_default() {
347 let mut field: MessageField<Inner> = MessageField::none();
348 assert!(!field.is_set());
349 field.get_or_insert_default().value = 10;
350 assert!(field.is_set());
351 assert_eq!(field.value, 10);
352 }
353
354 #[test]
355 fn test_equality() {
356 let a: MessageField<Inner> = MessageField::none();
357 let b: MessageField<Inner> = MessageField::some(Inner::default());
358 assert_eq!(a, b);
360 }
361
362 #[test]
363 fn test_take() {
364 let mut field = MessageField::some(Inner {
365 value: 7,
366 name: "taken".into(),
367 });
368 let taken = field.take();
369 assert!(field.is_unset());
370 assert_eq!(taken.unwrap().value, 7);
371 }
372
373 #[test]
374 fn test_clone() {
375 let field = MessageField::some(Inner {
376 value: 99,
377 name: "clone".into(),
378 });
379 let cloned = field.clone();
380 assert_eq!(field, cloned);
381 }
382
383 #[test]
384 fn test_modify_initializes_unset_field() {
385 let mut field: MessageField<Inner> = MessageField::none();
386 field.modify(|inner| {
387 inner.value = 42;
388 inner.name = "hello".into();
389 });
390 assert!(field.is_set());
391 assert_eq!(field.value, 42);
392 assert_eq!(field.name, "hello");
393 }
394
395 #[test]
396 fn test_modify_updates_already_set_field() {
397 let mut field = MessageField::some(Inner {
398 value: 1,
399 name: "original".into(),
400 });
401 field.modify(|inner| {
402 inner.value = 99;
403 });
404 assert_eq!(field.value, 99);
406 assert_eq!(field.name, "original");
407 }
408
409 #[test]
410 fn test_modify_multiple_fields_in_one_call() {
411 let mut field: MessageField<Inner> = MessageField::none();
413 field.modify(|inner| {
414 inner.value = 10;
415 inner.name = "multi".into();
416 });
417 assert_eq!(field.value, 10);
418 assert_eq!(field.name, "multi");
419 }
420
421 #[test]
422 fn test_modify_noop_still_initializes_unset_field() {
423 let mut field: MessageField<Inner> = MessageField::none();
425 field.modify(|_| {});
426 assert!(field.is_set());
427 assert_eq!(field.value, 0);
428 assert_eq!(field.name, "");
429 }
430
431 #[test]
432 fn test_modify_closure_can_move_captured_values() {
433 let mut field: MessageField<Inner> = MessageField::none();
436 let name = alloc::string::String::from("moved");
437 field.modify(|inner| {
438 inner.name = name; });
440 assert_eq!(field.name, "moved");
441 }
442
443 #[cfg(feature = "json")]
444 mod serde_tests {
445 use super::*;
446
447 #[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
448 struct Msg {
449 value: i32,
450 }
451
452 #[test]
453 fn unset_serializes_as_null() {
454 let f: MessageField<Msg> = MessageField::none();
455 assert_eq!(serde_json::to_string(&f).unwrap(), "null");
456 }
457
458 #[test]
459 fn set_serializes_as_inner_json() {
460 let f = MessageField::some(Msg { value: 42 });
461 let json = serde_json::to_string(&f).unwrap();
462 assert_eq!(json, r#"{"value":42}"#);
463 }
464
465 #[test]
466 fn null_deserializes_as_unset() {
467 let f: MessageField<Msg> = serde_json::from_str("null").unwrap();
468 assert!(f.is_unset());
469 }
470
471 #[test]
472 fn object_deserializes_as_set() {
473 let f: MessageField<Msg> = serde_json::from_str(r#"{"value":7}"#).unwrap();
474 assert!(f.is_set());
475 assert_eq!(f.as_option().unwrap().value, 7);
476 }
477
478 #[test]
479 fn round_trip_set_field() {
480 let original = MessageField::some(Msg { value: 99 });
481 let json = serde_json::to_string(&original).unwrap();
482 let recovered: MessageField<Msg> = serde_json::from_str(&json).unwrap();
483 assert_eq!(
484 original.as_option().unwrap().value,
485 recovered.as_option().unwrap().value
486 );
487 }
488 }
489
490 #[test]
491 fn test_into_option_unboxes() {
492 let field = MessageField::some(Inner {
493 value: 5,
494 name: "x".into(),
495 });
496 let opt: Option<Inner> = field.into_option();
498 assert_eq!(opt.unwrap().value, 5);
499
500 let field: MessageField<Inner> = MessageField::none();
501 assert!(field.into_option().is_none());
502 }
503
504 #[test]
505 fn test_ok_or() {
506 let set = MessageField::some(Inner {
507 value: 1,
508 name: "set".into(),
509 });
510 let r: Result<Inner, &str> = set.ok_or("missing");
511 assert_eq!(r.unwrap().value, 1);
512
513 let unset: MessageField<Inner> = MessageField::none();
514 assert_eq!(unset.ok_or("missing"), Err("missing"));
515 }
516
517 #[test]
518 fn test_ok_or_else() {
519 let set = MessageField::some(Inner {
520 value: 2,
521 name: "set".into(),
522 });
523 assert_eq!(set.ok_or_else(|| "unreachable").unwrap().value, 2);
524
525 let unset: MessageField<Inner> = MessageField::none();
526 assert_eq!(unset.ok_or_else(|| "missing"), Err("missing"));
527 }
528
529 #[test]
530 fn test_ok_or_else_closure_not_called_when_set() {
531 let set = MessageField::some(Inner::default());
532 let _ = set.ok_or_else(|| -> &str { panic!("closure must not run") });
533 }
534
535 #[test]
536 fn test_ok_or_else_partial_move() {
537 #[derive(Default)]
541 struct Request {
542 a: MessageField<Inner>,
543 b: MessageField<Inner>,
544 }
545 let req = Request {
546 a: MessageField::some(Inner {
547 value: 1,
548 ..Default::default()
549 }),
550 b: MessageField::some(Inner {
551 value: 2,
552 ..Default::default()
553 }),
554 };
555 let a = req.a.ok_or_else(|| "missing a").unwrap();
556 let b = req.b.ok_or_else(|| "missing b").unwrap();
557 assert_eq!(a.value, 1);
558 assert_eq!(b.value, 2);
559 }
560
561 #[test]
562 fn test_from_conversions() {
563 let field: MessageField<Inner> = Inner {
564 value: 1,
565 name: "from".into(),
566 }
567 .into();
568 assert!(field.is_set());
569
570 let field: MessageField<Inner> = None.into();
571 assert!(field.is_unset());
572
573 let field: MessageField<Inner> = Some(Inner {
574 value: 2,
575 name: "some".into(),
576 })
577 .into();
578 assert!(field.is_set());
579 }
580}