value_extra/
lib.rs

1//! # value-extra
2//!
3//! A tri-state `Patch<T>` type for partial update semantics.
4//!
5//! ## The Problem
6//!
7//! When handling partial updates (PATCH requests, config merging, etc.),
8//! `Option<T>` conflates two distinct states:
9//!
10//! - **Field is absent** → don't touch the existing value
11//! - **Field is explicitly null** → clear/reset the value
12//!
13//! ## The Solution
14//!
15//! `Patch<T>` provides three states:
16//!
17//! - `Patch::Some(T)` — set the field to this value
18//! - [`Patch::Empty`] — field was absent, leave unchanged
19//! - [`Patch::None`] — field was explicitly null, clear it
20//!
21//! ## Quick Start
22//!
23//! ```
24//! use value_extra::Patch;
25//!
26//! fn apply_name_patch(current: &mut Option<String>, patch: Patch<String>) {
27//!     match patch {
28//!         Patch::Some(new) => *current = Some(new),
29//!         Patch::None => *current = None,
30//!         Patch::Empty => {}
31//!     }
32//! }
33//! ```
34//!
35//! ## Serde Usage
36//!
37//! With the `serde` feature enabled:
38//!
39//! ```ignore
40//! #[derive(Deserialize, Serialize)]
41//! struct UserPatch {
42//!     #[serde(default, skip_serializing_if = "Patch::is_empty")]
43//!     name: Patch<String>,
44//! }
45//! ```
46//!
47//! | JSON Input | Patch State | Meaning |
48//! |------------|-------------|---------|
49//! | `{ "name": "Alice" }` | `Patch::Some("Alice")` | Set to value |
50//! | `{ "name": null }` | `Patch::None` | Explicitly clear |
51//! | `{ }` | `Patch::Empty` | Leave unchanged |
52
53#![cfg_attr(not(feature = "std"), no_std)]
54#![cfg_attr(docsrs, feature(doc_cfg))]
55
56#[cfg(not(feature = "std"))]
57extern crate alloc;
58
59use core::ops::Deref;
60
61/// A tri-state type for partial update semantics.
62///
63/// `Patch<T>` distinguishes between three states:
64///
65/// - `Patch::Some(T)` — a value is present
66/// - [`Patch::Empty`] — no value was provided (field absent)
67/// - [`Patch::None`] — value was explicitly set to null
68///
69/// This is particularly useful for PATCH/UPDATE operations where you need
70/// to distinguish between "don't change this field" and "clear this field".
71///
72/// # Examples
73///
74/// ```
75/// use value_extra::Patch;
76///
77/// let some = Patch::Some(42);
78/// let empty: Patch<i32> = Patch::Empty;
79/// let none: Patch<i32> = Patch::None;
80///
81/// assert!(some.is_some());
82/// assert!(empty.is_empty());
83/// assert!(none.is_none());
84/// ```
85#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
86#[must_use = "this `Patch` may contain a value that should be used"]
87pub enum Patch<T> {
88    /// A value is present.
89    Some(T),
90    /// No value was provided (field absent).
91    Empty,
92    /// Value was explicitly set to null.
93    None,
94}
95
96impl<T: Copy> Copy for Patch<T> {}
97
98impl<T> Patch<T> {
99    /// Returns `true` if the patch contains a value.
100    ///
101    /// # Examples
102    ///
103    /// ```
104    /// use value_extra::Patch;
105    ///
106    /// assert!(Patch::Some(42).is_some());
107    /// assert!(!Patch::<i32>::Empty.is_some());
108    /// assert!(!Patch::<i32>::None.is_some());
109    /// ```
110    #[inline]
111    pub fn is_some(&self) -> bool {
112        matches!(self, Patch::Some(_))
113    }
114
115    /// Returns `true` if the patch is empty (field absent).
116    ///
117    /// # Examples
118    ///
119    /// ```
120    /// use value_extra::Patch;
121    ///
122    /// assert!(Patch::<i32>::Empty.is_empty());
123    /// assert!(!Patch::Some(42).is_empty());
124    /// assert!(!Patch::<i32>::None.is_empty());
125    /// ```
126    #[inline]
127    pub fn is_empty(&self) -> bool {
128        matches!(self, Patch::Empty)
129    }
130
131    /// Returns `true` if the patch is explicitly null.
132    ///
133    /// # Examples
134    ///
135    /// ```
136    /// use value_extra::Patch;
137    ///
138    /// assert!(Patch::<i32>::None.is_none());
139    /// assert!(!Patch::Some(42).is_none());
140    /// assert!(!Patch::<i32>::Empty.is_none());
141    /// ```
142    #[inline]
143    pub fn is_none(&self) -> bool {
144        matches!(self, Patch::None)
145    }
146
147    /// Alias for [`is_none`](Self::is_none). Returns `true` if explicitly null.
148    ///
149    /// This alias may be clearer in JSON/API contexts where "null" is the term used.
150    #[inline]
151    pub fn is_null(&self) -> bool {
152        self.is_none()
153    }
154
155    /// Returns `true` if the patch contains the given value.
156    ///
157    /// # Examples
158    ///
159    /// ```
160    /// use value_extra::Patch;
161    ///
162    /// assert!(Patch::Some(42).contains(&42));
163    /// assert!(!Patch::Some(42).contains(&0));
164    /// assert!(!Patch::<i32>::Empty.contains(&42));
165    /// ```
166    #[inline]
167    pub fn contains<U>(&self, x: &U) -> bool
168    where
169        T: PartialEq<U>,
170    {
171        matches!(self, Patch::Some(v) if v == x)
172    }
173}
174
175impl<T> Patch<T> {
176    /// Converts from `&Patch<T>` to `Patch<&T>`.
177    ///
178    /// # Examples
179    ///
180    /// ```
181    /// use value_extra::Patch;
182    ///
183    /// let patch = Patch::Some(String::from("hello"));
184    /// assert_eq!(patch.as_ref(), Patch::Some(&String::from("hello")));
185    /// ```
186    #[inline]
187    pub fn as_ref(&self) -> Patch<&T> {
188        match *self {
189            Patch::Some(ref x) => Patch::Some(x),
190            Patch::Empty => Patch::Empty,
191            Patch::None => Patch::None,
192        }
193    }
194
195    /// Converts from `&mut Patch<T>` to `Patch<&mut T>`.
196    ///
197    /// # Examples
198    ///
199    /// ```
200    /// use value_extra::Patch;
201    ///
202    /// let mut patch = Patch::Some(42);
203    /// if let Patch::Some(v) = patch.as_mut() {
204    ///     *v = 100;
205    /// }
206    /// assert_eq!(patch, Patch::Some(100));
207    /// ```
208    #[inline]
209    pub fn as_mut(&mut self) -> Patch<&mut T> {
210        match *self {
211            Patch::Some(ref mut x) => Patch::Some(x),
212            Patch::Empty => Patch::Empty,
213            Patch::None => Patch::None,
214        }
215    }
216}
217
218impl<T: Deref> Patch<T> {
219    /// Converts from `&Patch<T>` to `Patch<&T::Target>`.
220    ///
221    /// Useful for converting `Patch<String>` to `Patch<&str>`.
222    ///
223    /// # Examples
224    ///
225    /// ```
226    /// use value_extra::Patch;
227    ///
228    /// let patch = Patch::Some(String::from("hello"));
229    /// assert_eq!(patch.as_deref(), Patch::Some("hello"));
230    /// ```
231    #[inline]
232    pub fn as_deref(&self) -> Patch<&<T as Deref>::Target> {
233        self.as_ref().map(|t| t.deref())
234    }
235}
236
237impl<T> Patch<T> {
238    /// Maps a `Patch<T>` to `Patch<U>` by applying a function to the contained value.
239    ///
240    /// `Empty` and `None` are propagated unchanged.
241    ///
242    /// # Examples
243    ///
244    /// ```
245    /// use value_extra::Patch;
246    ///
247    /// let patch = Patch::Some(21);
248    /// assert_eq!(patch.map(|x| x * 2), Patch::Some(42));
249    ///
250    /// let empty: Patch<i32> = Patch::Empty;
251    /// assert_eq!(empty.map(|x| x * 2), Patch::Empty);
252    /// ```
253    #[inline]
254    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Patch<U> {
255        match self {
256            Patch::Some(x) => Patch::Some(f(x)),
257            Patch::Empty => Patch::Empty,
258            Patch::None => Patch::None,
259        }
260    }
261
262    /// Returns the provided default if `Empty` or `None`, otherwise applies `f` to the value.
263    ///
264    /// # Examples
265    ///
266    /// ```
267    /// use value_extra::Patch;
268    ///
269    /// assert_eq!(Patch::Some(21).map_or(0, |x| x * 2), 42);
270    /// assert_eq!(Patch::<i32>::Empty.map_or(0, |x| x * 2), 0);
271    /// assert_eq!(Patch::<i32>::None.map_or(0, |x| x * 2), 0);
272    /// ```
273    #[inline]
274    pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
275        match self {
276            Patch::Some(x) => f(x),
277            Patch::Empty | Patch::None => default,
278        }
279    }
280
281    /// Computes a default from a closure if `Empty` or `None`, otherwise applies `f`.
282    ///
283    /// # Examples
284    ///
285    /// ```
286    /// use value_extra::Patch;
287    ///
288    /// let result = Patch::Some(21).map_or_else(|| 0, |x| x * 2);
289    /// assert_eq!(result, 42);
290    /// ```
291    #[inline]
292    pub fn map_or_else<U, D, F>(self, default: D, f: F) -> U
293    where
294        D: FnOnce() -> U,
295        F: FnOnce(T) -> U,
296    {
297        match self {
298            Patch::Some(x) => f(x),
299            Patch::Empty | Patch::None => default(),
300        }
301    }
302
303    /// Calls `f` with the value if `Some`, returning the result.
304    ///
305    /// `Empty` and `None` are propagated unchanged.
306    ///
307    /// # Examples
308    ///
309    /// ```
310    /// use value_extra::Patch;
311    ///
312    /// fn parse_positive(s: String) -> Patch<u32> {
313    ///     s.parse::<u32>().ok().filter(|&n| n > 0).into()
314    /// }
315    ///
316    /// assert_eq!(Patch::Some("42".to_string()).and_then(parse_positive), Patch::Some(42));
317    /// assert_eq!(Patch::Some("0".to_string()).and_then(parse_positive), Patch::None);
318    /// assert_eq!(Patch::<String>::Empty.and_then(parse_positive), Patch::Empty);
319    /// ```
320    #[inline]
321    pub fn and_then<U, F>(self, f: F) -> Patch<U>
322    where
323        F: FnOnce(T) -> Patch<U>,
324    {
325        match self {
326            Patch::Some(x) => f(x),
327            Patch::Empty => Patch::Empty,
328            Patch::None => Patch::None,
329        }
330    }
331
332    /// Returns `Patch::None` if the predicate returns `false`, otherwise returns `self`.
333    ///
334    /// # Examples
335    ///
336    /// ```
337    /// use value_extra::Patch;
338    ///
339    /// assert_eq!(Patch::Some(42).filter(|&x| x > 0), Patch::Some(42));
340    /// assert_eq!(Patch::Some(-1).filter(|&x| x > 0), Patch::None);
341    /// assert_eq!(Patch::<i32>::Empty.filter(|&x| x > 0), Patch::Empty);
342    /// ```
343    #[inline]
344    pub fn filter<P>(self, predicate: P) -> Patch<T>
345    where
346        P: FnOnce(&T) -> bool,
347    {
348        match self {
349            Patch::Some(x) if predicate(&x) => Patch::Some(x),
350            Patch::Some(_) => Patch::None,
351            Patch::Empty => Patch::Empty,
352            Patch::None => Patch::None,
353        }
354    }
355}
356
357impl<T> Patch<T> {
358    /// Returns the contained value, panicking with a custom message if not `Some`.
359    ///
360    /// # Panics
361    ///
362    /// Panics if the patch is `Empty` or `None`.
363    ///
364    /// # Examples
365    ///
366    /// ```
367    /// use value_extra::Patch;
368    ///
369    /// assert_eq!(Patch::Some(42).expect("should have value"), 42);
370    /// ```
371    #[inline]
372    pub fn expect(self, msg: &str) -> T {
373        match self {
374            Patch::Some(x) => x,
375            Patch::Empty => panic!("{msg}"),
376            Patch::None => panic!("{msg}"),
377        }
378    }
379
380    /// Returns the contained value, panicking if not `Some`.
381    ///
382    /// # Panics
383    ///
384    /// Panics if the patch is `Empty` or `None`.
385    ///
386    /// # Examples
387    ///
388    /// ```
389    /// use value_extra::Patch;
390    ///
391    /// assert_eq!(Patch::Some(42).unwrap(), 42);
392    /// ```
393    #[inline]
394    pub fn unwrap(self) -> T {
395        match self {
396            Patch::Some(x) => x,
397            Patch::Empty => panic!("called `Patch::unwrap()` on an `Empty` value"),
398            Patch::None => panic!("called `Patch::unwrap()` on a `None` value"),
399        }
400    }
401
402    /// Returns the contained value or a default.
403    ///
404    /// # Examples
405    ///
406    /// ```
407    /// use value_extra::Patch;
408    ///
409    /// assert_eq!(Patch::Some(42).unwrap_or(0), 42);
410    /// assert_eq!(Patch::<i32>::Empty.unwrap_or(0), 0);
411    /// assert_eq!(Patch::<i32>::None.unwrap_or(0), 0);
412    /// ```
413    #[inline]
414    pub fn unwrap_or(self, default: T) -> T {
415        match self {
416            Patch::Some(x) => x,
417            Patch::Empty | Patch::None => default,
418        }
419    }
420
421    /// Returns the contained value or computes it from a closure.
422    ///
423    /// # Examples
424    ///
425    /// ```
426    /// use value_extra::Patch;
427    ///
428    /// assert_eq!(Patch::Some(42).unwrap_or_else(|| 0), 42);
429    /// assert_eq!(Patch::<i32>::Empty.unwrap_or_else(|| 100), 100);
430    /// ```
431    #[inline]
432    pub fn unwrap_or_else<F>(self, f: F) -> T
433    where
434        F: FnOnce() -> T,
435    {
436        match self {
437            Patch::Some(x) => x,
438            Patch::Empty | Patch::None => f(),
439        }
440    }
441}
442
443impl<T: Default> Patch<T> {
444    /// Returns the contained value or the default for `T`.
445    ///
446    /// # Examples
447    ///
448    /// ```
449    /// use value_extra::Patch;
450    ///
451    /// assert_eq!(Patch::Some(42).unwrap_or_default(), 42);
452    /// assert_eq!(Patch::<i32>::Empty.unwrap_or_default(), 0);
453    /// ```
454    #[inline]
455    pub fn unwrap_or_default(self) -> T {
456        self.unwrap_or(T::default())
457    }
458}
459
460impl<T> Patch<T> {
461    /// Returns `self` if it contains a value, otherwise returns `other`.
462    ///
463    /// # Examples
464    ///
465    /// ```
466    /// use value_extra::Patch;
467    ///
468    /// assert_eq!(Patch::Some(1).or(Patch::Some(2)), Patch::Some(1));
469    /// assert_eq!(Patch::<i32>::Empty.or(Patch::Some(2)), Patch::Some(2));
470    /// assert_eq!(Patch::<i32>::None.or(Patch::Some(2)), Patch::Some(2));
471    /// ```
472    #[inline]
473    pub fn or(self, other: Patch<T>) -> Patch<T> {
474        match self {
475            Patch::Some(_) => self,
476            Patch::Empty | Patch::None => other,
477        }
478    }
479
480    /// Returns `self` if it contains a value, otherwise calls `f`.
481    ///
482    /// # Examples
483    ///
484    /// ```
485    /// use value_extra::Patch;
486    ///
487    /// assert_eq!(Patch::Some(1).or_else(|| Patch::Some(2)), Patch::Some(1));
488    /// assert_eq!(Patch::<i32>::Empty.or_else(|| Patch::Some(2)), Patch::Some(2));
489    /// ```
490    #[inline]
491    pub fn or_else<F>(self, f: F) -> Patch<T>
492    where
493        F: FnOnce() -> Patch<T>,
494    {
495        match self {
496            Patch::Some(_) => self,
497            Patch::Empty | Patch::None => f(),
498        }
499    }
500
501    /// Returns `Some` if exactly one of `self` or `other` is `Some`.
502    ///
503    /// # Examples
504    ///
505    /// ```
506    /// use value_extra::Patch;
507    ///
508    /// assert_eq!(Patch::Some(1).xor(Patch::<i32>::Empty), Patch::Some(1));
509    /// assert_eq!(Patch::<i32>::None.xor(Patch::Some(2)), Patch::Some(2));
510    /// assert_eq!(Patch::Some(1).xor(Patch::Some(2)), Patch::None);
511    /// assert_eq!(Patch::<i32>::Empty.xor(Patch::<i32>::None), Patch::Empty);
512    /// assert_eq!(Patch::<i32>::None.xor(Patch::<i32>::None), Patch::None);
513    /// ```
514    #[inline]
515    pub fn xor(self, other: Patch<T>) -> Patch<T> {
516        match (self, other) {
517            (Patch::Some(a), Patch::Empty | Patch::None) => Patch::Some(a),
518            (Patch::Empty | Patch::None, Patch::Some(b)) => Patch::Some(b),
519            (Patch::Empty, Patch::None) | (Patch::None, Patch::Empty) => Patch::Empty,
520            _ => Patch::None,
521        }
522    }
523
524    /// Zips `self` with another `Patch`.
525    ///
526    /// Returns `Some((a, b))` if both are `Some`, otherwise propagates `Empty` or `None`.
527    ///
528    /// # Examples
529    ///
530    /// ```
531    /// use value_extra::Patch;
532    ///
533    /// assert_eq!(Patch::Some(1).zip(Patch::Some("a")), Patch::Some((1, "a")));
534    /// assert_eq!(Patch::Some(1).zip(Patch::<&str>::Empty), Patch::Empty);
535    /// assert_eq!(Patch::<i32>::None.zip(Patch::Some("a")), Patch::None);
536    /// ```
537    #[inline]
538    pub fn zip<U>(self, other: Patch<U>) -> Patch<(T, U)> {
539        match (self, other) {
540            (Patch::Some(a), Patch::Some(b)) => Patch::Some((a, b)),
541            (Patch::Empty, _) | (_, Patch::Empty) => Patch::Empty,
542            _ => Patch::None,
543        }
544    }
545
546    /// Zips `self` with another `Patch` using a function.
547    ///
548    /// # Examples
549    ///
550    /// ```
551    /// use value_extra::Patch;
552    ///
553    /// assert_eq!(Patch::Some(1).zip_with(Patch::Some(2), |a, b| a + b), Patch::Some(3));
554    /// ```
555    #[inline]
556    pub fn zip_with<U, R, F>(self, other: Patch<U>, f: F) -> Patch<R>
557    where
558        F: FnOnce(T, U) -> R,
559    {
560        self.zip(other).map(|(a, b)| f(a, b))
561    }
562}
563
564impl<T> Patch<T> {
565    /// Inserts a value, returning a mutable reference to it.
566    ///
567    /// # Examples
568    ///
569    /// ```
570    /// use value_extra::Patch;
571    ///
572    /// let mut patch = Patch::<i32>::Empty;
573    /// let v = patch.insert(42);
574    /// assert_eq!(*v, 42);
575    /// ```
576    #[inline]
577    pub fn insert(&mut self, value: T) -> &mut T {
578        *self = Patch::Some(value);
579        match self {
580            Patch::Some(v) => v,
581            _ => unreachable!(),
582        }
583    }
584
585    /// Inserts a value if `Empty` or `None`, returning a mutable reference.
586    ///
587    /// # Examples
588    ///
589    /// ```
590    /// use value_extra::Patch;
591    ///
592    /// let mut patch = Patch::<i32>::Empty;
593    /// assert_eq!(*patch.get_or_insert(42), 42);
594    ///
595    /// let mut patch = Patch::Some(1);
596    /// assert_eq!(*patch.get_or_insert(42), 1);
597    /// ```
598    #[inline]
599    pub fn get_or_insert(&mut self, value: T) -> &mut T {
600        if !self.is_some() {
601            *self = Patch::Some(value);
602        }
603        match self {
604            Patch::Some(v) => v,
605            _ => unreachable!(),
606        }
607    }
608
609    /// Inserts a value computed from a closure if `Empty` or `None`.
610    ///
611    /// # Examples
612    ///
613    /// ```
614    /// use value_extra::Patch;
615    ///
616    /// let mut patch = Patch::<i32>::Empty;
617    /// assert_eq!(*patch.get_or_insert_with(|| 42), 42);
618    /// ```
619    #[inline]
620    pub fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
621    where
622        F: FnOnce() -> T,
623    {
624        if !self.is_some() {
625            *self = Patch::Some(f());
626        }
627        match self {
628            Patch::Some(v) => v,
629            _ => unreachable!(),
630        }
631    }
632
633    /// Takes the value out, leaving `Empty` in its place.
634    ///
635    /// # Examples
636    ///
637    /// ```
638    /// use value_extra::Patch;
639    ///
640    /// let mut patch = Patch::Some(42);
641    /// let taken = patch.take();
642    /// assert_eq!(taken, Patch::Some(42));
643    /// assert_eq!(patch, Patch::Empty);
644    /// ```
645    #[inline]
646    pub fn take(&mut self) -> Patch<T> {
647        core::mem::replace(self, Patch::Empty)
648    }
649
650    /// Replaces the value, returning the old one.
651    ///
652    /// # Examples
653    ///
654    /// ```
655    /// use value_extra::Patch;
656    ///
657    /// let mut patch = Patch::Some(42);
658    /// let old = patch.replace(100);
659    /// assert_eq!(old, Patch::Some(42));
660    /// assert_eq!(patch, Patch::Some(100));
661    /// ```
662    #[inline]
663    pub fn replace(&mut self, value: T) -> Patch<T> {
664        core::mem::replace(self, Patch::Some(value))
665    }
666}
667
668impl<T: Default> Patch<T> {
669    /// Inserts the default value if `Empty` or `None`, returning a mutable reference.
670    ///
671    /// # Examples
672    ///
673    /// ```
674    /// use value_extra::Patch;
675    ///
676    /// let mut patch = Patch::<i32>::Empty;
677    /// assert_eq!(*patch.get_or_insert_default(), 0);
678    /// ```
679    #[inline]
680    pub fn get_or_insert_default(&mut self) -> &mut T {
681        self.get_or_insert_with(T::default)
682    }
683}
684
685impl<T: Clone> Patch<&T> {
686    /// Maps a `Patch<&T>` to a `Patch<T>` by cloning.
687    ///
688    /// # Examples
689    ///
690    /// ```
691    /// use value_extra::Patch;
692    ///
693    /// let value = String::from("hello");
694    /// let patch = Patch::Some(&value);
695    /// assert_eq!(patch.cloned(), Patch::Some(String::from("hello")));
696    /// ```
697    #[inline]
698    pub fn cloned(self) -> Patch<T> {
699        self.map(|t| t.clone())
700    }
701}
702
703impl<T: Copy> Patch<&T> {
704    /// Maps a `Patch<&T>` to a `Patch<T>` by copying.
705    ///
706    /// # Examples
707    ///
708    /// ```
709    /// use value_extra::Patch;
710    ///
711    /// let value = 42;
712    /// let patch = Patch::Some(&value);
713    /// assert_eq!(patch.copied(), Patch::Some(42));
714    /// ```
715    #[inline]
716    pub fn copied(self) -> Patch<T> {
717        self.map(|&t| t)
718    }
719}
720
721impl<T> Patch<T> {
722    /// Converts the patch to an `Option`, treating `Empty` and `None` as `Option::None`.
723    ///
724    /// # Examples
725    ///
726    /// ```
727    /// use value_extra::Patch;
728    ///
729    /// assert_eq!(Patch::Some(42).into_option(), Some(42));
730    /// assert_eq!(Patch::<i32>::Empty.into_option(), None);
731    /// assert_eq!(Patch::<i32>::None.into_option(), None);
732    /// ```
733    #[inline]
734    pub fn into_option(self) -> Option<T> {
735        match self {
736            Patch::Some(v) => Some(v),
737            Patch::Empty | Patch::None => None,
738        }
739    }
740}
741
742impl<T> Default for Patch<T> {
743    /// Returns `Patch::Empty`.
744    #[inline]
745    fn default() -> Patch<T> {
746        Patch::Empty
747    }
748}
749
750impl<T> From<T> for Patch<T> {
751    /// Creates a `Patch::Some` from a value.
752    #[inline]
753    fn from(value: T) -> Patch<T> {
754        Patch::Some(value)
755    }
756}
757
758impl<T> From<Option<T>> for Patch<T> {
759    /// Converts `Option<T>` to `Patch<T>`.
760    ///
761    /// - `Some(v)` → `Patch::Some(v)`
762    /// - `None` → `Patch::None`
763    #[inline]
764    fn from(opt: Option<T>) -> Patch<T> {
765        match opt {
766            Some(v) => Patch::Some(v),
767            None => Patch::None,
768        }
769    }
770}
771
772impl<T> From<Patch<T>> for Option<T> {
773    /// Converts `Patch<T>` to `Option<T>`.
774    ///
775    /// Both `Empty` and `None` become `Option::None`.
776    #[inline]
777    fn from(patch: Patch<T>) -> Option<T> {
778        patch.into_option()
779    }
780}
781
782impl<T> From<Option<Option<T>>> for Patch<T> {
783    /// Converts `Option<Option<T>>` to `Patch<T>`.
784    ///
785    /// This is the canonical representation for serde:
786    /// - `None` → `Patch::Empty` (field absent)
787    /// - `Some(None)` → `Patch::None` (explicitly null)
788    /// - `Some(Some(v))` → `Patch::Some(v)`
789    #[inline]
790    fn from(value: Option<Option<T>>) -> Patch<T> {
791        match value {
792            None => Patch::Empty,
793            Some(None) => Patch::None,
794            Some(Some(v)) => Patch::Some(v),
795        }
796    }
797}
798
799impl<T> From<Patch<T>> for Option<Option<T>> {
800    /// Converts `Patch<T>` to `Option<Option<T>>`.
801    ///
802    /// - `Patch::Empty` → `None`
803    /// - `Patch::None` → `Some(None)`
804    /// - `Patch::Some(v)` → `Some(Some(v))`
805    #[inline]
806    fn from(patch: Patch<T>) -> Option<Option<T>> {
807        match patch {
808            Patch::Empty => None,
809            Patch::None => Some(None),
810            Patch::Some(v) => Some(Some(v)),
811        }
812    }
813}
814
815#[cfg(feature = "serde")]
816#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
817mod serde_impl {
818    use super::Patch;
819    use core::fmt;
820    use core::marker::PhantomData;
821    use serde::de::{self, Visitor};
822    use serde::{Deserialize, Deserializer, Serialize, Serializer};
823
824    impl<'de, T> Deserialize<'de> for Patch<T>
825    where
826        T: Deserialize<'de>,
827    {
828        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
829        where
830            D: Deserializer<'de>,
831        {
832            struct PatchVisitor<T>(PhantomData<T>);
833
834            impl<'de, T> Visitor<'de> for PatchVisitor<T>
835            where
836                T: Deserialize<'de>,
837            {
838                type Value = Patch<T>;
839
840                fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
841                    formatter.write_str("any value or null")
842                }
843
844                fn visit_none<E>(self) -> Result<Self::Value, E>
845                where
846                    E: de::Error,
847                {
848                    Ok(Patch::None)
849                }
850
851                fn visit_unit<E>(self) -> Result<Self::Value, E>
852                where
853                    E: de::Error,
854                {
855                    Ok(Patch::None)
856                }
857
858                fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
859                where
860                    D: Deserializer<'de>,
861                {
862                    T::deserialize(deserializer).map(Patch::Some)
863                }
864            }
865
866            deserializer.deserialize_option(PatchVisitor(PhantomData))
867        }
868    }
869
870    impl<T> Serialize for Patch<T>
871    where
872        T: Serialize,
873    {
874        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
875        where
876            S: Serializer,
877        {
878            match self {
879                Patch::Some(v) => serializer.serialize_some(v),
880                Patch::Empty | Patch::None => serializer.serialize_none(),
881            }
882        }
883    }
884}
885
886#[cfg(test)]
887mod tests {
888    use super::*;
889
890    #[cfg(not(feature = "std"))]
891    use alloc::string::String;
892    #[cfg(feature = "std")]
893    use std::string::String;
894
895    #[test]
896    fn test_queries() {
897        assert!(Patch::Some(42).is_some());
898        assert!(!Patch::<i32>::Empty.is_some());
899        assert!(!Patch::<i32>::None.is_some());
900
901        assert!(!Patch::Some(42).is_empty());
902        assert!(Patch::<i32>::Empty.is_empty());
903        assert!(!Patch::<i32>::None.is_empty());
904
905        assert!(!Patch::Some(42).is_none());
906        assert!(!Patch::<i32>::Empty.is_none());
907        assert!(Patch::<i32>::None.is_none());
908
909        assert!(Patch::<i32>::None.is_null());
910    }
911
912    #[test]
913    fn test_contains() {
914        assert!(Patch::Some(42).contains(&42));
915        assert!(!Patch::Some(42).contains(&0));
916        assert!(!Patch::<i32>::Empty.contains(&42));
917        assert!(!Patch::<i32>::None.contains(&42));
918    }
919
920    #[test]
921    fn test_as_ref_as_mut() {
922        let patch = Patch::Some(42);
923        assert_eq!(patch.as_ref(), Patch::Some(&42));
924
925        let mut patch = Patch::Some(42);
926        if let Patch::Some(v) = patch.as_mut() {
927            *v = 100;
928        }
929        assert_eq!(patch, Patch::Some(100));
930    }
931
932    #[test]
933    fn test_map() {
934        assert_eq!(Patch::Some(21).map(|x| x * 2), Patch::Some(42));
935        assert_eq!(Patch::<i32>::Empty.map(|x| x * 2), Patch::Empty);
936        assert_eq!(Patch::<i32>::None.map(|x| x * 2), Patch::None);
937    }
938
939    #[test]
940    fn test_map_or() {
941        assert_eq!(Patch::Some(21).map_or(0, |x| x * 2), 42);
942        assert_eq!(Patch::<i32>::Empty.map_or(0, |x| x * 2), 0);
943        assert_eq!(Patch::<i32>::None.map_or(0, |x| x * 2), 0);
944    }
945
946    #[test]
947    fn test_and_then() {
948        let double = |x: i32| Patch::Some(x * 2);
949        assert_eq!(Patch::Some(21).and_then(double), Patch::Some(42));
950        assert_eq!(Patch::<i32>::Empty.and_then(double), Patch::Empty);
951        assert_eq!(Patch::<i32>::None.and_then(double), Patch::None);
952    }
953
954    #[test]
955    fn test_filter() {
956        assert_eq!(Patch::Some(42).filter(|&x| x > 0), Patch::Some(42));
957        assert_eq!(Patch::Some(-1).filter(|&x| x > 0), Patch::None);
958        assert_eq!(Patch::<i32>::Empty.filter(|&x| x > 0), Patch::Empty);
959    }
960
961    #[test]
962    fn test_unwrap_variants() {
963        assert_eq!(Patch::Some(42).unwrap(), 42);
964        assert_eq!(Patch::Some(42).unwrap_or(0), 42);
965        assert_eq!(Patch::<i32>::Empty.unwrap_or(0), 0);
966        assert_eq!(Patch::<i32>::None.unwrap_or(0), 0);
967        assert_eq!(Patch::<i32>::Empty.unwrap_or_else(|| 100), 100);
968        assert_eq!(Patch::<i32>::Empty.unwrap_or_default(), 0);
969    }
970
971    #[test]
972    #[should_panic(expected = "called `Patch::unwrap()` on an `Empty` value")]
973    fn test_unwrap_empty_panics() {
974        Patch::<i32>::Empty.unwrap();
975    }
976
977    #[test]
978    #[should_panic(expected = "called `Patch::unwrap()` on a `None` value")]
979    fn test_unwrap_none_panics() {
980        Patch::<i32>::None.unwrap();
981    }
982
983    #[test]
984    fn test_or_combinators() {
985        assert_eq!(Patch::Some(1).or(Patch::Some(2)), Patch::Some(1));
986        assert_eq!(Patch::<i32>::Empty.or(Patch::Some(2)), Patch::Some(2));
987        assert_eq!(Patch::<i32>::None.or(Patch::Some(2)), Patch::Some(2));
988
989        assert_eq!(Patch::Some(1).or_else(|| Patch::Some(2)), Patch::Some(1));
990        assert_eq!(
991            Patch::<i32>::Empty.or_else(|| Patch::Some(2)),
992            Patch::Some(2)
993        );
994    }
995
996    #[test]
997    fn test_xor() {
998        assert_eq!(Patch::Some(1).xor(Patch::<i32>::Empty), Patch::Some(1));
999        assert_eq!(Patch::<i32>::Empty.xor(Patch::Some(2)), Patch::Some(2));
1000        assert_eq!(Patch::<i32>::Empty.xor(Patch::<i32>::None), Patch::Empty);
1001        assert_eq!(Patch::Some(1).xor(Patch::Some(2)), Patch::None);
1002        assert_eq!(Patch::<i32>::Empty.xor(Patch::<i32>::Empty), Patch::None);
1003        assert_eq!(Patch::<i32>::None.xor(Patch::<i32>::None), Patch::None);
1004    }
1005
1006    #[test]
1007    fn test_zip() {
1008        assert_eq!(Patch::Some(1).zip(Patch::Some("a")), Patch::Some((1, "a")));
1009        assert_eq!(Patch::Some(1).zip(Patch::<&str>::Empty), Patch::Empty);
1010        assert_eq!(Patch::<i32>::None.zip(Patch::Some("a")), Patch::None);
1011    }
1012
1013    #[test]
1014    fn test_mutation_methods() {
1015        let mut patch = Patch::<i32>::Empty;
1016        assert_eq!(*patch.insert(42), 42);
1017        assert_eq!(patch, Patch::Some(42));
1018
1019        let mut patch = Patch::<i32>::Empty;
1020        assert_eq!(*patch.get_or_insert(42), 42);
1021
1022        let mut patch = Patch::Some(1);
1023        assert_eq!(*patch.get_or_insert(42), 1);
1024
1025        let mut patch = Patch::Some(42);
1026        let taken = patch.take();
1027        assert_eq!(taken, Patch::Some(42));
1028        assert_eq!(patch, Patch::Empty);
1029
1030        let mut patch = Patch::Some(42);
1031        let old = patch.replace(100);
1032        assert_eq!(old, Patch::Some(42));
1033        assert_eq!(patch, Patch::Some(100));
1034    }
1035
1036    #[test]
1037    fn test_conversions() {
1038        // From<T>
1039        let patch: Patch<i32> = 42.into();
1040        assert_eq!(patch, Patch::Some(42));
1041
1042        // From<Option<T>>
1043        let patch: Patch<i32> = Some(42).into();
1044        assert_eq!(patch, Patch::Some(42));
1045        let patch: Patch<i32> = Option::<i32>::None.into();
1046        assert_eq!(patch, Patch::None);
1047
1048        // From<Patch<T>> for Option<T>
1049        let opt: Option<i32> = Patch::Some(42).into();
1050        assert_eq!(opt, Some(42));
1051        let opt: Option<i32> = Patch::<i32>::Empty.into();
1052        assert_eq!(opt, None);
1053
1054        // Option<Option<T>> round-trip
1055        let patch: Patch<i32> = Option::<Option<i32>>::None.into();
1056        assert_eq!(patch, Patch::Empty);
1057        let patch: Patch<i32> = Some(None).into();
1058        assert_eq!(patch, Patch::None);
1059        let patch: Patch<i32> = Some(Some(42)).into();
1060        assert_eq!(patch, Patch::Some(42));
1061
1062        let opt: Option<Option<i32>> = Patch::<i32>::Empty.into();
1063        assert_eq!(opt, None);
1064        let opt: Option<Option<i32>> = Patch::<i32>::None.into();
1065        assert_eq!(opt, Some(None));
1066        let opt: Option<Option<i32>> = Patch::<i32>::Some(42).into();
1067        assert_eq!(opt, Some(Some(42)));
1068    }
1069
1070    #[test]
1071    fn test_default() {
1072        let patch: Patch<i32> = Patch::default();
1073        assert_eq!(patch, Patch::Empty);
1074    }
1075
1076    #[test]
1077    fn test_clone_copy() {
1078        let patch = Patch::Some(String::from("hello"));
1079        let cloned = patch.clone();
1080        assert_eq!(patch, cloned);
1081
1082        let patch = Patch::Some(42);
1083        let copied = patch;
1084        assert_eq!(patch, copied);
1085    }
1086
1087    #[test]
1088    fn test_cloned_copied() {
1089        let value = 42;
1090        let patch = Patch::Some(&value);
1091        assert_eq!(patch.copied(), Patch::Some(42));
1092
1093        let s = String::from("hello");
1094        let patch = Patch::Some(&s);
1095        assert_eq!(patch.cloned(), Patch::Some(String::from("hello")));
1096    }
1097
1098    #[test]
1099    fn test_as_deref() {
1100        let patch = Patch::Some(String::from("hello"));
1101        assert_eq!(patch.as_deref(), Patch::Some("hello"));
1102
1103        let empty: Patch<String> = Patch::Empty;
1104        assert_eq!(empty.as_deref(), Patch::Empty);
1105    }
1106
1107    #[test]
1108    fn test_ord() {
1109        assert!(Patch::Some(1) < Patch::Some(2));
1110        assert!(Patch::<i32>::Empty < Patch::<i32>::None);
1111        assert!(Patch::Some(1) < Patch::<i32>::Empty);
1112    }
1113
1114    #[test]
1115    #[cfg(feature = "std")]
1116    fn test_hash() {
1117        use core::hash::{Hash, Hasher};
1118        use std::collections::hash_map::DefaultHasher;
1119
1120        fn hash<T: Hash>(t: &T) -> u64 {
1121            let mut s = DefaultHasher::new();
1122            t.hash(&mut s);
1123            s.finish()
1124        }
1125
1126        assert_eq!(hash(&Patch::Some(42)), hash(&Patch::Some(42)));
1127        assert_ne!(hash(&Patch::Some(42)), hash(&Patch::Some(0)));
1128        assert_ne!(hash(&Patch::<i32>::Empty), hash(&Patch::<i32>::None));
1129    }
1130}
1131
1132#[cfg(all(test, feature = "serde"))]
1133mod serde_tests {
1134    use super::*;
1135    use serde::{Deserialize, Serialize};
1136
1137    #[derive(Debug, Deserialize, Serialize, PartialEq)]
1138    struct TestStruct {
1139        #[serde(default, skip_serializing_if = "Patch::is_empty")]
1140        value: Patch<i32>,
1141    }
1142
1143    #[test]
1144    fn test_deserialize_some() {
1145        let json = r#"{"value": 42}"#;
1146        let s: TestStruct = serde_json::from_str(json).unwrap();
1147        assert_eq!(s.value, Patch::Some(42));
1148    }
1149
1150    #[test]
1151    fn test_deserialize_null() {
1152        let json = r#"{"value": null}"#;
1153        let s: TestStruct = serde_json::from_str(json).unwrap();
1154        assert_eq!(s.value, Patch::None);
1155    }
1156
1157    #[test]
1158    fn test_deserialize_missing() {
1159        let json = r#"{}"#;
1160        let s: TestStruct = serde_json::from_str(json).unwrap();
1161        assert_eq!(s.value, Patch::Empty);
1162    }
1163
1164    #[test]
1165    fn test_serialize_some() {
1166        let s = TestStruct {
1167            value: Patch::Some(42),
1168        };
1169        let json = serde_json::to_string(&s).unwrap();
1170        assert_eq!(json, r#"{"value":42}"#);
1171    }
1172
1173    #[test]
1174    fn test_serialize_none() {
1175        let s = TestStruct { value: Patch::None };
1176        let json = serde_json::to_string(&s).unwrap();
1177        assert_eq!(json, r#"{"value":null}"#);
1178    }
1179
1180    #[test]
1181    fn test_serialize_empty() {
1182        let s = TestStruct {
1183            value: Patch::Empty,
1184        };
1185        let json = serde_json::to_string(&s).unwrap();
1186        assert_eq!(json, r#"{}"#);
1187    }
1188
1189    #[test]
1190    fn test_roundtrip() {
1191        let original = TestStruct {
1192            value: Patch::Some(42),
1193        };
1194        let json = serde_json::to_string(&original).unwrap();
1195        let parsed: TestStruct = serde_json::from_str(&json).unwrap();
1196        assert_eq!(original, parsed);
1197    }
1198}