dofigen_lib/
deserialize.rs

1use crate::{Error, dofigen_struct::*};
2#[cfg(feature = "json_schema")]
3use schemars::JsonSchema;
4use serde::{Deserialize, Deserializer, de};
5use std::{
6    cmp::Ordering,
7    collections::{BTreeMap, HashMap},
8    fmt,
9    hash::Hash,
10    marker::PhantomData,
11    usize,
12};
13#[cfg(feature = "permissive")]
14use std::{ops::Deref, str::FromStr};
15use struct_patch::{Merge, Patch};
16
17/// Implements the From trait for a struct from a patch
18macro_rules! impl_from_patch_and_add {
19    ($struct:ty, $patch:ty) => {
20        impl From<$patch> for $struct {
21            fn from(value: $patch) -> Self {
22                let mut s = Self::default();
23                s.apply(value);
24                s
25            }
26        }
27    };
28}
29
30impl_from_patch_and_add!(Dofigen, DofigenPatch);
31impl_from_patch_and_add!(Stage, StagePatch);
32impl_from_patch_and_add!(Healthcheck, HealthcheckPatch);
33impl_from_patch_and_add!(ImageName, ImageNamePatch);
34impl_from_patch_and_add!(Run, RunPatch);
35impl_from_patch_and_add!(Cache, CachePatch);
36impl_from_patch_and_add!(Bind, BindPatch);
37impl_from_patch_and_add!(TmpFs, TmpFsPatch);
38impl_from_patch_and_add!(Secret, SecretPatch);
39impl_from_patch_and_add!(Ssh, SshPatch);
40impl_from_patch_and_add!(Port, PortPatch);
41impl_from_patch_and_add!(User, UserPatch);
42impl_from_patch_and_add!(CopyOptions, CopyOptionsPatch);
43impl_from_patch_and_add!(Copy, CopyPatch);
44impl_from_patch_and_add!(CopyContent, CopyContentPatch);
45impl_from_patch_and_add!(Add, AddPatch);
46impl_from_patch_and_add!(AddGitRepo, AddGitRepoPatch);
47
48//////////////////////// Patch structures ////////////////////////
49
50/// A struct that can be parsed from a string
51#[cfg(feature = "permissive")]
52#[derive(Debug, Clone, PartialEq, Default)]
53pub struct ParsableStruct<T>(pub(crate) T)
54where
55    T: FromStr;
56
57/// One or many values
58#[cfg(feature = "permissive")]
59#[derive(Deserialize, Debug, Clone, PartialEq)]
60#[serde(from = "OneOrManyDeserializable<T>")]
61pub struct OneOrMany<T>(pub Vec<T>);
62
63/// Patch for Vec<T> that handle some commands based on the position:
64/// - `_` to replace the whole list
65/// - `+` to append to the list
66/// - `n` to replace the nth element
67/// - `n+` to append to the nth element
68/// - `+n` to prepend to the nth element
69#[derive(Deserialize, Debug, Clone, PartialEq, Default)]
70#[serde(from = "VecPatchDeserializable<T>")]
71pub struct VecPatch<T>
72where
73    T: Clone,
74{
75    commands: Vec<VecPatchCommand<T>>,
76}
77
78#[derive(Debug, Clone, PartialEq)]
79enum VecPatchCommand<T> {
80    ReplaceAll(Vec<T>),
81    Replace(usize, T),
82    InsertBefore(usize, Vec<T>),
83    InsertAfter(usize, Vec<T>),
84    Append(Vec<T>),
85}
86
87/// Patch for Vec<T> that handle some commands based on the position:
88/// - `_` to replace the whole list
89/// - `+` to append to the list
90/// - `n` to replace the nth element
91/// - `n<` to patch the nth element
92/// - `n+` to append to the nth element
93/// - `+n` to prepend to the nth element
94#[derive(Deserialize, Debug, Clone, PartialEq, Default)]
95#[serde(
96    from = "VecDeepPatchDeserializable<T, P>",
97    bound(deserialize = "T: Clone + From<P>, P: Clone + Deserialize<'de>")
98)]
99pub struct VecDeepPatch<T, P>
100where
101    T: Clone + Patch<P> + From<P>,
102    P: Clone,
103{
104    commands: Vec<VecDeepPatchCommand<T, P>>,
105}
106
107#[derive(Debug, Clone, PartialEq)]
108enum VecDeepPatchCommand<T, P>
109where
110    T: Clone,
111{
112    ReplaceAll(Vec<T>),
113    Replace(usize, T),
114    Patch(usize, P),
115    InsertBefore(usize, Vec<T>),
116    InsertAfter(usize, Vec<T>),
117    Append(Vec<T>),
118}
119
120#[derive(Deserialize, Debug, Clone, PartialEq, Default)]
121pub struct HashMapPatch<K, V>
122where
123    K: Clone + Eq + std::hash::Hash,
124    V: Clone,
125{
126    #[serde(flatten)]
127    patches: HashMap<K, Option<V>>,
128}
129
130#[derive(Deserialize, Debug, Clone, PartialEq, Default)]
131pub struct HashMapDeepPatch<K, V>
132where
133    K: Clone + Eq + std::hash::Hash,
134    V: Clone,
135{
136    #[serde(flatten)]
137    patches: HashMap<K, Option<V>>,
138}
139
140/// A multilevel key map
141#[cfg(not(feature = "strict"))]
142#[derive(Deserialize, Debug, Clone, PartialEq, Default)]
143#[cfg_attr(feature = "json_schema", derive(JsonSchema))]
144pub(crate) struct NestedMap<T>(HashMap<String, NestedMapValue<T>>);
145
146#[cfg(not(feature = "strict"))]
147#[derive(Deserialize, Debug, Clone, PartialEq)]
148#[cfg_attr(feature = "json_schema", derive(JsonSchema))]
149#[serde(untagged)]
150enum NestedMapValue<T> {
151    Value(T),
152    Map(NestedMap<T>),
153    Null,
154}
155
156//////////////////////// Deserialization structures ////////////////////////
157
158#[derive(Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
159#[serde(untagged)]
160enum StringOrNumber {
161    String(String),
162    Number(usize),
163}
164
165/// One or many for deserialization
166#[cfg(feature = "permissive")]
167#[derive(Deserialize, Debug, Clone, PartialEq)]
168#[serde(untagged)]
169#[cfg_attr(feature = "json_schema", derive(JsonSchema))]
170enum OneOrManyDeserializable<T> {
171    One(T),
172    Many(Vec<T>),
173}
174
175#[derive(Deserialize, Debug, Clone, PartialEq)]
176#[serde(untagged)]
177enum VecPatchDeserializable<T>
178where
179    T: Clone,
180{
181    #[cfg(feature = "permissive")]
182    Vec(OneOrMany<T>),
183    #[cfg(not(feature = "permissive"))]
184    Vec(Vec<T>),
185    Map(VecPatchCommandMap<T>),
186}
187
188#[derive(Debug, Clone, PartialEq)]
189struct VecPatchCommandMap<T>
190where
191    T: Clone,
192{
193    commands: Vec<VecPatchCommand<T>>,
194}
195
196#[derive(Deserialize, Debug, Clone, PartialEq)]
197#[serde(
198    untagged,
199    bound(deserialize = "T: Clone + From<P> + Patch<P>, P: Clone + Deserialize<'de>")
200)]
201enum VecDeepPatchDeserializable<T, P>
202where
203    T: Clone + From<P>,
204    P: Clone,
205{
206    Map(VecDeepPatchCommandMap<T, P>),
207    #[cfg(feature = "permissive")]
208    Vec(OneOrMany<P>),
209    #[cfg(not(feature = "permissive"))]
210    Vec(Vec<P>),
211}
212
213#[derive(Debug, Clone, PartialEq)]
214struct VecDeepPatchCommandMap<T, P>
215where
216    T: Clone,
217{
218    commands: Vec<VecDeepPatchCommand<T, P>>,
219}
220
221//////////////////////// Implementations ////////////////////////
222
223impl From<FromContextPatch> for FromContext {
224    fn from(patch: FromContextPatch) -> Self {
225        match patch {
226            FromContextPatch::FromImage(p) => FromContext::FromImage(p.into()),
227            FromContextPatch::FromBuilder(p) => FromContext::FromBuilder(p),
228            FromContextPatch::FromContext(p) => FromContext::FromContext(p),
229        }
230    }
231}
232
233impl From<ImageName> for FromContext {
234    fn from(image: ImageName) -> Self {
235        FromContext::FromImage(image)
236    }
237}
238
239impl Default for FromContext {
240    fn default() -> Self {
241        FromContext::FromContext(None)
242    }
243}
244
245impl FromContext {
246    pub fn is_empty(&self) -> bool {
247        match self {
248            FromContext::FromContext(p) => p.is_none(),
249            _ => false,
250        }
251    }
252}
253
254impl Default for FromContextPatch {
255    fn default() -> Self {
256        FromContextPatch::FromContext(None)
257    }
258}
259
260impl Default for CopyResourcePatch {
261    fn default() -> Self {
262        CopyResourcePatch::Unknown(UnknownPatch::default())
263    }
264}
265
266impl Default for CacheSharing {
267    fn default() -> Self {
268        CacheSharing::Locked
269    }
270}
271
272impl From<CopyResourcePatch> for CopyResource {
273    fn from(patch: CopyResourcePatch) -> Self {
274        match patch {
275            CopyResourcePatch::Copy(p) => CopyResource::Copy(p.into()),
276            CopyResourcePatch::Content(p) => CopyResource::Content(p.into()),
277            CopyResourcePatch::Add(p) => CopyResource::Add(p.into()),
278            CopyResourcePatch::AddGitRepo(p) => CopyResource::AddGitRepo(p.into()),
279            CopyResourcePatch::Unknown(p) => panic!("Unknown patch: {:?}", p),
280        }
281    }
282}
283
284#[cfg(feature = "permissive")]
285impl<T: FromStr> From<T> for ParsableStruct<T> {
286    fn from(value: T) -> Self {
287        ParsableStruct(value)
288    }
289}
290
291#[cfg(feature = "permissive")]
292impl<T> Default for OneOrMany<T>
293where
294    T: Sized,
295{
296    fn default() -> Self {
297        OneOrMany(vec![])
298    }
299}
300
301#[cfg(feature = "permissive")]
302impl<T> Deref for OneOrMany<T>
303where
304    T: Sized,
305{
306    type Target = Vec<T>;
307
308    fn deref(&self) -> &Self::Target {
309        &self.0
310    }
311}
312
313#[cfg(feature = "permissive")]
314impl<T> From<OneOrManyDeserializable<T>> for OneOrMany<T> {
315    fn from(value: OneOrManyDeserializable<T>) -> Self {
316        match value {
317            OneOrManyDeserializable::One(v) => OneOrMany(vec![v]),
318            OneOrManyDeserializable::Many(v) => OneOrMany(v),
319        }
320    }
321}
322
323impl<T> From<VecPatchDeserializable<T>> for VecPatch<T>
324where
325    T: Clone,
326{
327    fn from(value: VecPatchDeserializable<T>) -> Self {
328        match value {
329            #[cfg(feature = "permissive")]
330            VecPatchDeserializable::Vec(v) => VecPatch {
331                commands: vec![VecPatchCommand::ReplaceAll(v.0)],
332            },
333            #[cfg(not(feature = "permissive"))]
334            VecPatchDeserializable::Vec(v) => VecPatch {
335                commands: vec![VecPatchCommand::ReplaceAll(v)],
336            },
337            VecPatchDeserializable::Map(v) => VecPatch {
338                commands: v.commands,
339            },
340        }
341    }
342}
343
344impl<T, P> TryFrom<VecDeepPatchCommand<T, P>> for VecPatchCommand<T>
345where
346    T: Clone + From<P>,
347{
348    type Error = Error;
349
350    fn try_from(value: VecDeepPatchCommand<T, P>) -> Result<Self, Error> {
351        Ok(match value {
352            VecDeepPatchCommand::ReplaceAll(v) => VecPatchCommand::ReplaceAll(v),
353            VecDeepPatchCommand::Replace(pos, v) => VecPatchCommand::Replace(pos, v),
354            VecDeepPatchCommand::Patch(pos, _) => {
355                return Err(Error::Custom(format!(
356                    "VecPatch don't allow patching on {pos}: '{pos}<'"
357                )));
358            }
359            VecDeepPatchCommand::InsertBefore(pos, v) => VecPatchCommand::InsertBefore(pos, v),
360            VecDeepPatchCommand::InsertAfter(pos, v) => VecPatchCommand::InsertAfter(pos, v),
361            VecDeepPatchCommand::Append(v) => VecPatchCommand::Append(v),
362        })
363    }
364}
365
366impl<T, P> From<VecDeepPatchDeserializable<T, P>> for VecDeepPatch<T, P>
367where
368    T: Clone + Patch<P> + From<P>,
369    P: Clone,
370{
371    fn from(value: VecDeepPatchDeserializable<T, P>) -> Self {
372        match value {
373            #[cfg(feature = "permissive")]
374            VecDeepPatchDeserializable::Vec(v) => VecDeepPatch {
375                commands: vec![VecDeepPatchCommand::ReplaceAll(
376                    v.0.iter().map(|p| p.clone().into()).collect(),
377                )],
378            },
379            #[cfg(not(feature = "permissive"))]
380            VecDeepPatchDeserializable::Vec(v) => VecDeepPatch {
381                commands: vec![VecDeepPatchCommand::ReplaceAll(
382                    v.iter().map(|p| p.clone().into()).collect(),
383                )],
384            },
385            VecDeepPatchDeserializable::Map(v) => VecDeepPatch {
386                commands: v.commands,
387            },
388        }
389    }
390}
391
392#[cfg(not(feature = "strict"))]
393impl<T: Clone> NestedMap<T> {
394    fn flatten(&mut self) {
395        let keys = self.0.keys().cloned().collect::<Vec<_>>();
396        for key in keys {
397            if let Some(NestedMapValue::Map(nested_map)) = self.0.get_mut(&key) {
398                let mut nested_map = nested_map.clone();
399                self.0.remove(&key);
400                nested_map.flatten();
401                for (nested_key, nested_value) in nested_map.0 {
402                    let final_key = format!("{key}.{nested_key}");
403                    // Check if the key already exists in the map
404                    if !self.0.contains_key(&final_key) {
405                        self.0.insert(final_key, nested_value);
406                    }
407                }
408            }
409        }
410    }
411}
412
413//////////////////////// Patch ////////////////////////
414
415impl Patch<FromContextPatch> for FromContext {
416    fn apply(&mut self, patch: FromContextPatch) {
417        match (self, patch) {
418            (Self::FromImage(s), FromContextPatch::FromImage(p)) => s.apply(p),
419            (s, patch) => *s = patch.into(),
420        }
421    }
422
423    fn into_patch(self) -> FromContextPatch {
424        match self {
425            FromContext::FromImage(s) => FromContextPatch::FromImage(s.into_patch()),
426            FromContext::FromBuilder(s) => FromContextPatch::FromBuilder(s),
427            FromContext::FromContext(s) => FromContextPatch::FromContext(s),
428        }
429    }
430
431    fn into_patch_by_diff(self, _previous_struct: Self) -> FromContextPatch {
432        todo!()
433    }
434
435    fn new_empty_patch() -> FromContextPatch {
436        panic!("Cannot create an empty patch for FromContext");
437    }
438}
439
440impl Patch<CopyResourcePatch> for CopyResource {
441    fn apply(&mut self, patch: CopyResourcePatch) {
442        match (self, patch) {
443            (Self::Copy(s), CopyResourcePatch::Copy(p)) => s.apply(p),
444            (Self::Copy(s), CopyResourcePatch::Unknown(p)) => s.apply(p),
445            (Self::Content(s), CopyResourcePatch::Content(p)) => s.apply(p),
446            (Self::Content(s), CopyResourcePatch::Unknown(p)) => s.apply(p),
447            (Self::Add(s), CopyResourcePatch::Add(p)) => s.apply(p),
448            (Self::Add(s), CopyResourcePatch::Unknown(p)) => s.apply(p),
449            (Self::AddGitRepo(s), CopyResourcePatch::AddGitRepo(p)) => s.apply(p),
450            (Self::AddGitRepo(s), CopyResourcePatch::Unknown(p)) => s.apply(p),
451            (s, p) => panic!("Cannot apply patch {:?} on {:?}", p, s),
452        }
453    }
454
455    fn into_patch(self) -> CopyResourcePatch {
456        match self {
457            CopyResource::Copy(s) => CopyResourcePatch::Copy(s.into_patch()),
458            CopyResource::Content(s) => CopyResourcePatch::Content(s.into_patch()),
459            CopyResource::Add(s) => CopyResourcePatch::Add(s.into_patch()),
460            CopyResource::AddGitRepo(s) => CopyResourcePatch::AddGitRepo(s.into_patch()),
461        }
462    }
463
464    fn into_patch_by_diff(self, previous_struct: Self) -> CopyResourcePatch {
465        match (self, previous_struct) {
466            (CopyResource::Copy(s), CopyResource::Copy(p)) => {
467                CopyResourcePatch::Copy(s.into_patch_by_diff(p))
468            }
469            (CopyResource::Add(s), CopyResource::Add(p)) => {
470                CopyResourcePatch::Add(s.into_patch_by_diff(p))
471            }
472            (CopyResource::AddGitRepo(s), CopyResource::AddGitRepo(p)) => {
473                CopyResourcePatch::AddGitRepo(s.into_patch_by_diff(p))
474            }
475            _ => todo!(),
476        }
477    }
478
479    fn new_empty_patch() -> CopyResourcePatch {
480        CopyResourcePatch::default()
481    }
482}
483
484impl Patch<UnknownPatch> for Copy {
485    fn apply(&mut self, patch: UnknownPatch) {
486        if let Some(options) = patch.options {
487            self.options.apply(options);
488        }
489    }
490
491    fn into_patch(self) -> UnknownPatch {
492        UnknownPatch {
493            options: Some(self.options.into_patch()),
494            exclude: Some(self.exclude.into_patch()),
495        }
496    }
497
498    fn into_patch_by_diff(self, previous_struct: Self) -> UnknownPatch {
499        UnknownPatch {
500            options: Some(self.options.into_patch_by_diff(previous_struct.options)),
501            exclude: Some(self.exclude.into_patch_by_diff(previous_struct.exclude)),
502        }
503    }
504
505    fn new_empty_patch() -> UnknownPatch {
506        UnknownPatch::default()
507    }
508}
509
510impl Patch<UnknownPatch> for CopyContent {
511    fn apply(&mut self, patch: UnknownPatch) {
512        if let Some(options) = patch.options {
513            self.options.apply(options);
514        }
515    }
516
517    fn into_patch(self) -> UnknownPatch {
518        UnknownPatch {
519            options: Some(self.options.into_patch()),
520            exclude: None,
521        }
522    }
523
524    fn into_patch_by_diff(self, previous_struct: Self) -> UnknownPatch {
525        UnknownPatch {
526            options: Some(self.options.into_patch_by_diff(previous_struct.options)),
527            exclude: None,
528        }
529    }
530
531    fn new_empty_patch() -> UnknownPatch {
532        UnknownPatch::default()
533    }
534}
535
536impl Patch<UnknownPatch> for Add {
537    fn apply(&mut self, patch: UnknownPatch) {
538        if let Some(options) = patch.options {
539            self.options.apply(options);
540        }
541    }
542
543    fn into_patch(self) -> UnknownPatch {
544        UnknownPatch {
545            options: Some(self.options.into_patch()),
546            exclude: None,
547        }
548    }
549
550    fn into_patch_by_diff(self, previous_struct: Self) -> UnknownPatch {
551        UnknownPatch {
552            options: Some(self.options.into_patch_by_diff(previous_struct.options)),
553            exclude: None,
554        }
555    }
556
557    fn new_empty_patch() -> UnknownPatch {
558        UnknownPatch::default()
559    }
560}
561
562impl Patch<UnknownPatch> for AddGitRepo {
563    fn apply(&mut self, patch: UnknownPatch) {
564        if let Some(options) = patch.options {
565            self.options.apply(options);
566        }
567    }
568
569    fn into_patch(self) -> UnknownPatch {
570        UnknownPatch {
571            options: Some(self.options.into_patch()),
572            exclude: Some(self.exclude.into_patch()),
573        }
574    }
575
576    fn into_patch_by_diff(self, previous_struct: Self) -> UnknownPatch {
577        UnknownPatch {
578            options: Some(self.options.into_patch_by_diff(previous_struct.options)),
579            exclude: Some(self.exclude.into_patch_by_diff(previous_struct.exclude)),
580        }
581    }
582
583    fn new_empty_patch() -> UnknownPatch {
584        UnknownPatch::default()
585    }
586}
587
588impl<T> Patch<VecPatch<T>> for Vec<T>
589where
590    T: Clone,
591{
592    fn apply(&mut self, patch: VecPatch<T>) {
593        let mut reset = false;
594        let mut last_modified_position: usize = usize::MAX;
595        // initial array length
596        let initial_len = self.len();
597        // save the number of elements added before the positions
598        let mut adapted_positions: Vec<usize> = vec![0; self.len()];
599        // save the current position and corresponding adapted position to avoid recomputing it
600        let mut current_position = 0;
601        let mut position_adaptation = 0;
602
603        for command in patch.commands {
604            match command {
605                VecPatchCommand::ReplaceAll(elements) => {
606                    if reset {
607                        panic!("Cannot replace the list twice");
608                    }
609                    reset = true;
610                    self.clear();
611                    self.extend(elements.into_iter());
612                }
613                VecPatchCommand::Replace(pos, elements) => {
614                    if reset {
615                        panic!("Cannot replace element at position {} after a reset", pos);
616                    }
617                    if pos >= initial_len {
618                        panic!("Position {} is out of bounds", pos);
619                    }
620                    if pos == last_modified_position {
621                        panic!(
622                            "Cannot replace element at position {} after another modification on it",
623                            pos
624                        );
625                    }
626                    for i in current_position..=pos {
627                        current_position = i;
628                        position_adaptation += adapted_positions[i];
629                    }
630                    let adapted_position = current_position + position_adaptation;
631                    self[adapted_position] = elements;
632                    last_modified_position = pos;
633                }
634                VecPatchCommand::InsertBefore(pos, elements) => {
635                    if reset {
636                        panic!(
637                            "Cannot insert before element at position {} after a reset",
638                            pos
639                        );
640                    }
641                    if pos >= initial_len {
642                        panic!("Position {} is out of bounds", pos);
643                    }
644                    for i in current_position..=pos {
645                        current_position = i;
646                        position_adaptation += adapted_positions[i];
647                    }
648                    let added = elements.len();
649                    let adapted_position = current_position + position_adaptation;
650                    self.splice(adapted_position..adapted_position, elements);
651                    adapted_positions[pos as usize] += added;
652                }
653                VecPatchCommand::InsertAfter(pos, elements) => {
654                    if reset {
655                        panic!(
656                            "Cannot insert after element at position {} after a reset",
657                            pos
658                        );
659                    }
660                    if pos >= initial_len {
661                        panic!("Position {} is out of bounds", pos);
662                    }
663                    for i in current_position..=pos {
664                        current_position = i;
665                        position_adaptation += adapted_positions[i];
666                    }
667                    let adapted_position = current_position + position_adaptation + 1;
668                    let added = elements.len();
669                    self.splice(adapted_position..adapted_position, elements);
670                    if pos + 1 < initial_len {
671                        adapted_positions[(pos + 1) as usize] = added;
672                    } else {
673                        adapted_positions.push(added);
674                    }
675                }
676                VecPatchCommand::Append(elements) => {
677                    self.extend(elements);
678                }
679            }
680        }
681    }
682
683    fn into_patch(self) -> VecPatch<T> {
684        VecPatch {
685            commands: vec![VecPatchCommand::ReplaceAll(self)],
686        }
687    }
688
689    fn into_patch_by_diff(self, _previous_struct: Self) -> VecPatch<T> {
690        todo!()
691        // the diff is computed by comparing the two arrays
692        // let mut commands = vec![];
693
694        // VecPatch { commands }
695    }
696
697    fn new_empty_patch() -> VecPatch<T> {
698        VecPatch { commands: vec![] }
699    }
700}
701
702impl<T, P> Patch<VecDeepPatch<T, P>> for Vec<T>
703where
704    T: Clone + Patch<P> + From<P>,
705    P: Clone,
706{
707    fn apply(&mut self, patch: VecDeepPatch<T, P>) {
708        let mut reset = false;
709        let mut last_modified_position: usize = usize::MAX;
710        // initial array length
711        let initial_len = self.len();
712        let patch_len = patch.commands.len();
713        // save the number of elements added before the positions
714        let mut adapted_positions: Vec<usize> = vec![0; self.len()];
715        // save the current position and corresponding adapted position to avoid recomputing it
716        let mut current_position = 0;
717        let mut position_adaptation = 0;
718
719        for command in patch.commands {
720            match command {
721                VecDeepPatchCommand::ReplaceAll(elements) => {
722                    if reset {
723                        panic!("Cannot replace the list twice");
724                    }
725                    if patch_len > 1 {
726                        panic!("Cannot combine a replace all with other commands");
727                    }
728                    reset = true;
729                    self.clear();
730                    self.extend(elements.into_iter());
731                }
732                VecDeepPatchCommand::Replace(pos, element) => {
733                    if reset {
734                        panic!("Cannot replace element at position {} after a reset", pos);
735                    }
736                    if pos >= initial_len {
737                        panic!("Position {} is out of bounds", pos);
738                    }
739                    if pos == last_modified_position {
740                        panic!(
741                            "Cannot replace element at position {} after another modification on it",
742                            pos
743                        );
744                    }
745                    for i in current_position..=pos {
746                        current_position = i;
747                        position_adaptation += adapted_positions[i];
748                    }
749                    let adapted_position = current_position + position_adaptation;
750                    self[adapted_position] = element;
751                    last_modified_position = pos;
752                }
753                VecDeepPatchCommand::Patch(pos, element) => {
754                    if reset {
755                        panic!("Cannot patch element at position {} after a reset", pos);
756                    }
757                    if pos >= initial_len {
758                        panic!("Position {} is out of bounds", pos);
759                    }
760                    if pos == last_modified_position {
761                        panic!(
762                            "Cannot patch element at position {} after another modification on it",
763                            pos
764                        );
765                    }
766                    for i in current_position..=pos {
767                        current_position = i;
768                        position_adaptation += adapted_positions[i];
769                    }
770                    let adapted_position = current_position + position_adaptation;
771                    self[adapted_position].apply(element);
772                    last_modified_position = pos;
773                }
774                VecDeepPatchCommand::InsertBefore(pos, elements) => {
775                    if reset {
776                        panic!(
777                            "Cannot insert before element at position {} after a reset",
778                            pos
779                        );
780                    }
781                    if pos >= initial_len {
782                        panic!("Position {} is out of bounds", pos);
783                    }
784                    for i in current_position..=pos {
785                        current_position = i;
786                        position_adaptation += adapted_positions[i];
787                    }
788                    let adapted_position = current_position + position_adaptation;
789                    let added = elements.len();
790                    self.splice(adapted_position..adapted_position, elements);
791                    adapted_positions[pos as usize] += added;
792                }
793                VecDeepPatchCommand::InsertAfter(pos, elements) => {
794                    if reset {
795                        panic!(
796                            "Cannot insert after element at position {} after a reset",
797                            pos
798                        );
799                    }
800                    if pos >= initial_len {
801                        panic!("Position {} is out of bounds", pos);
802                    }
803                    for i in current_position..=pos {
804                        current_position = i;
805                        position_adaptation += adapted_positions[i];
806                    }
807                    let adapted_position = current_position + position_adaptation;
808                    let usize_pos = adapted_position + 1;
809                    let added = elements.len();
810                    self.splice(usize_pos..usize_pos, elements);
811                    if pos + 1 < initial_len {
812                        adapted_positions[(pos + 1) as usize] = added;
813                    } else {
814                        adapted_positions.push(added);
815                    }
816                }
817                VecDeepPatchCommand::Append(elements) => {
818                    self.extend(elements);
819                }
820            }
821        }
822    }
823
824    fn into_patch(self) -> VecDeepPatch<T, P> {
825        VecDeepPatch {
826            commands: vec![VecDeepPatchCommand::ReplaceAll(self)],
827        }
828    }
829
830    fn into_patch_by_diff(self, _previous_struct: Self) -> VecDeepPatch<T, P> {
831        todo!()
832    }
833
834    fn new_empty_patch() -> VecDeepPatch<T, P> {
835        VecDeepPatch { commands: vec![] }
836    }
837}
838
839impl<K, V> Patch<HashMapPatch<K, V>> for HashMap<K, V>
840where
841    K: Clone + Eq + Hash,
842    V: Clone,
843{
844    fn apply(&mut self, patch: HashMapPatch<K, V>) {
845        for (key, value) in patch.patches {
846            match value {
847                Some(value) => {
848                    self.insert(key, value);
849                }
850                None => {
851                    self.remove(&key);
852                }
853            }
854        }
855    }
856
857    fn into_patch(self) -> HashMapPatch<K, V> {
858        let mut patches = HashMap::new();
859        for (key, value) in self {
860            patches.insert(key, Some(value));
861        }
862        HashMapPatch { patches }
863    }
864
865    fn into_patch_by_diff(self, _previous_struct: Self) -> HashMapPatch<K, V> {
866        todo!()
867    }
868
869    fn new_empty_patch() -> HashMapPatch<K, V> {
870        HashMapPatch {
871            patches: HashMap::new(),
872        }
873    }
874}
875
876impl<K, T, P> Patch<HashMapDeepPatch<K, P>> for HashMap<K, T>
877where
878    K: Clone + Eq + Hash,
879    T: Clone + Patch<P> + From<P>,
880    P: Clone,
881{
882    fn apply(&mut self, patch: HashMapDeepPatch<K, P>) {
883        for (key, value) in patch.patches {
884            match value {
885                Some(value) => {
886                    self.insert(key, value.into());
887                }
888                None => {
889                    self.remove(&key);
890                }
891            }
892        }
893    }
894
895    fn into_patch(self) -> HashMapDeepPatch<K, P> {
896        let mut patches = HashMap::new();
897        for (key, value) in self {
898            patches.insert(key, Some(value.into_patch()));
899        }
900        HashMapDeepPatch { patches }
901    }
902
903    fn into_patch_by_diff(self, _previous_struct: Self) -> HashMapDeepPatch<K, P> {
904        todo!()
905    }
906
907    fn new_empty_patch() -> HashMapDeepPatch<K, P> {
908        HashMapDeepPatch {
909            patches: HashMap::new(),
910        }
911    }
912}
913
914#[cfg(not(feature = "strict"))]
915impl<T: Clone> From<NestedMap<T>> for HashMap<String, Option<T>> {
916    fn from(value: NestedMap<T>) -> Self {
917        let mut value = value.clone();
918        value.flatten();
919        return value
920            .0
921            .into_iter()
922            .map(|(key, value)| {
923                (
924                    key,
925                    match value {
926                        NestedMapValue::Value(value) => Some(value),
927                        NestedMapValue::Map(_) => unreachable!(),
928                        NestedMapValue::Null => None,
929                    },
930                )
931            })
932            .collect();
933    }
934}
935
936#[cfg(not(feature = "strict"))]
937impl<T> Patch<NestedMap<T>> for HashMap<String, T>
938where
939    T: Clone,
940{
941    fn apply(&mut self, patch: NestedMap<T>) {
942        let flatten: HashMap<String, Option<T>> = patch.into();
943        flatten.into_iter().for_each(|(key, opt)| {
944            if let Some(value) = opt {
945                self.insert(key, value);
946            } else {
947                self.remove(&key);
948            }
949        });
950    }
951
952    fn into_patch(self) -> NestedMap<T> {
953        NestedMap(
954            self.into_iter()
955                .map(|(key, value)| (key.clone(), NestedMapValue::Value(value)))
956                .collect(),
957        )
958    }
959
960    fn into_patch_by_diff(self, _previous_struct: Self) -> NestedMap<T> {
961        todo!()
962    }
963
964    fn new_empty_patch() -> NestedMap<T> {
965        NestedMap(HashMap::new())
966    }
967}
968
969//////////////////////// Deserialize ////////////////////////
970
971#[cfg(feature = "permissive")]
972impl<'de, T> Deserialize<'de> for ParsableStruct<T>
973where
974    T: FromStr<Err = serde::de::value::Error> + Sized + Deserialize<'de>,
975{
976    fn deserialize<D>(deserializer: D) -> Result<ParsableStruct<T>, D::Error>
977    where
978        D: Deserializer<'de>,
979    {
980        struct PermissiveStructVisitor<T>(Option<T>);
981
982        impl<'de, T> de::Visitor<'de> for PermissiveStructVisitor<T>
983        where
984            T: Deserialize<'de> + FromStr<Err = serde::de::value::Error>,
985        {
986            type Value = T;
987
988            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
989                formatter.write_str("a number, a string or a map")
990            }
991
992            fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
993            where
994                E: de::Error,
995            {
996                self.visit_str(v.to_string().as_str())
997            }
998
999            fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
1000            where
1001                E: de::Error,
1002            {
1003                self.visit_str(v.to_string().as_str())
1004            }
1005
1006            fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
1007            where
1008                E: de::Error,
1009            {
1010                self.visit_str(v.to_string().as_str())
1011            }
1012
1013            fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
1014            where
1015                E: de::Error,
1016            {
1017                self.visit_str(v.to_string().as_str())
1018            }
1019
1020            fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
1021            where
1022                E: de::Error,
1023            {
1024                self.visit_str(v.to_string().as_str())
1025            }
1026
1027            fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
1028            where
1029                E: de::Error,
1030            {
1031                self.visit_str(v.to_string().as_str())
1032            }
1033
1034            fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
1035            where
1036                E: de::Error,
1037            {
1038                self.visit_str(v.to_string().as_str())
1039            }
1040
1041            fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
1042            where
1043                E: de::Error,
1044            {
1045                self.visit_str(v.to_string().as_str())
1046            }
1047
1048            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
1049            where
1050                E: de::Error,
1051            {
1052                self.visit_str(v.to_string().as_str())
1053            }
1054
1055            fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
1056            where
1057                E: de::Error,
1058            {
1059                self.visit_str(v.to_string().as_str())
1060            }
1061
1062            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
1063            where
1064                E: de::Error,
1065            {
1066                v.parse().map_err(|err| {
1067                    E::custom(format!("Error while parsing a permissive struct: {}", err))
1068                })
1069            }
1070
1071            fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
1072            where
1073                A: de::MapAccess<'de>,
1074            {
1075                Deserialize::deserialize(de::value::MapAccessDeserializer::new(map))
1076            }
1077        }
1078
1079        let visitor: PermissiveStructVisitor<T> = PermissiveStructVisitor(None);
1080
1081        deserializer.deserialize_any(visitor).map(ParsableStruct)
1082    }
1083}
1084
1085impl<'de, T> Deserialize<'de> for VecPatchCommandMap<T>
1086where
1087    T: Clone + Deserialize<'de>,
1088{
1089    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1090    where
1091        D: Deserializer<'de>,
1092    {
1093        let commands: Vec<VecDeepPatchCommand<T, T>> =
1094            deserialize_vec_patch_commands(deserializer)?;
1095        Ok(VecPatchCommandMap {
1096            commands: commands
1097                .iter()
1098                .map(|c| c.clone().try_into().map_err(de::Error::custom))
1099                .collect::<Result<Vec<_>, _>>()?,
1100        })
1101    }
1102}
1103
1104impl<'de, T, P> Deserialize<'de> for VecDeepPatchCommandMap<T, P>
1105where
1106    T: Clone + From<P>,
1107    P: Clone + Deserialize<'de>,
1108{
1109    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1110    where
1111        D: Deserializer<'de>,
1112    {
1113        Ok(VecDeepPatchCommandMap {
1114            commands: deserialize_vec_patch_commands(deserializer)?,
1115        })
1116    }
1117}
1118
1119fn deserialize_vec_patch_commands<'de, D, T, P>(
1120    deserializer: D,
1121) -> Result<Vec<VecDeepPatchCommand<T, P>>, D::Error>
1122where
1123    D: Deserializer<'de>,
1124    T: Clone + From<P>,
1125    P: Clone + Deserialize<'de>,
1126{
1127    struct VecDeepPatchCommandsVisitor<T, P>(PhantomData<fn() -> BTreeMap<T, P>>);
1128
1129    #[cfg(feature = "permissive")]
1130    fn map_vec<T, P>(patch: OneOrMany<P>) -> Vec<T>
1131    where
1132        T: Clone + From<P>,
1133        P: Clone,
1134    {
1135        patch.iter().map(|p| p.clone().into()).collect()
1136    }
1137
1138    #[cfg(not(feature = "permissive"))]
1139    fn map_vec<T, P>(patch: Vec<P>) -> Vec<T>
1140    where
1141        T: Clone + From<P>,
1142        P: Clone,
1143    {
1144        patch.iter().map(|p| p.clone().into()).collect()
1145    }
1146
1147    impl<'de, T, P> de::Visitor<'de> for VecDeepPatchCommandsVisitor<T, P>
1148    where
1149        T: Clone + From<P>,
1150        P: Clone + Deserialize<'de>,
1151    {
1152        type Value = Vec<VecDeepPatchCommand<T, P>>;
1153
1154        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1155            formatter.write_str("a map")
1156        }
1157
1158        fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
1159        where
1160            A: de::MapAccess<'de>,
1161        {
1162            let mut commands = vec![];
1163
1164            while let Some(key) = map.next_key()? {
1165                match key {
1166                    StringOrNumber::String(key) => match key.as_str() {
1167                        "_" => {
1168                            commands
1169                                .push(VecDeepPatchCommand::ReplaceAll(map_vec(map.next_value()?)));
1170                        }
1171                        "+" => {
1172                            commands.push(VecDeepPatchCommand::Append(map_vec(map.next_value()?)));
1173                        }
1174                        key => {
1175                            if key.starts_with('+') {
1176                                let pos = key[1..key.len()].parse::<usize>().unwrap();
1177                                commands.push(VecDeepPatchCommand::InsertBefore(
1178                                    pos,
1179                                    map_vec(map.next_value()?),
1180                                ));
1181                            } else if key.ends_with('+') {
1182                                let pos = key[..key.len() - 1].parse::<usize>().unwrap();
1183                                commands.push(VecDeepPatchCommand::InsertAfter(
1184                                    pos,
1185                                    map_vec(map.next_value()?),
1186                                ));
1187                            } else if key.ends_with('<') {
1188                                let pos = key[..key.len() - 1].parse::<usize>().unwrap();
1189                                commands.push(VecDeepPatchCommand::Patch(pos, map.next_value()?));
1190                            } else {
1191                                let value: P = map.next_value()?;
1192                                let pos = key.parse::<usize>().unwrap();
1193                                commands.push(VecDeepPatchCommand::Replace(pos, value.into()));
1194                            }
1195                        }
1196                    },
1197                    StringOrNumber::Number(pos) => {
1198                        let value: P = map.next_value()?;
1199                        commands.push(VecDeepPatchCommand::Replace(pos, value.into()));
1200                    }
1201                }
1202            }
1203
1204            // Sort the commands by position and kind
1205            commands.sort_by(sort_commands);
1206
1207            Ok(commands)
1208        }
1209    }
1210
1211    let visitor: VecDeepPatchCommandsVisitor<T, P> = VecDeepPatchCommandsVisitor(PhantomData);
1212
1213    deserializer.deserialize_any(visitor)
1214}
1215
1216#[cfg(feature = "permissive")]
1217pub(crate) fn deserialize_from_optional_string_or_number<'de, D>(
1218    deserializer: D,
1219) -> Result<Option<Option<String>>, D::Error>
1220where
1221    D: Deserializer<'de>,
1222{
1223    let val: Option<StringOrNumber> = Deserialize::deserialize(deserializer)?;
1224
1225    Ok(Some(val.map(|val| match val {
1226        StringOrNumber::String(s) => s,
1227        StringOrNumber::Number(n) => n.to_string(),
1228    })))
1229}
1230
1231fn sort_commands<T, P>(a: &VecDeepPatchCommand<T, P>, b: &VecDeepPatchCommand<T, P>) -> Ordering
1232where
1233    T: Clone + From<P>,
1234    P: Clone,
1235{
1236    match (a, b) {
1237        // ReplaceAll should always be first
1238        (VecDeepPatchCommand::ReplaceAll(_), _) => std::cmp::Ordering::Less,
1239        (_, VecDeepPatchCommand::ReplaceAll(_)) => std::cmp::Ordering::Greater,
1240        // Append should always be last
1241        (VecDeepPatchCommand::Append(_), _) => std::cmp::Ordering::Greater,
1242        (_, VecDeepPatchCommand::Append(_)) => std::cmp::Ordering::Less,
1243        // Same type should be sorted by position
1244        (VecDeepPatchCommand::InsertBefore(a, _), VecDeepPatchCommand::InsertBefore(b, _))
1245        | (
1246            VecDeepPatchCommand::Replace(a, _) | VecDeepPatchCommand::Patch(a, _),
1247            VecDeepPatchCommand::Replace(b, _) | VecDeepPatchCommand::Patch(b, _),
1248        )
1249        | (VecDeepPatchCommand::InsertAfter(a, _), VecDeepPatchCommand::InsertAfter(b, _)) => {
1250            a.cmp(b)
1251        }
1252        /*
1253        For a same position
1254            InsertBefore should be before Replace, Patch and InsertAfter
1255            Replace and Patch should be before InsertAfter
1256        */
1257        (
1258            VecDeepPatchCommand::InsertBefore(a, _),
1259            VecDeepPatchCommand::Replace(b, _)
1260            | VecDeepPatchCommand::Patch(b, _)
1261            | VecDeepPatchCommand::InsertAfter(b, _),
1262        )
1263        | (
1264            VecDeepPatchCommand::Replace(a, _) | VecDeepPatchCommand::Patch(a, _),
1265            VecDeepPatchCommand::InsertAfter(b, _),
1266        ) => match a.cmp(b) {
1267            std::cmp::Ordering::Equal => std::cmp::Ordering::Less,
1268            other => other,
1269        },
1270        (
1271            VecDeepPatchCommand::Replace(a, _)
1272            | VecDeepPatchCommand::Patch(a, _)
1273            | VecDeepPatchCommand::InsertAfter(a, _),
1274            VecDeepPatchCommand::InsertBefore(b, _),
1275        )
1276        | (
1277            VecDeepPatchCommand::InsertAfter(a, _),
1278            VecDeepPatchCommand::Replace(b, _) | VecDeepPatchCommand::Patch(b, _),
1279        ) => match a.cmp(b) {
1280            std::cmp::Ordering::Equal => std::cmp::Ordering::Greater,
1281            other => other,
1282        },
1283    }
1284}
1285
1286//////////////////////// Merge //////////////////////////
1287
1288// Can't use merge on option since it removes the previous value if it's none
1289macro_rules! merge_option_patch {
1290    ($opt_a: expr_2021, $opt_b: expr_2021) => {
1291        match ($opt_a, $opt_b) {
1292            (Some(a), Some(b)) => Some(a.merge(b)),
1293            (Some(a), None) => Some(a),
1294            (None, Some(b)) => Some(b),
1295            (None, None) => None,
1296        }
1297    };
1298}
1299
1300impl Merge for FromContextPatch {
1301    fn merge(self, other: Self) -> Self {
1302        match (self, other) {
1303            (Self::FromImage(a), Self::FromImage(b)) => Self::FromImage(a.merge(b)),
1304            (_, b) => b,
1305        }
1306    }
1307}
1308
1309impl Merge for CopyResourcePatch {
1310    fn merge(self, other: Self) -> Self {
1311        match (self, other) {
1312            (Self::Copy(a), Self::Copy(b)) => Self::Copy(a.merge(b)),
1313            (Self::Copy(a), Self::Unknown(b)) => {
1314                let mut a = a;
1315                a.options = merge_option_patch!(a.options, b.options);
1316                Self::Copy(a)
1317            }
1318            (Self::Unknown(a), Self::Copy(b)) => {
1319                let mut b = b;
1320                b.options = merge_option_patch!(a.options, b.options);
1321                Self::Copy(b)
1322            }
1323            (Self::Add(a), Self::Add(b)) => Self::Add(a.merge(b)),
1324            (Self::Add(a), Self::Unknown(b)) => {
1325                let mut a = a;
1326                a.options = merge_option_patch!(a.options, b.options);
1327                Self::Add(a)
1328            }
1329            (Self::Unknown(a), Self::Add(b)) => {
1330                let mut b = b;
1331                b.options = merge_option_patch!(a.options, b.options);
1332                Self::Add(b)
1333            }
1334            (Self::AddGitRepo(a), Self::AddGitRepo(b)) => Self::AddGitRepo(a.merge(b)),
1335            (Self::AddGitRepo(a), Self::Unknown(b)) => {
1336                let mut a = a;
1337                a.options = merge_option_patch!(a.options, b.options);
1338                Self::AddGitRepo(a)
1339            }
1340            (Self::Unknown(a), Self::AddGitRepo(b)) => {
1341                let mut b = b;
1342                b.options = merge_option_patch!(a.options, b.options);
1343                Self::AddGitRepo(b)
1344            }
1345            (Self::Unknown(a), Self::Unknown(b)) => Self::Unknown(a.merge(b)),
1346            (a, b) => panic!("Can't merge {:?} and {:?}", a, b),
1347        }
1348    }
1349}
1350
1351impl Merge for UnknownPatch {
1352    fn merge(self, other: Self) -> Self {
1353        Self {
1354            options: merge_option_patch!(self.options, other.options),
1355            exclude: merge_option_patch!(self.exclude, other.exclude),
1356        }
1357    }
1358}
1359
1360#[cfg(feature = "permissive")]
1361impl<T> Merge for ParsableStruct<T>
1362where
1363    T: Clone + FromStr + Merge,
1364{
1365    fn merge(self, other: Self) -> Self {
1366        ParsableStruct(self.0.merge(other.0))
1367    }
1368}
1369
1370impl<T> Merge for VecPatch<T>
1371where
1372    T: Clone,
1373{
1374    fn merge(self, other: Self) -> Self {
1375        if other.commands.len() == 1
1376            && matches!(other.commands.first(), Some(VecPatchCommand::ReplaceAll(_)))
1377        {
1378            return other;
1379        }
1380        if self.commands.len() == 1 {
1381            if let Some(VecPatchCommand::ReplaceAll(self_vec)) = self.commands.first() {
1382                let mut self_vec = self_vec.clone();
1383                self_vec.apply(other);
1384                return VecPatch {
1385                    commands: vec![VecPatchCommand::ReplaceAll(self_vec)],
1386                };
1387            }
1388        }
1389
1390        let mut commands: Vec<VecPatchCommand<T>> = vec![];
1391
1392        let mut self_it = self.commands.iter();
1393        let mut rhs_it = other.commands.iter();
1394
1395        let mut self_next = self_it.next();
1396        let mut rhs_next = rhs_it.next();
1397
1398        while let (Some(self_command), Some(rhs_command)) = (self_next, rhs_next) {
1399            match (self_command.clone(), rhs_command.clone()) {
1400                (VecPatchCommand::ReplaceAll(_), _) | (_, VecPatchCommand::ReplaceAll(_)) => {
1401                    panic!("Cannot combine a replace all with other commands");
1402                }
1403                (VecPatchCommand::Append(elements), VecPatchCommand::Append(rhs_elements)) => {
1404                    // For append, we first add self elements then rhs elements
1405                    // Since we apply the self first and then the rhs the rhs elements will be added after the self elements
1406                    let mut elements = elements;
1407                    elements.extend(rhs_elements);
1408                    commands.push(VecPatchCommand::Append(elements));
1409                    self_next = self_it.next();
1410                    rhs_next = rhs_it.next();
1411                }
1412                (self_command, VecPatchCommand::Append(_)) => {
1413                    commands.push(self_command);
1414                    self_next = self_it.next();
1415                }
1416                (VecPatchCommand::Append(_), rhs_command) => {
1417                    commands.push(rhs_command);
1418                    rhs_next = rhs_it.next();
1419                }
1420                (
1421                    VecPatchCommand::Replace(self_pos, self_val),
1422                    VecPatchCommand::Replace(rhs_pos, rhs_val),
1423                ) => {
1424                    if self_pos == rhs_pos {
1425                        commands.push(VecPatchCommand::Replace(rhs_pos, rhs_val));
1426                        self_next = self_it.next();
1427                        rhs_next = rhs_it.next();
1428                    } else if self_pos < rhs_pos {
1429                        commands.push(VecPatchCommand::Replace(self_pos, self_val));
1430                        self_next = self_it.next();
1431                    } else {
1432                        commands.push(VecPatchCommand::Replace(rhs_pos, rhs_val));
1433                        rhs_next = rhs_it.next();
1434                    }
1435                }
1436                (
1437                    VecPatchCommand::InsertBefore(self_pos, self_val),
1438                    VecPatchCommand::InsertBefore(rhs_pos, mut rhs_val),
1439                )
1440                | (
1441                    VecPatchCommand::InsertAfter(self_pos, self_val),
1442                    VecPatchCommand::InsertAfter(rhs_pos, mut rhs_val),
1443                ) => {
1444                    if self_pos == rhs_pos {
1445                        // We first add rhs elements then self elements
1446                        // For insert before, the position is the position of the first element added by the self patch
1447                        // For insert after, the position does not change so we append rhs elements after the elements, after that the self elements are added
1448                        rhs_val.extend(self_val);
1449                        commands.push(rhs_command.clone());
1450                        self_next = self_it.next();
1451                        rhs_next = rhs_it.next();
1452                    } else if self_pos < rhs_pos {
1453                        commands.push(self_command.clone());
1454                        self_next = self_it.next();
1455                    } else {
1456                        commands.push(rhs_command.clone());
1457                        rhs_next = rhs_it.next();
1458                    }
1459                }
1460                (
1461                    VecPatchCommand::Replace(self_pos, _)
1462                    | VecPatchCommand::InsertBefore(self_pos, _)
1463                    | VecPatchCommand::InsertAfter(self_pos, _),
1464                    VecPatchCommand::Replace(rhs_pos, _)
1465                    | VecPatchCommand::InsertBefore(rhs_pos, _)
1466                    | VecPatchCommand::InsertAfter(rhs_pos, _),
1467                ) => {
1468                    if self_pos == rhs_pos {
1469                        match (self_command, rhs_command) {
1470                            (VecPatchCommand::InsertBefore(_, _), _)
1471                            | (_, VecPatchCommand::InsertAfter(_, _)) => {
1472                                commands.push(self_command.clone());
1473                                self_next = self_it.next();
1474                            }
1475                            (_, VecPatchCommand::InsertBefore(_, _))
1476                            | (VecPatchCommand::InsertAfter(_, _), _) => {
1477                                commands.push(rhs_command.clone());
1478                                rhs_next = rhs_it.next();
1479                            }
1480                            _ => panic!("This case should have been reached"),
1481                        }
1482                    } else if self_pos < rhs_pos {
1483                        commands.push(self_command.clone());
1484                        self_next = self_it.next();
1485                    } else {
1486                        commands.push(rhs_command.clone());
1487                        rhs_next = rhs_it.next();
1488                    }
1489                }
1490            }
1491        }
1492
1493        let remaining_commands = if self_next.is_some() {
1494            std::iter::once(self_next.unwrap()).chain(self_it)
1495        } else {
1496            std::iter::once(rhs_next.unwrap()).chain(self_it)
1497        };
1498        remaining_commands.for_each(|c| commands.push(c.clone()));
1499
1500        Self { commands }
1501    }
1502}
1503
1504impl<T, P> Merge for VecDeepPatch<T, P>
1505where
1506    T: Clone + Patch<P> + From<P>,
1507    P: Clone + Merge,
1508{
1509    fn merge(self, other: Self) -> Self {
1510        if other.commands.len() == 1
1511            && matches!(
1512                other.commands.first(),
1513                Some(VecDeepPatchCommand::ReplaceAll(_))
1514            )
1515        {
1516            return other;
1517        }
1518        if self.commands.len() == 1 {
1519            if let Some(VecDeepPatchCommand::ReplaceAll(self_vec)) = self.commands.first() {
1520                let mut self_vec = self_vec.clone();
1521                self_vec.apply(other);
1522                return VecDeepPatch {
1523                    commands: vec![VecDeepPatchCommand::ReplaceAll(self_vec)],
1524                };
1525            }
1526        }
1527
1528        let mut commands: Vec<VecDeepPatchCommand<T, P>> = vec![];
1529
1530        let mut self_it = self.commands.iter();
1531        let mut rhs_it = other.commands.iter();
1532
1533        let mut self_next = self_it.next();
1534        let mut rhs_next = rhs_it.next();
1535
1536        while let (Some(self_command), Some(rhs_command)) = (self_next, rhs_next) {
1537            match (self_command.clone(), rhs_command.clone()) {
1538                (VecDeepPatchCommand::ReplaceAll(_), _)
1539                | (_, VecDeepPatchCommand::ReplaceAll(_)) => {
1540                    panic!("Cannot combine a replace all with other commands");
1541                }
1542                (
1543                    VecDeepPatchCommand::Append(elements),
1544                    VecDeepPatchCommand::Append(rhs_elements),
1545                ) => {
1546                    // For append, we first add self elements then rhs elements
1547                    // Since we apply the self first and then the rhs the rhs elements will be added after the self elements
1548                    let mut elements = elements;
1549                    elements.extend(rhs_elements);
1550                    commands.push(VecDeepPatchCommand::Append(elements));
1551                    self_next = self_it.next();
1552                    rhs_next = rhs_it.next();
1553                }
1554                (self_command, VecDeepPatchCommand::Append(_)) => {
1555                    commands.push(self_command);
1556                    self_next = self_it.next();
1557                }
1558                (VecDeepPatchCommand::Append(_), rhs_command) => {
1559                    commands.push(rhs_command);
1560                    rhs_next = rhs_it.next();
1561                }
1562                (
1563                    VecDeepPatchCommand::Replace(self_pos, self_val),
1564                    VecDeepPatchCommand::Replace(rhs_pos, rhs_val),
1565                ) => {
1566                    if self_pos == rhs_pos {
1567                        commands.push(VecDeepPatchCommand::Replace(rhs_pos, rhs_val));
1568                        self_next = self_it.next();
1569                        rhs_next = rhs_it.next();
1570                    } else if self_pos < rhs_pos {
1571                        commands.push(VecDeepPatchCommand::Replace(self_pos, self_val));
1572                        self_next = self_it.next();
1573                    } else {
1574                        commands.push(VecDeepPatchCommand::Replace(rhs_pos, rhs_val));
1575                        rhs_next = rhs_it.next();
1576                    }
1577                }
1578                (
1579                    VecDeepPatchCommand::Replace(self_pos, self_val),
1580                    VecDeepPatchCommand::Patch(rhs_pos, rhs_val),
1581                ) => {
1582                    if self_pos == rhs_pos {
1583                        let mut val = self_val.clone();
1584                        val.apply(rhs_val);
1585                        commands.push(VecDeepPatchCommand::Replace(rhs_pos, val));
1586                        self_next = self_it.next();
1587                        rhs_next = rhs_it.next();
1588                    } else if self_pos < rhs_pos {
1589                        commands.push(VecDeepPatchCommand::Replace(self_pos, self_val));
1590                        self_next = self_it.next();
1591                    } else {
1592                        commands.push(VecDeepPatchCommand::Patch(rhs_pos, rhs_val));
1593                        rhs_next = rhs_it.next();
1594                    }
1595                }
1596                (
1597                    VecDeepPatchCommand::Patch(self_pos, self_val),
1598                    VecDeepPatchCommand::Replace(rhs_pos, rhs_val),
1599                ) => {
1600                    if self_pos == rhs_pos {
1601                        commands.push(VecDeepPatchCommand::Replace(rhs_pos, rhs_val));
1602                        self_next = self_it.next();
1603                        rhs_next = rhs_it.next();
1604                    } else if self_pos < rhs_pos {
1605                        commands.push(VecDeepPatchCommand::Patch(self_pos, self_val));
1606                        self_next = self_it.next();
1607                    } else {
1608                        commands.push(VecDeepPatchCommand::Replace(rhs_pos, rhs_val));
1609                        rhs_next = rhs_it.next();
1610                    }
1611                }
1612                (
1613                    VecDeepPatchCommand::Patch(self_pos, self_val),
1614                    VecDeepPatchCommand::Patch(rhs_pos, rhs_val),
1615                ) => {
1616                    if self_pos == rhs_pos {
1617                        commands.push(VecDeepPatchCommand::Patch(rhs_pos, self_val.merge(rhs_val)));
1618                        self_next = self_it.next();
1619                        rhs_next = rhs_it.next();
1620                    } else if self_pos < rhs_pos {
1621                        commands.push(VecDeepPatchCommand::Patch(self_pos, self_val));
1622                        self_next = self_it.next();
1623                    } else {
1624                        commands.push(VecDeepPatchCommand::Patch(rhs_pos, rhs_val));
1625                        rhs_next = rhs_it.next();
1626                    }
1627                }
1628                (
1629                    VecDeepPatchCommand::InsertBefore(self_pos, self_val),
1630                    VecDeepPatchCommand::InsertBefore(rhs_pos, mut rhs_val),
1631                )
1632                | (
1633                    VecDeepPatchCommand::InsertAfter(self_pos, self_val),
1634                    VecDeepPatchCommand::InsertAfter(rhs_pos, mut rhs_val),
1635                ) => {
1636                    if self_pos == rhs_pos {
1637                        // We first add rhs elements then self elements
1638                        // For insert before, the position is the position of the first element added by the self patch
1639                        // For insert after, the position does not change so we append rhs elements after the elements, after that the self elements are added
1640                        rhs_val.extend(self_val);
1641                        commands.push(rhs_command.clone());
1642                        self_next = self_it.next();
1643                        rhs_next = rhs_it.next();
1644                    } else if self_pos < rhs_pos {
1645                        commands.push(self_command.clone());
1646                        self_next = self_it.next();
1647                    } else {
1648                        commands.push(rhs_command.clone());
1649                        rhs_next = rhs_it.next();
1650                    }
1651                }
1652                (
1653                    VecDeepPatchCommand::Replace(_, _)
1654                    | VecDeepPatchCommand::Patch(_, _)
1655                    | VecDeepPatchCommand::InsertBefore(_, _)
1656                    | VecDeepPatchCommand::InsertAfter(_, _),
1657                    VecDeepPatchCommand::Replace(_, _)
1658                    | VecDeepPatchCommand::Patch(_, _)
1659                    | VecDeepPatchCommand::InsertBefore(_, _)
1660                    | VecDeepPatchCommand::InsertAfter(_, _),
1661                ) => {
1662                    if sort_commands(self_command, rhs_command) == Ordering::Less {
1663                        commands.push(self_command.clone());
1664                        self_next = self_it.next();
1665                    } else {
1666                        commands.push(rhs_command.clone());
1667                        rhs_next = rhs_it.next();
1668                    }
1669                }
1670            }
1671        }
1672
1673        let remaining_commands = if self_next.is_some() {
1674            std::iter::once(self_next.unwrap()).chain(self_it)
1675        } else {
1676            std::iter::once(rhs_next.unwrap()).chain(self_it)
1677        };
1678        remaining_commands.for_each(|c| commands.push(c.clone()));
1679
1680        Self { commands }
1681    }
1682}
1683
1684impl<K, V> Merge for HashMapPatch<K, V>
1685where
1686    K: Clone + Eq + Hash,
1687    V: Clone,
1688{
1689    fn merge(self, other: Self) -> Self {
1690        let mut patches = self.patches;
1691        for (key, value) in other.patches {
1692            match value {
1693                Some(value) => {
1694                    patches.insert(key, Some(value));
1695                }
1696                None => {
1697                    patches.remove(&key);
1698                }
1699            }
1700        }
1701        HashMapPatch { patches }
1702    }
1703}
1704
1705impl<K, V> Merge for HashMapDeepPatch<K, V>
1706where
1707    K: Clone + Eq + Hash,
1708    V: Clone + Merge,
1709{
1710    fn merge(mut self, other: Self) -> Self {
1711        for (key, value) in other.patches {
1712            match value {
1713                Some(value) => match self.patches.get_mut(&key) {
1714                    Some(Some(patch)) => {
1715                        *patch = patch.clone().merge(value);
1716                    }
1717                    _ => {
1718                        self.patches.insert(key, Some(value));
1719                    }
1720                },
1721                None => {
1722                    self.patches.remove(&key);
1723                }
1724            }
1725        }
1726        self
1727    }
1728}
1729
1730#[cfg(not(feature = "strict"))]
1731impl<T> Merge for NestedMap<T>
1732where
1733    T: Clone,
1734{
1735    fn merge(mut self, other: Self) -> Self {
1736        let mut flatten = other.clone();
1737        flatten.flatten();
1738        self.flatten();
1739        for (key, value) in flatten.0 {
1740            self.0.insert(key.clone(), value.clone());
1741        }
1742        self
1743    }
1744}
1745
1746//////////////////////// Unit tests ////////////////////////
1747
1748#[cfg(test)]
1749mod test {
1750    use super::*;
1751    use pretty_assertions_sorted::assert_eq_sorted;
1752
1753    #[cfg(feature = "permissive")]
1754    mod parsable_struct {
1755        use super::*;
1756
1757        #[test]
1758        fn deserialize_basic_user() {
1759            let user: ParsableStruct<UserPatch> = serde_yaml::from_str("user").unwrap();
1760
1761            assert_eq_sorted!(
1762                user,
1763                ParsableStruct(UserPatch {
1764                    user: Some("user".into()),
1765                    group: Some(None),
1766                })
1767            );
1768        }
1769
1770        #[test]
1771        fn deserialize_user_error_wrong_username() {
1772            let res = serde_yaml::from_str::<ParsableStruct<UserPatch>>("user*name");
1773
1774            assert!(res.is_err());
1775
1776            assert_eq_sorted!(
1777                res.unwrap_err().to_string(),
1778                "Error while parsing a permissive struct: Not matching chown pattern"
1779            );
1780        }
1781
1782        #[test]
1783        fn deserialize_stage_with_invalid_user() {
1784            let res = serde_yaml::from_str::<StagePatch>("user: user*name");
1785
1786            assert!(res.is_err());
1787
1788            assert_eq_sorted!(
1789                res.unwrap_err().to_string(),
1790                "user: Error while parsing a permissive struct: Not matching chown pattern at line 1 column 7"
1791            );
1792        }
1793
1794        #[ignore = "Not managed yet by serde because of multilevel flatten: https://serde.rs/field-attrs.html#flatten"]
1795        #[test]
1796        fn deserialize_dofigen_with_invalid_user() {
1797            let res = serde_yaml::from_str::<DofigenPatch>("user: user*name");
1798
1799            assert!(res.is_err());
1800
1801            assert_eq_sorted!(
1802                res.unwrap_err().to_string(),
1803                "user: Error while parsing a permissive struct: Not matching chown pattern at line 1 column 7"
1804            );
1805        }
1806    }
1807
1808    mod vec_patch {
1809        use super::*;
1810        use serde::Deserialize;
1811        use struct_patch::Patch;
1812
1813        #[derive(Debug, Clone, PartialEq, Patch, Default)]
1814        #[patch(attribute(derive(Deserialize, Debug, Clone, PartialEq, Default)))]
1815        struct TestStruct {
1816            pub name: String,
1817            #[patch(name = "Option<SubTestStructPatch>")]
1818            pub sub: Option<SubTestStruct>,
1819        }
1820
1821        #[derive(Debug, Clone, PartialEq, Patch, Default)]
1822        #[patch(attribute(derive(Deserialize, Debug, Clone, PartialEq, Default)))]
1823        struct SubTestStruct {
1824            #[patch(name = "VecPatch<String>")]
1825            pub list: Vec<String>,
1826            pub num: Option<u32>,
1827        }
1828
1829        impl From<TestStructPatch> for TestStruct {
1830            fn from(patch: TestStructPatch) -> Self {
1831                let mut sub = Self::default();
1832                sub.apply(patch);
1833                sub
1834            }
1835        }
1836
1837        impl From<SubTestStructPatch> for SubTestStruct {
1838            fn from(patch: SubTestStructPatch) -> Self {
1839                let mut sub = Self::default();
1840                sub.apply(patch);
1841                sub
1842            }
1843        }
1844
1845        #[test]
1846        fn test_simple_patch() {
1847            let base = r#"
1848                name: patch1
1849                sub:
1850                  list:
1851                    - item1
1852                    - item2
1853                  num: 42
1854            "#;
1855
1856            let patch = r#"
1857                name: patch2
1858                sub:
1859                    num: 43
1860            "#;
1861
1862            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
1863                .unwrap()
1864                .into();
1865            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
1866
1867            base_data.apply(patch_data);
1868
1869            assert_eq_sorted!(
1870                base_data,
1871                TestStruct {
1872                    name: "patch2".into(),
1873                    sub: Some(SubTestStruct {
1874                        list: vec!["item1".into(), "item2".into()],
1875                        num: Some(43)
1876                    })
1877                }
1878            );
1879        }
1880
1881        #[test]
1882        fn test_vec_replace() {
1883            let base = r#"
1884                name: patch1
1885                sub:
1886                  list:
1887                    - item1
1888                    - item2
1889                  num: 42
1890            "#;
1891
1892            let patch = r#"
1893                sub:
1894                  list:
1895                    - item3
1896                    - item4
1897            "#;
1898
1899            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
1900                .unwrap()
1901                .into();
1902            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
1903
1904            base_data.apply(patch_data);
1905
1906            assert_eq_sorted!(
1907                base_data,
1908                TestStruct {
1909                    name: "patch1".into(),
1910                    sub: Some(SubTestStruct {
1911                        list: vec!["item3".into(), "item4".into()],
1912                        num: Some(42)
1913                    })
1914                }
1915            );
1916        }
1917
1918        #[test]
1919        fn test_vec_append_list_patch() {
1920            let base = r#"
1921                name: patch1
1922                sub:
1923                  list:
1924                    - item1
1925                    - item2
1926                  num: 42
1927            "#;
1928
1929            let patch = r#"
1930                sub:
1931                    list:
1932                        +:
1933                            - item3
1934                            - item4
1935            "#;
1936
1937            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
1938                .unwrap()
1939                .into();
1940            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
1941
1942            base_data.apply(patch_data);
1943
1944            assert_eq_sorted!(
1945                base_data,
1946                TestStruct {
1947                    name: "patch1".into(),
1948                    sub: Some(SubTestStruct {
1949                        list: vec![
1950                            "item1".into(),
1951                            "item2".into(),
1952                            "item3".into(),
1953                            "item4".into()
1954                        ],
1955                        num: Some(42)
1956                    })
1957                }
1958            );
1959        }
1960
1961        #[cfg(feature = "permissive")]
1962        #[test]
1963        fn test_vec_append_one_patch() {
1964            let base = r#"
1965                name: patch1
1966                sub:
1967                  list:
1968                    - item1
1969                    - item2
1970                  num: 42
1971            "#;
1972
1973            let patch = r#"
1974                sub:
1975                    list:
1976                        +: item3
1977            "#;
1978
1979            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
1980                .unwrap()
1981                .into();
1982            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
1983
1984            base_data.apply(patch_data);
1985
1986            assert_eq_sorted!(
1987                base_data,
1988                TestStruct {
1989                    name: "patch1".into(),
1990                    sub: Some(SubTestStruct {
1991                        list: vec!["item1".into(), "item2".into(), "item3".into()],
1992                        num: Some(42)
1993                    })
1994                }
1995            );
1996        }
1997
1998        #[test]
1999        fn test_vec_replace_patch() {
2000            let base = r#"
2001                name: patch1
2002                sub:
2003                  list:
2004                    - item1
2005                    - item2
2006                    - item3
2007                    - item4
2008                  num: 42
2009            "#;
2010
2011            let patch = r#"
2012                sub:
2013                    list:
2014                        1: item5
2015                        3: item6
2016            "#;
2017
2018            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2019                .unwrap()
2020                .into();
2021            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2022
2023            base_data.apply(patch_data);
2024
2025            assert_eq_sorted!(
2026                base_data,
2027                TestStruct {
2028                    name: "patch1".into(),
2029                    sub: Some(SubTestStruct {
2030                        list: vec![
2031                            "item1".into(),
2032                            "item5".into(),
2033                            "item3".into(),
2034                            "item6".into()
2035                        ],
2036                        num: Some(42)
2037                    })
2038                }
2039            );
2040        }
2041
2042        #[test]
2043        fn test_vec_insert_before_patch() {
2044            let base = r#"
2045                name: patch1
2046                sub:
2047                  list:
2048                    - item1
2049                    - item2
2050                    - item3
2051                    - item4
2052                  num: 42
2053            "#;
2054
2055            let patch = r#"
2056                sub:
2057                    list:
2058                        "+1": 
2059                          - item5
2060                          - item6
2061            "#;
2062
2063            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2064                .unwrap()
2065                .into();
2066            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2067
2068            base_data.apply(patch_data);
2069
2070            assert_eq_sorted!(
2071                base_data,
2072                TestStruct {
2073                    name: "patch1".into(),
2074                    sub: Some(SubTestStruct {
2075                        list: vec![
2076                            "item1".into(),
2077                            "item5".into(),
2078                            "item6".into(),
2079                            "item2".into(),
2080                            "item3".into(),
2081                            "item4".into()
2082                        ],
2083                        num: Some(42)
2084                    })
2085                }
2086            );
2087        }
2088
2089        #[test]
2090        fn test_vec_insert_after_patch() {
2091            let base = r#"
2092                name: patch1
2093                sub:
2094                  list:
2095                    - item1
2096                    - item2
2097                    - item3
2098                    - item4
2099                  num: 42
2100            "#;
2101
2102            let patch = r#"
2103                sub:
2104                    list:
2105                        1+: 
2106                          - item5
2107                          - item6
2108            "#;
2109
2110            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2111                .unwrap()
2112                .into();
2113            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2114
2115            base_data.apply(patch_data);
2116
2117            assert_eq_sorted!(
2118                base_data,
2119                TestStruct {
2120                    name: "patch1".into(),
2121                    sub: Some(SubTestStruct {
2122                        list: vec![
2123                            "item1".into(),
2124                            "item2".into(),
2125                            "item5".into(),
2126                            "item6".into(),
2127                            "item3".into(),
2128                            "item4".into()
2129                        ],
2130                        num: Some(42)
2131                    })
2132                }
2133            );
2134        }
2135
2136        #[test]
2137        fn test_vec_many_operations_patch() {
2138            let base = r#"
2139                name: patch1
2140                sub:
2141                  list:
2142                    - item1
2143                    - item2
2144                    - item3
2145                    - item4
2146                  num: 42
2147            "#;
2148
2149            let patch = r#"
2150                sub:
2151                    list:
2152                        "+2":
2153                          - item6
2154                        1+:
2155                          - item5
2156                        +:
2157                          - item7
2158                        0: item0
2159            "#;
2160
2161            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2162                .unwrap()
2163                .into();
2164            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2165
2166            base_data.apply(patch_data);
2167
2168            assert_eq_sorted!(
2169                base_data,
2170                TestStruct {
2171                    name: "patch1".into(),
2172                    sub: Some(SubTestStruct {
2173                        list: vec![
2174                            "item0".into(),
2175                            "item2".into(),
2176                            "item5".into(),
2177                            "item6".into(),
2178                            "item3".into(),
2179                            "item4".into(),
2180                            "item7".into()
2181                        ],
2182                        num: Some(42)
2183                    })
2184                }
2185            );
2186        }
2187    }
2188
2189    mod vec_deep_patch {
2190        use super::*;
2191        use serde::Deserialize;
2192        use struct_patch::Patch;
2193
2194        #[derive(Debug, Clone, PartialEq, Patch, Default)]
2195        #[patch(attribute(derive(Deserialize, Debug, Clone, PartialEq, Default)))]
2196        struct TestStruct {
2197            pub name: String,
2198            #[patch(name = "VecDeepPatch<SubTestStruct, SubTestStructPatch>")]
2199            pub subs: Vec<SubTestStruct>,
2200        }
2201
2202        #[derive(Debug, Clone, PartialEq, Patch, Default)]
2203        #[patch(attribute(derive(Deserialize, Debug, Clone, PartialEq, Default)))]
2204        struct SubTestStruct {
2205            pub name: String,
2206            pub num: u32,
2207        }
2208
2209        impl From<TestStructPatch> for TestStruct {
2210            fn from(patch: TestStructPatch) -> Self {
2211                let mut sub = Self::default();
2212                sub.apply(patch);
2213                sub
2214            }
2215        }
2216
2217        impl From<SubTestStructPatch> for SubTestStruct {
2218            fn from(patch: SubTestStructPatch) -> Self {
2219                let mut sub = Self::default();
2220                sub.apply(patch);
2221                sub
2222            }
2223        }
2224
2225        #[test]
2226        fn test_simple_patch() {
2227            let base = r#"
2228                name: patch1
2229                subs:
2230                  - name: sub1
2231                    num: 1
2232                  - name: sub2
2233                    num: 2
2234            "#;
2235
2236            let patch = r#"
2237                name: patch2
2238            "#;
2239
2240            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2241                .unwrap()
2242                .into();
2243            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2244
2245            base_data.apply(patch_data);
2246
2247            assert_eq_sorted!(
2248                base_data,
2249                TestStruct {
2250                    name: "patch2".into(),
2251                    subs: vec![
2252                        SubTestStruct {
2253                            name: "sub1".into(),
2254                            num: 1
2255                        },
2256                        SubTestStruct {
2257                            name: "sub2".into(),
2258                            num: 2
2259                        }
2260                    ],
2261                }
2262            );
2263        }
2264
2265        #[test]
2266        fn test_vec_replace() {
2267            let base = r#"
2268                name: patch1
2269                subs:
2270                  - name: sub1
2271                    num: 1
2272                  - name: sub2
2273                    num: 2
2274            "#;
2275
2276            let patch = r#"
2277                subs:
2278                  - name: sub3
2279                    num: 3
2280                  - name: sub4
2281                    num: 4
2282            "#;
2283
2284            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2285                .unwrap()
2286                .into();
2287            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2288
2289            base_data.apply(patch_data);
2290
2291            assert_eq_sorted!(
2292                base_data,
2293                TestStruct {
2294                    name: "patch1".into(),
2295                    subs: vec![
2296                        SubTestStruct {
2297                            name: "sub3".into(),
2298                            num: 3
2299                        },
2300                        SubTestStruct {
2301                            name: "sub4".into(),
2302                            num: 4
2303                        }
2304                    ]
2305                }
2306            );
2307        }
2308
2309        #[test]
2310        fn test_vec_append_list_patch() {
2311            let base = r#"
2312                name: patch1
2313                subs:
2314                  - name: sub1
2315                    num: 1
2316                  - name: sub2
2317                    num: 2
2318            "#;
2319
2320            let patch = r#"
2321                subs:
2322                  +:
2323                    - name: sub3
2324                      num: 3
2325                    - name: sub4
2326                      num: 4
2327            "#;
2328
2329            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2330                .unwrap()
2331                .into();
2332            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2333
2334            base_data.apply(patch_data);
2335
2336            assert_eq_sorted!(
2337                base_data,
2338                TestStruct {
2339                    name: "patch1".into(),
2340                    subs: vec![
2341                        SubTestStruct {
2342                            name: "sub1".into(),
2343                            num: 1
2344                        },
2345                        SubTestStruct {
2346                            name: "sub2".into(),
2347                            num: 2
2348                        },
2349                        SubTestStruct {
2350                            name: "sub3".into(),
2351                            num: 3
2352                        },
2353                        SubTestStruct {
2354                            name: "sub4".into(),
2355                            num: 4
2356                        }
2357                    ]
2358                }
2359            );
2360        }
2361
2362        #[cfg(feature = "permissive")]
2363        #[test]
2364        fn test_vec_append_one_patch() {
2365            let base = r#"
2366                name: patch1
2367                subs:
2368                  - name: sub1
2369                    num: 1
2370                  - name: sub2
2371                    num: 2
2372            "#;
2373
2374            let patch = r#"
2375                subs:
2376                  +:
2377                    name: sub3
2378                    num: 3
2379            "#;
2380
2381            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2382                .unwrap()
2383                .into();
2384            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2385
2386            base_data.apply(patch_data);
2387
2388            assert_eq_sorted!(
2389                base_data,
2390                TestStruct {
2391                    name: "patch1".into(),
2392                    subs: vec![
2393                        SubTestStruct {
2394                            name: "sub1".into(),
2395                            num: 1
2396                        },
2397                        SubTestStruct {
2398                            name: "sub2".into(),
2399                            num: 2
2400                        },
2401                        SubTestStruct {
2402                            name: "sub3".into(),
2403                            num: 3
2404                        }
2405                    ]
2406                }
2407            );
2408        }
2409
2410        #[test]
2411        fn test_vec_replace_patch() {
2412            let base = r#"
2413                name: patch1
2414                subs:
2415                  - name: sub1
2416                    num: 1
2417                  - name: sub2
2418                    num: 2
2419            "#;
2420
2421            let patch = r#"
2422                subs:
2423                  1: 
2424                    name: sub3
2425                    num: 3
2426            "#;
2427
2428            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2429                .unwrap()
2430                .into();
2431            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2432
2433            base_data.apply(patch_data);
2434
2435            assert_eq_sorted!(
2436                base_data,
2437                TestStruct {
2438                    name: "patch1".into(),
2439                    subs: vec![
2440                        SubTestStruct {
2441                            name: "sub1".into(),
2442                            num: 1
2443                        },
2444                        SubTestStruct {
2445                            name: "sub3".into(),
2446                            num: 3
2447                        },
2448                    ]
2449                }
2450            );
2451        }
2452
2453        #[test]
2454        fn test_vec_deep_patch() {
2455            let base = r#"
2456                name: patch1
2457                subs:
2458                  - name: sub1
2459                    num: 1
2460                  - name: sub2
2461                    num: 2
2462            "#;
2463
2464            let patch = r#"
2465                subs:
2466                  0<: 
2467                    num: 3
2468            "#;
2469
2470            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2471                .unwrap()
2472                .into();
2473            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2474
2475            base_data.apply(patch_data);
2476
2477            assert_eq_sorted!(
2478                base_data,
2479                TestStruct {
2480                    name: "patch1".into(),
2481                    subs: vec![
2482                        SubTestStruct {
2483                            name: "sub1".into(),
2484                            num: 3
2485                        },
2486                        SubTestStruct {
2487                            name: "sub2".into(),
2488                            num: 2
2489                        },
2490                    ]
2491                }
2492            );
2493        }
2494
2495        #[test]
2496        fn test_vec_insert_before_patch() {
2497            let base = r#"
2498                name: patch1
2499                subs:
2500                  - name: sub1
2501                    num: 1
2502                  - name: sub2
2503                    num: 2
2504                  - name: sub3
2505                    num: 3
2506                  - name: sub4
2507                    num: 4
2508            "#;
2509
2510            let patch = r#"
2511                subs:
2512                    "+1":
2513                        - name: sub5
2514                          num: 5
2515                        - name: sub6
2516                          num: 6
2517            "#;
2518
2519            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2520                .unwrap()
2521                .into();
2522            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2523
2524            base_data.apply(patch_data);
2525
2526            assert_eq_sorted!(
2527                base_data,
2528                TestStruct {
2529                    name: "patch1".into(),
2530                    subs: vec![
2531                        SubTestStruct {
2532                            name: "sub1".into(),
2533                            num: 1
2534                        },
2535                        SubTestStruct {
2536                            name: "sub5".into(),
2537                            num: 5
2538                        },
2539                        SubTestStruct {
2540                            name: "sub6".into(),
2541                            num: 6
2542                        },
2543                        SubTestStruct {
2544                            name: "sub2".into(),
2545                            num: 2
2546                        },
2547                        SubTestStruct {
2548                            name: "sub3".into(),
2549                            num: 3
2550                        },
2551                        SubTestStruct {
2552                            name: "sub4".into(),
2553                            num: 4
2554                        },
2555                    ]
2556                }
2557            );
2558        }
2559
2560        #[test]
2561        fn test_vec_insert_after_patch() {
2562            let base = r#"
2563              name: patch1
2564              subs:
2565                - name: sub1
2566                  num: 1
2567                - name: sub2
2568                  num: 2
2569                - name: sub3
2570                  num: 3
2571                - name: sub4
2572                  num: 4
2573            "#;
2574
2575            let patch = r#"
2576                subs:
2577                  1+:
2578                    - name: sub5
2579                      num: 5
2580                    - name: sub6
2581                      num: 6
2582            "#;
2583
2584            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2585                .unwrap()
2586                .into();
2587            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2588
2589            base_data.apply(patch_data);
2590
2591            assert_eq_sorted!(
2592                base_data,
2593                TestStruct {
2594                    name: "patch1".into(),
2595                    subs: vec![
2596                        SubTestStruct {
2597                            name: "sub1".into(),
2598                            num: 1
2599                        },
2600                        SubTestStruct {
2601                            name: "sub2".into(),
2602                            num: 2
2603                        },
2604                        SubTestStruct {
2605                            name: "sub5".into(),
2606                            num: 5
2607                        },
2608                        SubTestStruct {
2609                            name: "sub6".into(),
2610                            num: 6
2611                        },
2612                        SubTestStruct {
2613                            name: "sub3".into(),
2614                            num: 3
2615                        },
2616                        SubTestStruct {
2617                            name: "sub4".into(),
2618                            num: 4
2619                        },
2620                    ]
2621                }
2622            );
2623        }
2624
2625        #[test]
2626        fn test_vec_many_operations_patch() {
2627            let base = r#"
2628              name: patch1
2629              subs:
2630                - name: sub1
2631                  num: 1
2632                - name: sub2
2633                  num: 2
2634                - name: sub3
2635                  num: 3
2636                - name: sub4
2637                  num: 4
2638            "#;
2639
2640            let patch = r#"
2641                subs:
2642                  "+2":
2643                    - name: sub6
2644                      num: 6
2645                  1+:
2646                    - name: sub5
2647                      num: 5
2648                  +:
2649                    - name: sub7
2650                      num: 7
2651                  0:
2652                    name: sub0
2653                    num: 0
2654                  1<:
2655                    num: 1
2656            "#;
2657
2658            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2659                .unwrap()
2660                .into();
2661            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2662
2663            base_data.apply(patch_data);
2664
2665            assert_eq_sorted!(
2666                base_data,
2667                TestStruct {
2668                    name: "patch1".into(),
2669                    subs: vec![
2670                        SubTestStruct {
2671                            name: "sub0".into(),
2672                            num: 0
2673                        },
2674                        SubTestStruct {
2675                            name: "sub2".into(),
2676                            num: 1
2677                        },
2678                        SubTestStruct {
2679                            name: "sub5".into(),
2680                            num: 5
2681                        },
2682                        SubTestStruct {
2683                            name: "sub6".into(),
2684                            num: 6
2685                        },
2686                        SubTestStruct {
2687                            name: "sub3".into(),
2688                            num: 3
2689                        },
2690                        SubTestStruct {
2691                            name: "sub4".into(),
2692                            num: 4
2693                        },
2694                        SubTestStruct {
2695                            name: "sub7".into(),
2696                            num: 7
2697                        },
2698                    ]
2699                }
2700            );
2701        }
2702    }
2703
2704    mod hashmap_patch {
2705        use super::*;
2706        use serde::Deserialize;
2707        use struct_patch::Patch;
2708
2709        #[derive(Debug, Clone, PartialEq, Patch, Default)]
2710        #[patch(attribute(derive(Deserialize, Debug, Clone, PartialEq, Default)))]
2711        struct TestStruct {
2712            pub name: String,
2713            #[patch(name = "HashMapPatch<String, String>")]
2714            pub subs: HashMap<String, String>,
2715        }
2716
2717        impl From<TestStructPatch> for TestStruct {
2718            fn from(patch: TestStructPatch) -> Self {
2719                let mut sub = Self::default();
2720                sub.apply(patch);
2721                sub
2722            }
2723        }
2724
2725        #[test]
2726        fn test_simple_patch() {
2727            let base = r#"
2728                name: patch1
2729                subs:
2730                  sub1: value1
2731                  sub2: value2
2732            "#;
2733
2734            let patch = r#"
2735                name: patch2
2736                subs:
2737                  sub2: null
2738                  sub3: value3
2739            "#;
2740
2741            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2742                .unwrap()
2743                .into();
2744            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2745
2746            base_data.apply(patch_data);
2747
2748            assert_eq_sorted!(
2749                base_data,
2750                TestStruct {
2751                    name: "patch2".into(),
2752                    subs: HashMap::from([
2753                        ("sub1".to_string(), "value1".to_string()),
2754                        ("sub3".to_string(), "value3".to_string())
2755                    ])
2756                }
2757            );
2758        }
2759    }
2760
2761    mod hashmap_deep_patch {
2762        use super::*;
2763        use serde::Deserialize;
2764        use struct_patch::Patch;
2765
2766        #[derive(Debug, Clone, PartialEq, Patch, Default)]
2767        #[patch(attribute(derive(Deserialize, Debug, Clone, PartialEq, Default)))]
2768        struct TestStruct {
2769            pub name: String,
2770            #[patch(name = "HashMapDeepPatch<String, TestSubStructPatch>")]
2771            pub subs: HashMap<String, TestSubStruct>,
2772        }
2773
2774        #[derive(Debug, Clone, PartialEq, Patch, Default)]
2775        #[patch(attribute(derive(Deserialize, Debug, Clone, PartialEq, Default)))]
2776        struct TestSubStruct {
2777            pub name: String,
2778        }
2779
2780        impl From<TestStructPatch> for TestStruct {
2781            fn from(patch: TestStructPatch) -> Self {
2782                let mut sub = Self::default();
2783                sub.apply(patch);
2784                sub
2785            }
2786        }
2787
2788        impl From<TestSubStructPatch> for TestSubStruct {
2789            fn from(patch: TestSubStructPatch) -> Self {
2790                let mut sub = Self::default();
2791                sub.apply(patch);
2792                sub
2793            }
2794        }
2795
2796        #[test]
2797        fn test_simple_patch() {
2798            let base = r#"
2799                name: patch1
2800                subs:
2801                  sub1:
2802                    name: value1
2803                  sub2:
2804                    name: value2
2805            "#;
2806
2807            let patch = r#"
2808                name: patch2
2809                subs:
2810                  sub1:
2811                    name: value2
2812                  sub2: null
2813                  sub3:
2814                    name: value3
2815            "#;
2816
2817            let mut base_data: TestStruct = serde_yaml::from_str::<TestStructPatch>(base)
2818                .unwrap()
2819                .into();
2820            let patch_data: TestStructPatch = serde_yaml::from_str(patch).unwrap();
2821
2822            base_data.apply(patch_data);
2823
2824            assert_eq_sorted!(
2825                base_data,
2826                TestStruct {
2827                    name: "patch2".into(),
2828                    subs: HashMap::from([
2829                        (
2830                            "sub1".to_string(),
2831                            TestSubStruct {
2832                                name: "value2".to_string()
2833                            }
2834                        ),
2835                        (
2836                            "sub3".to_string(),
2837                            TestSubStruct {
2838                                name: "value3".to_string()
2839                            }
2840                        )
2841                    ])
2842                }
2843            );
2844        }
2845    }
2846
2847    #[cfg(feature = "permissive")]
2848    mod nested_map {
2849
2850        use super::*;
2851
2852        #[test]
2853        fn test_nested_map_patch() {
2854            let mut base_data: HashMap<String, String> =
2855                HashMap::from([("key1.key2".to_string(), "value2".to_string())]);
2856            let patch_data: NestedMap<String> = NestedMap(HashMap::from([
2857                (
2858                    "key1".to_string(),
2859                    NestedMapValue::Map(NestedMap(HashMap::from([(
2860                        "key2".to_string(),
2861                        NestedMapValue::Value("patch 1".to_string()),
2862                    )]))),
2863                ),
2864                (
2865                    "key1.key3".to_string(),
2866                    NestedMapValue::Value("value3".to_string()),
2867                ),
2868            ]));
2869
2870            base_data.apply(patch_data);
2871
2872            assert_eq!(
2873                base_data,
2874                HashMap::from([
2875                    ("key1.key2".to_string(), "patch 1".to_string()),
2876                    ("key1.key3".to_string(), "value3".to_string())
2877                ])
2878            );
2879        }
2880    }
2881
2882    #[cfg(feature = "permissive")]
2883    mod deserialize {
2884        use super::*;
2885
2886        mod one_or_many {
2887            use super::*;
2888
2889            #[derive(Deserialize, Debug, Clone, PartialEq)]
2890            struct TestStruct {
2891                pub one_or_many: OneOrMany<String>,
2892            }
2893
2894            #[test]
2895            fn one() {
2896                let ret: TestStruct = serde_yaml::from_str("one_or_many: test").unwrap();
2897                assert_eq_sorted!(
2898                    ret,
2899                    TestStruct {
2900                        one_or_many: OneOrMany(vec!["test".into()])
2901                    }
2902                )
2903            }
2904
2905            #[test]
2906            fn many() {
2907                let ret: TestStruct = serde_yaml::from_str("one_or_many: [test]").unwrap();
2908                assert_eq_sorted!(
2909                    ret,
2910                    TestStruct {
2911                        one_or_many: OneOrMany(vec!["test".into()])
2912                    }
2913                )
2914            }
2915        }
2916
2917        mod optional_one_or_many {
2918            use super::*;
2919
2920            #[derive(Deserialize, Debug, Clone, PartialEq, Default)]
2921            struct TestStruct {
2922                pub test: Option<String>,
2923                pub one_or_many: Option<OneOrMany<String>>,
2924            }
2925
2926            #[test]
2927            fn one() {
2928                let ret: TestStruct = serde_yaml::from_str("one_or_many: test").unwrap();
2929                assert_eq_sorted!(
2930                    ret,
2931                    TestStruct {
2932                        test: None,
2933                        one_or_many: Some(OneOrMany(vec!["test".into()]))
2934                    }
2935                )
2936            }
2937
2938            #[test]
2939            fn many() {
2940                let ret: TestStruct = serde_yaml::from_str("one_or_many: [test]").unwrap();
2941                assert_eq_sorted!(
2942                    ret,
2943                    TestStruct {
2944                        test: None,
2945                        one_or_many: Some(OneOrMany(vec!["test".into()]))
2946                    }
2947                )
2948            }
2949
2950            #[test]
2951            fn null() {
2952                let ret: TestStruct = serde_yaml::from_str("one_or_many: null").unwrap();
2953                assert_eq_sorted!(
2954                    ret,
2955                    TestStruct {
2956                        test: None,
2957                        one_or_many: None
2958                    }
2959                )
2960            }
2961
2962            #[test]
2963            fn absent() {
2964                let ret: TestStruct = serde_yaml::from_str("test: test").unwrap();
2965                assert_eq_sorted!(
2966                    ret,
2967                    TestStruct {
2968                        test: Some("test".into()),
2969                        one_or_many: None
2970                    }
2971                )
2972            }
2973        }
2974
2975        #[cfg(feature = "permissive")]
2976        mod from_optional_string_or_number {
2977            use super::*;
2978
2979            #[derive(Deserialize, Debug, Clone, PartialEq, Default)]
2980            struct TestStruct {
2981                #[serde(
2982                    deserialize_with = "deserialize_from_optional_string_or_number",
2983                    default
2984                )]
2985                pub test: Option<Option<String>>,
2986            }
2987
2988            #[test]
2989            fn string() {
2990                let ret: TestStruct = serde_yaml::from_str("test: \"123\"").unwrap();
2991                assert_eq_sorted!(
2992                    ret,
2993                    TestStruct {
2994                        test: Some(Some("123".into()))
2995                    }
2996                )
2997            }
2998
2999            #[test]
3000            fn number() {
3001                let ret: TestStruct = serde_yaml::from_str("test: 123").unwrap();
3002                assert_eq_sorted!(
3003                    ret,
3004                    TestStruct {
3005                        test: Some(Some("123".into()))
3006                    }
3007                )
3008            }
3009
3010            #[test]
3011            fn null() {
3012                let ret: TestStruct = serde_yaml::from_str("test: null").unwrap();
3013                assert_eq_sorted!(ret, TestStruct { test: Some(None) })
3014            }
3015
3016            #[test]
3017            fn absent() {
3018                let ret: TestStruct = serde_yaml::from_str("").unwrap();
3019                assert_eq_sorted!(ret, TestStruct { test: None })
3020            }
3021        }
3022
3023        mod nested_map {
3024
3025            use super::*;
3026
3027            #[test]
3028            fn test_single_level_map() {
3029                let yaml = r#"
3030                        key1: value1
3031                        key2: value2
3032                        key3:
3033                    "#;
3034
3035                let result: NestedMap<String> = serde_yaml::from_str(yaml).unwrap();
3036
3037                assert_eq!(
3038                    result,
3039                    NestedMap(HashMap::from([
3040                        (
3041                            "key1".to_string(),
3042                            NestedMapValue::Value("value1".to_string())
3043                        ),
3044                        (
3045                            "key2".to_string(),
3046                            NestedMapValue::Value("value2".to_string())
3047                        ),
3048                        ("key3".to_string(), NestedMapValue::Null)
3049                    ]))
3050                );
3051            }
3052
3053            #[test]
3054            fn test_multilevel_map() {
3055                let yaml = r#"
3056                        key1:
3057                          key2: value
3058                    "#;
3059
3060                let result: NestedMap<String> = serde_yaml::from_str(yaml).unwrap();
3061
3062                assert_eq!(
3063                    result,
3064                    NestedMap(HashMap::from([(
3065                        "key1".to_string(),
3066                        NestedMapValue::Map(NestedMap(HashMap::from([(
3067                            "key2".to_string(),
3068                            NestedMapValue::Value("value".to_string())
3069                        )])))
3070                    )]))
3071                );
3072            }
3073
3074            #[test]
3075            fn test_equivalent_flattened_map() {
3076                let yaml = r#"
3077                          key1.key2: value
3078                    "#;
3079
3080                let result: NestedMap<String> = serde_yaml::from_str(yaml).unwrap();
3081
3082                assert_eq!(
3083                    result,
3084                    NestedMap(HashMap::from([(
3085                        "key1.key2".to_string(),
3086                        NestedMapValue::Value("value".to_string())
3087                    )]))
3088                );
3089            }
3090
3091            #[test]
3092            fn test_combined_multilevel_and_flattened_map() {
3093                let yaml = r#"
3094                          key1:
3095                            key2: value2
3096                          key1.key3: value3
3097                    "#;
3098
3099                let result: NestedMap<String> = serde_yaml::from_str(yaml).unwrap();
3100
3101                assert_eq!(
3102                    result,
3103                    NestedMap(HashMap::from([
3104                        (
3105                            "key1".to_string(),
3106                            NestedMapValue::Map(NestedMap(HashMap::from([(
3107                                "key2".to_string(),
3108                                NestedMapValue::Value("value2".to_string())
3109                            )])))
3110                        ),
3111                        (
3112                            "key1.key3".to_string(),
3113                            NestedMapValue::Value("value3".to_string())
3114                        )
3115                    ]))
3116                );
3117            }
3118
3119            #[test]
3120            fn test_empty_map() {
3121                let yaml = r#"
3122                    "#;
3123
3124                let result: NestedMap<String> = serde_yaml::from_str(yaml).unwrap();
3125
3126                assert_eq!(result, NestedMap(HashMap::new()));
3127            }
3128
3129            #[test]
3130            fn test_nested_empty_map() {
3131                let yaml = r#"
3132                          key1: {}
3133                    "#;
3134
3135                let result: NestedMap<String> = serde_yaml::from_str(yaml).unwrap();
3136
3137                assert_eq!(
3138                    result,
3139                    NestedMap(HashMap::from([(
3140                        "key1".to_string(),
3141                        NestedMapValue::Map(NestedMap(HashMap::new()))
3142                    )]))
3143                );
3144            }
3145        }
3146    }
3147}