bucky_objects/objects/
raw_diff.rs

1use crate::*;
2
3use generic_array::typenum::{U32, U48};
4use generic_array::{ArrayLength, GenericArray};
5use std::convert::From;
6
7//--------------------------
8// DiffOpCode/DiffOpRef/DiffOp/RawDiff/RawPatch
9//--------------------------
10
11#[derive(Debug)]
12pub enum DiffOpCode {
13    // Scalar
14    None,
15    Set,
16
17    // Option<T>
18    SetNone,
19
20    // Vec<T>
21    Add,
22    Remove,
23    TrimEnd,
24}
25
26impl DiffOpCode {
27    pub fn eq_or_set<T: PartialEq>(l: &T, r: &T) -> Self {
28        if l.eq(r) {
29            DiffOpCode::None
30        } else {
31            DiffOpCode::Set
32        }
33    }
34}
35
36impl From<&u8> for DiffOpCode {
37    fn from(req_type: &u8) -> Self {
38        match req_type {
39            0u8 => DiffOpCode::None,
40            1u8 => DiffOpCode::Set,
41            2u8 => DiffOpCode::SetNone,
42            3u8 => DiffOpCode::Add,
43            4u8 => DiffOpCode::Remove,
44            5u8 => DiffOpCode::TrimEnd,
45            _ => DiffOpCode::None, // TODO
46        }
47    }
48}
49
50impl From<u8> for DiffOpCode {
51    fn from(req_type: u8) -> Self {
52        (&req_type).into()
53    }
54}
55
56impl From<&DiffOpCode> for u8 {
57    fn from(t: &DiffOpCode) -> u8 {
58        match t {
59            DiffOpCode::None => 0u8,
60            DiffOpCode::Set => 1u8,
61            DiffOpCode::SetNone => 2u8,
62            DiffOpCode::Add => 3u8,
63            DiffOpCode::Remove => 4u8,
64            DiffOpCode::TrimEnd => 5u8,
65        }
66    }
67}
68
69impl From<DiffOpCode> for u8 {
70    fn from(t: DiffOpCode) -> u8 {
71        (&t).into()
72    }
73}
74
75pub struct DiffOpRef<'op, T> {
76    pub code: DiffOpCode,
77    pub value: &'op T,
78}
79
80impl<'op, T> RawEncode for DiffOpRef<'op, T>
81where
82    T: RawEncode,
83{
84    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
85        match self.code {
86            DiffOpCode::None => Ok(u8::raw_bytes().unwrap()),
87            _ => Ok(u8::raw_bytes().unwrap() + self.value.raw_measure(purpose)?),
88        }
89    }
90
91    fn raw_encode<'a>(
92        &self,
93        buf: &'a mut [u8],
94        purpose: &Option<RawEncodePurpose>,
95    ) -> BuckyResult<&'a mut [u8]> {
96        let size = self.raw_measure(purpose).unwrap();
97        if buf.len() < size {
98            return Err(BuckyError::new(
99                BuckyErrorCode::OutOfLimit,
100                "[raw_encode] not enough buffer for DiffOpRef",
101            ));
102        }
103
104        let code: u8 = (&self.code).into();
105        let buf = code.raw_encode(buf, purpose)?;
106
107        match self.code {
108            DiffOpCode::None => {
109                println!("scalar type diff is none");
110                Ok(buf)
111            }
112            _ => {
113                let buf = self.value.raw_encode(buf, purpose)?;
114                Ok(buf)
115            }
116        }
117    }
118}
119
120pub struct DiffOp<T> {
121    pub code: DiffOpCode,
122    pub value: Option<T>,
123}
124
125impl<'de, T> RawDecode<'de> for DiffOp<T>
126where
127    T: RawDecode<'de>,
128{
129    fn raw_decode(buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
130        let (code, buf) = u8::raw_decode(buf)?;
131
132        match code.into() {
133            DiffOpCode::None => Ok((
134                Self {
135                    code: code.into(),
136                    value: None,
137                },
138                buf,
139            )),
140            _ => {
141                let (value, buf) = T::raw_decode(buf)?;
142
143                Ok((
144                    Self {
145                        code: code.into(),
146                        value: Some(value),
147                    },
148                    buf,
149                ))
150            }
151        }
152    }
153}
154
155pub trait RawDiff: RawEncode {
156    fn diff_measure(&self, right: &Self) -> BuckyResult<usize>;
157    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]>;
158}
159
160pub trait RawPatch<'de>: RawDecode<'de> {
161    fn patch(self, diff: &'de [u8]) -> BuckyResult<(Self, &'de [u8])>;
162}
163
164pub trait RawDiffWithContext<'v, Context>: RawEncode {
165    fn diff_measure(&self, right: &'v Self, _: &mut Context) -> BuckyResult<usize>;
166    fn diff<'d>(
167        &self,
168        right: &Self,
169        buf: &'d mut [u8],
170        _: &mut Context,
171    ) -> BuckyResult<&'d mut [u8]>;
172}
173
174pub trait RawPatchWithContext<'de, Context>: RawDecode<'de> {
175    fn patch(self, diff: &'de [u8], _: &mut Context) -> BuckyResult<(Self, &'de [u8])>;
176}
177
178//--------------------------
179// u8
180//--------------------------
181
182impl RawDiff for u8 {
183    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
184        let op = DiffOpRef::<u8> {
185            code: DiffOpCode::eq_or_set(self, right),
186            value: right,
187        };
188        op.raw_measure(&None)
189    }
190
191    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
192        let op = DiffOpRef::<u8> {
193            code: DiffOpCode::eq_or_set(self, right),
194            value: right,
195        };
196        op.raw_encode(buf, &None)
197    }
198}
199
200impl<'de> RawPatch<'de> for u8 {
201    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
202        let (op, buf) = DiffOp::<u8>::raw_decode(buf)?;
203
204        match op.code {
205            DiffOpCode::None => Ok((self, buf)),
206            DiffOpCode::Set => Ok((op.value.unwrap(), buf)),
207            _ => Err(BuckyError::from(format!(
208                "Scalar Type Can not diff by opcode:{:?}",
209                op.code
210            ))),
211        }
212    }
213}
214
215//--------------------------
216// u16
217//--------------------------
218
219impl RawDiff for u16 {
220    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
221        let op = DiffOpRef::<u16> {
222            code: DiffOpCode::eq_or_set(self, right),
223            value: right,
224        };
225        op.raw_measure(&None)
226    }
227
228    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
229        let op = DiffOpRef::<u16> {
230            code: DiffOpCode::eq_or_set(self, right),
231            value: right,
232        };
233        op.raw_encode(buf, &None)
234    }
235}
236
237impl<'de> RawPatch<'de> for u16 {
238    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
239        let (op, buf) = DiffOp::<u16>::raw_decode(buf)?;
240        match op.code {
241            DiffOpCode::None => Ok((self, buf)),
242            DiffOpCode::Set => Ok((op.value.unwrap(), buf)),
243            _ => Err(BuckyError::from(format!(
244                "Scalar Type Can not diff by opcode:{:?}",
245                op.code
246            ))),
247        }
248    }
249}
250
251//--------------------------
252// u32
253//--------------------------
254
255impl RawDiff for u32 {
256    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
257        let op = DiffOpRef::<u32> {
258            code: DiffOpCode::eq_or_set(self, right),
259            value: right,
260        };
261        op.raw_measure(&None)
262    }
263
264    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
265        let op = DiffOpRef::<u32> {
266            code: DiffOpCode::eq_or_set(self, right),
267            value: right,
268        };
269        op.raw_encode(buf, &None)
270    }
271}
272
273impl<'de> RawPatch<'de> for u32 {
274    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
275        let (op, buf) = DiffOp::<u32>::raw_decode(buf)?;
276        match op.code {
277            DiffOpCode::None => Ok((self, buf)),
278            DiffOpCode::Set => Ok((op.value.unwrap(), buf)),
279            _ => Err(BuckyError::from(format!(
280                "Scalar Type Can not diff by opcode:{:?}",
281                op.code
282            ))),
283        }
284    }
285}
286
287//--------------------------
288// u64
289//--------------------------
290
291impl RawDiff for u64 {
292    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
293        let op = DiffOpRef::<u64> {
294            code: DiffOpCode::eq_or_set(self, right),
295            value: right,
296        };
297        op.raw_measure(&None)
298    }
299
300    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
301        let op = DiffOpRef::<u64> {
302            code: DiffOpCode::eq_or_set(self, right),
303            value: right,
304        };
305        op.raw_encode(buf, &None)
306    }
307}
308
309impl<'de> RawPatch<'de> for u64 {
310    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
311        let (op, buf) = DiffOp::<u64>::raw_decode(buf)?;
312        match op.code {
313            DiffOpCode::None => Ok((self, buf)),
314            DiffOpCode::Set => Ok((op.value.unwrap(), buf)),
315            _ => Err(BuckyError::from(format!(
316                "Scalar Type Can not diff by opcode:{:?}",
317                op.code
318            ))),
319        }
320    }
321}
322
323//--------------------------
324// u128
325//--------------------------
326
327impl RawDiff for u128 {
328    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
329        let op = DiffOpRef::<u128> {
330            code: DiffOpCode::eq_or_set(self, right),
331            value: right,
332        };
333        op.raw_measure(&None)
334    }
335
336    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
337        let op = DiffOpRef::<u128> {
338            code: DiffOpCode::eq_or_set(self, right),
339            value: right,
340        };
341        op.raw_encode(buf, &None)
342    }
343}
344
345impl<'de> RawPatch<'de> for u128 {
346    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
347        let (op, buf) = DiffOp::<u128>::raw_decode(buf)?;
348        match op.code {
349            DiffOpCode::None => Ok((self, buf)),
350            DiffOpCode::Set => Ok((op.value.unwrap(), buf)),
351            _ => Err(BuckyError::from(format!(
352                "Scalar Type Can not diff by opcode:{:?}",
353                op.code
354            ))),
355        }
356    }
357}
358
359//--------------------------
360// String/str
361//--------------------------
362
363impl RawDiff for String {
364    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
365        let op = DiffOpRef::<String> {
366            code: DiffOpCode::eq_or_set(self, right),
367            value: right,
368        };
369        op.raw_measure(&None)
370    }
371
372    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
373        let op = DiffOpRef::<String> {
374            code: DiffOpCode::eq_or_set(self, right),
375            value: right,
376        };
377        op.raw_encode(buf, &None)
378    }
379}
380
381impl<'de> RawPatch<'de> for String {
382    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
383        let (op, buf) = DiffOp::<String>::raw_decode(buf)?;
384        match op.code {
385            DiffOpCode::None => Ok((self, buf)),
386            DiffOpCode::Set => Ok((op.value.unwrap(), buf)),
387            _ => Err(BuckyError::from(format!(
388                "Scalar Type Can not diff by opcode:{:?}",
389                op.code
390            ))),
391        }
392    }
393}
394
395impl RawDiff for str {
396    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
397        let code = if self == right {
398            DiffOpCode::None
399        } else {
400            DiffOpCode::Set
401        };
402        match code {
403            DiffOpCode::None => Ok(u8::raw_bytes().unwrap()),
404            DiffOpCode::Set => Ok(u8::raw_bytes().unwrap() + right.raw_measure(&None)?),
405            _ => Err(BuckyError::from(format!(
406                "Scalar Type Can not diff by opcode:{:?}",
407                code
408            ))),
409        }
410    }
411
412    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
413        let size = self.raw_measure(&None).unwrap();
414        if buf.len() < size {
415            return Err(BuckyError::new(
416                BuckyErrorCode::OutOfLimit,
417                "[raw_diff] not enough buffer for str diff",
418            ));
419        }
420
421        let code = if self == right {
422            DiffOpCode::None
423        } else {
424            DiffOpCode::Set
425        };
426
427        let ucode: u8 = (&code).into();
428        let buf = ucode.raw_encode(buf, &None)?;
429
430        match code {
431            DiffOpCode::None => Ok(buf),
432            DiffOpCode::Set => {
433                let buf = right.raw_encode(buf, &None)?;
434                Ok(buf)
435            }
436            _ => Err(BuckyError::from(format!(
437                "Scalar Type Can not diff by opcode:{:?}",
438                code
439            ))),
440        }
441    }
442}
443
444//--------------------------
445// GenericArray
446//--------------------------
447impl<T: RawEncode + PartialEq, U: ArrayLength<T>> RawDiff for GenericArray<T, U> {
448    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
449        let op = DiffOpRef::<Self> {
450            code: DiffOpCode::eq_or_set(self, right),
451            value: right,
452        };
453        op.raw_measure(&None)
454    }
455
456    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
457        let op = DiffOpRef::<Self> {
458            code: DiffOpCode::eq_or_set(self, right),
459            value: right,
460        };
461        op.raw_encode(buf, &None)
462    }
463}
464
465impl<'de, T: RawEncode + RawDecode<'de> + Default, U: ArrayLength<T>> RawPatch<'de>
466    for GenericArray<T, U>
467{
468    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
469        let (op, buf) = DiffOp::<Self>::raw_decode(buf)?;
470        match op.code {
471            DiffOpCode::None => {
472                println!("genneric array patch is none");
473                Ok((self, buf))
474            }
475            DiffOpCode::Set => Ok((op.value.unwrap(), buf)),
476            _ => Err(BuckyError::from(format!(
477                "Scalar Type Can not diff by opcode:{:?}",
478                op.code
479            ))),
480        }
481    }
482}
483
484//--------------------------
485// Option<T>
486//--------------------------
487impl<T: RawDiff> RawDiff for Option<T> {
488    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
489        match self {
490            Some(left) => {
491                match right {
492                    Some(right) => {
493                        // Compare
494                        left.diff_measure(right)
495                    }
496                    None => {
497                        // SetNone
498                        Ok(u8::raw_bytes().unwrap())
499                    }
500                }
501            }
502            None => {
503                match right {
504                    Some(right) => {
505                        // Set+right
506                        let op = DiffOpRef::<T> {
507                            code: DiffOpCode::Set,
508                            value: right,
509                        };
510                        op.raw_measure(&None)
511                    }
512                    None => {
513                        // None
514                        Ok(u8::raw_bytes().unwrap())
515                    }
516                }
517            }
518        }
519    }
520
521    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
522        match self {
523            Some(left) => {
524                match right {
525                    Some(right) => {
526                        // Compare
527                        left.diff(right, buf)
528                    }
529                    None => {
530                        // SetNone
531                        let code: u8 = DiffOpCode::SetNone.into();
532                        code.raw_encode(buf, &None)
533                    }
534                }
535            }
536            None => {
537                match right {
538                    Some(right) => {
539                        // Set+right
540                        let op = DiffOpRef::<T> {
541                            code: DiffOpCode::Set,
542                            value: right,
543                        };
544                        op.raw_encode(buf, &None)
545                    }
546                    None => {
547                        // None
548                        let code: u8 = DiffOpCode::None.into();
549                        code.raw_encode(buf, &None)
550                    }
551                }
552            }
553        }
554    }
555}
556
557impl<'v, U, T: RawDiffWithContext<'v, VecDiffContext<'v, U>>>
558    RawDiffWithContext<'v, VecDiffContext<'v, U>> for OptionRef<'v, T>
559{
560    fn diff_measure(&self, right: &'v Self, ctx: &mut VecDiffContext<'v, U>) -> BuckyResult<usize> {
561        let left: Option<&'v T> = self.option();
562        let right: Option<&'v T> = right.option();
563        match left {
564            Some(left) => {
565                match right {
566                    Some(right) => {
567                        // Compare
568                        left.diff_measure(right, ctx)
569                    }
570                    None => {
571                        // SetNone
572                        Ok(u8::raw_bytes().unwrap())
573                    }
574                }
575            }
576            None => {
577                match right {
578                    Some(right) => {
579                        // Set+right
580                        let op = DiffOpRef::<T> {
581                            code: DiffOpCode::Set,
582                            value: right,
583                        };
584                        op.raw_measure(&None)
585                    }
586                    None => {
587                        // None
588                        Ok(u8::raw_bytes().unwrap())
589                    }
590                }
591            }
592        }
593    }
594
595    fn diff<'d>(
596        &self,
597        right: &Self,
598        buf: &'d mut [u8],
599        ctx: &mut VecDiffContext<'v, U>,
600    ) -> BuckyResult<&'d mut [u8]> {
601        let left: Option<&'v T> = self.option();
602        let right: Option<&'v T> = right.option();
603        match left {
604            Some(left) => {
605                match right {
606                    Some(right) => {
607                        // Compare
608                        left.diff(right, buf, ctx)
609                    }
610                    None => {
611                        // SetNone
612                        let code: u8 = DiffOpCode::SetNone.into();
613                        code.raw_encode(buf, &None)
614                    }
615                }
616            }
617            None => {
618                match right {
619                    Some(right) => {
620                        // Set+right
621                        let op = DiffOpRef::<T> {
622                            code: DiffOpCode::Set,
623                            value: right,
624                        };
625                        op.raw_encode(buf, &None)
626                    }
627                    None => {
628                        // None
629                        let code: u8 = DiffOpCode::None.into();
630                        code.raw_encode(buf, &None)
631                    }
632                }
633            }
634        }
635    }
636}
637
638impl<'de, T> RawPatch<'de> for Option<T>
639where
640    T: RawDecode<'de>,
641{
642    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
643        let (op, buf) = u8::raw_decode(buf)?;
644        let code = op.into();
645        match code {
646            DiffOpCode::None => {
647                // 没有改变
648                Ok((self, buf))
649            }
650            DiffOpCode::Set => {
651                // 设置为right
652                let (right, buf) = T::raw_decode(buf)?;
653                Ok((Some(right), buf))
654            }
655            DiffOpCode::SetNone => {
656                // 设置为None
657                Ok((None, buf))
658            }
659            _ => Err(BuckyError::from(format!(
660                "Opton<T> Type Can not patch by opcode:{:?}",
661                code
662            ))),
663        }
664    }
665}
666
667//--------------------------
668// Vec<T>
669//--------------------------
670pub struct ItemChangeRef<'v, T> {
671    pub code: DiffOpCode,
672    pub index: usize,
673    pub value: Option<&'v T>,
674}
675
676impl<'v, T> ItemChangeRef<'v, T> {
677    pub fn new(code: DiffOpCode, index: usize, value: Option<&'v T>) -> Self {
678        Self { code, index, value }
679    }
680}
681
682impl<'v, T> RawEncode for ItemChangeRef<'v, T>
683where
684    T: RawEncode,
685{
686    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
687        let mut size = u8::raw_bytes().unwrap() + u32::raw_bytes().unwrap();
688
689        if self.value.is_some() {
690            size = size + self.value.unwrap().raw_measure(purpose)?;
691        } else {
692            //
693        }
694
695        Ok(size)
696    }
697    fn raw_encode<'a>(
698        &self,
699        buf: &'a mut [u8],
700        purpose: &Option<RawEncodePurpose>,
701    ) -> BuckyResult<&'a mut [u8]> {
702        let size = self.raw_measure(purpose)?;
703        if buf.len() < size {
704            return Err(BuckyError::new(
705                BuckyErrorCode::OutOfLimit,
706                "[raw_encode] not enough buffer for ItemChangeRef",
707            ));
708        }
709
710        let code: u8 = (&self.code).into();
711        let buf = code.raw_encode(buf, purpose)?;
712        let buf = (self.index as u32).raw_encode(buf, purpose)?;
713
714        if self.value.is_some() {
715            let buf = self.value.unwrap().raw_encode(buf, purpose)?;
716            Ok(buf)
717        } else {
718            Ok(buf)
719        }
720    }
721}
722
723pub struct ItemChange<T> {
724    pub code: DiffOpCode,
725    pub index: usize,
726    pub value: Option<T>,
727}
728
729impl<T> RawEncode for ItemChange<T>
730where
731    T: RawEncode,
732{
733    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
734        let mut size = u8::raw_bytes().unwrap() + u32::raw_bytes().unwrap();
735
736        if self.value.is_some() {
737            size = size + self.value.as_ref().unwrap().raw_measure(purpose)?;
738        } else {
739            //
740        }
741
742        Ok(size)
743    }
744
745    fn raw_encode<'a>(
746        &self,
747        buf: &'a mut [u8],
748        purpose: &Option<RawEncodePurpose>,
749    ) -> BuckyResult<&'a mut [u8]> {
750        let size = self.raw_measure(purpose)?;
751        if buf.len() < size {
752            return Err(BuckyError::new(
753                BuckyErrorCode::OutOfLimit,
754                "[raw_encode] not enough buffer for ItemChange",
755            ));
756        }
757
758        let code: u8 = (&self.code).into();
759        let buf = code.raw_encode(buf, purpose)?;
760        let buf = (self.index as u32).raw_encode(buf, purpose)?;
761
762        if self.value.is_some() {
763            let buf = self.value.as_ref().unwrap().raw_encode(buf, purpose)?;
764            Ok(buf)
765        } else {
766            Ok(buf)
767        }
768    }
769}
770
771impl<'de, T> RawDecode<'de> for ItemChange<T>
772where
773    T: RawDecode<'de>,
774{
775    fn raw_decode(buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
776        if buf.len() < 1 {
777            let msg = format!(
778                "not enough buffer for encode ItemChange, min bytes={}, got={}",
779                1,
780                buf.len()
781            );
782            error!("{}", msg);
783
784            return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
785        }
786
787        let (code, buf) = u8::raw_decode(buf)?;
788        let (index, buf) = u32::raw_decode(buf)?;
789
790        let code: DiffOpCode = code.into();
791        match code {
792            DiffOpCode::Add => {
793                let (value, buf) = T::raw_decode(buf)?;
794                Ok((
795                    Self {
796                        code,
797                        index: index as usize,
798                        value: Some(value),
799                    },
800                    buf,
801                ))
802            }
803            _ => Ok((
804                Self {
805                    code,
806                    index: index as usize,
807                    value: None,
808                },
809                buf,
810            )),
811        }
812    }
813}
814
815pub struct VecDiffContext<'v, T> {
816    change_list: Vec<ItemChangeRef<'v, T>>,
817}
818
819impl<'v, T> Default for VecDiffContext<'v, T> {
820    fn default() -> Self {
821        Self {
822            change_list: Vec::new(),
823        }
824    }
825}
826
827impl<'v, T> VecDiffContext<'v, T> {
828    pub fn change(&mut self, range: ItemChangeRef<'v, T>) {
829        self.change_list.push(range);
830    }
831
832    pub fn change_list(&self) -> &Vec<ItemChangeRef<'v, T>> {
833        &self.change_list
834    }
835}
836
837impl<'v, T: RawDiff + PartialEq> RawDiffWithContext<'v, VecDiffContext<'v, T>> for Vec<T> {
838    fn diff_measure(&self, right: &'v Self, ctx: &mut VecDiffContext<'v, T>) -> BuckyResult<usize> {
839        // diff here
840
841        if self.len() == 0 && right.len() == 0 {
842            // 两边都是空,没有变化,None
843            Ok(u8::raw_bytes().unwrap())
844        } else if self.len() == 0 {
845            // 左边为空,右边非空,设置为右边 Set
846            Ok(u8::raw_bytes().unwrap() + right.raw_measure(&None)?)
847        } else if right.len() == 0 {
848            // 左边非空,右边为空,清空 SetNone
849            Ok(u8::raw_bytes().unwrap())
850        } else {
851            // 两边都非空
852
853            let mut right_start = 0;
854
855            // 比对
856            {
857                let mut i = 0;
858                let mut k = 0;
859
860                while i < self.len() {
861                    // 左边还有剩余,右边结束,左边剩余的全部移除
862                    if right_start == right.len() {
863                        println!("==> truncate at:{}", k);
864                        ctx.change(ItemChangeRef::<T>::new(DiffOpCode::TrimEnd, k, None));
865                        break;
866                    }
867
868                    // 从right_start开始扫描右边,查找和self[i]相等的元素
869                    // 如果找不到,则移除self[i]
870                    // 否则,添加right[right_start...j]
871                    let mut hint = None;
872                    for j in right_start..right.len() {
873                        if self[i] == right[j] {
874                            hint = Some(j)
875                        }
876                    }
877
878                    // 添加或移除
879                    match hint {
880                        Some(hint) => {
881                            // 反复插入元素,并更新下一个变动点k
882                            for j in right_start..hint {
883                                println!("==> add at:{}, hint:{}", k, hint);
884                                ctx.change(ItemChangeRef::<T>::new(
885                                    DiffOpCode::Add,
886                                    k,
887                                    Some(&right[j]),
888                                ));
889                                k = k + 1;
890                            }
891
892                            println!("==> keep at:{}", k);
893                            k = k + 1;
894
895                            // 到hint为止的right已经被处理
896                            right_start = hint + 1;
897                        }
898                        None => {
899                            println!("==> remove at:{}", k);
900                            // 在k处移除元素,k不动
901                            ctx.change(ItemChangeRef::<T>::new(DiffOpCode::Remove, k, None));
902                        }
903                    }
904
905                    i = i + 1;
906                }
907
908                // 右边还有剩余,左边结束,把右边剩余的全部添加
909                if right_start < right.len() {
910                    for j in right_start..right.len() {
911                        println!("==> add at:{}, right_start:{}", k, right_start);
912                        ctx.change(ItemChangeRef::<T>::new(DiffOpCode::Add, k, Some(&right[j])));
913                        k = k + 1;
914                    }
915                }
916            }
917
918            Ok(u8::raw_bytes().unwrap() + ctx.change_list().raw_measure(&None)?)
919        }
920    }
921
922    fn diff<'d>(
923        &self,
924        right: &Self,
925        buf: &'d mut [u8],
926        ctx: &mut VecDiffContext<'v, T>,
927    ) -> BuckyResult<&'d mut [u8]> {
928        let size = self.raw_measure(&None)?;
929        if buf.len() < size {
930            return Err(BuckyError::new(
931                BuckyErrorCode::OutOfLimit,
932                "[raw_diff] not enough buffer for VecDiffContext",
933            ));
934        }
935
936        if self.len() == 0 && right.len() == 0 {
937            // 两边都是空,没有变化,None
938            let code: u8 = DiffOpCode::None.into();
939            let buf = code.raw_encode(buf, &None)?;
940            Ok(buf)
941        } else if self.len() == 0 {
942            // 左边为空,右边非空,设置为右边 Set
943            let code: u8 = DiffOpCode::Set.into();
944            let buf = code.raw_encode(buf, &None)?;
945            let buf = right.raw_encode(buf, &None)?;
946            Ok(buf)
947        } else if right.len() == 0 {
948            // 左边非空,右边为空,清空 SetNone
949            let code: u8 = DiffOpCode::SetNone.into();
950            let buf = code.raw_encode(buf, &None)?;
951            Ok(buf)
952        } else {
953            // 两边都非空
954            let code: u8 = DiffOpCode::Add.into();
955            let buf = code.raw_encode(buf, &None)?;
956            let buf = ctx.change_list().raw_encode(buf, &None)?;
957            Ok(buf)
958        }
959    }
960}
961
962impl<'de, T> RawPatch<'de> for Vec<T>
963where
964    T: RawDecode<'de> + RawEncode,
965{
966    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
967        let (op, buf) = u8::raw_decode(buf)?;
968        let code = op.into();
969
970        let mut left = self;
971
972        match code {
973            DiffOpCode::None => {
974                // 没有改变
975                Ok((left, buf))
976            }
977            DiffOpCode::Set => {
978                // 设置为right
979                let (right, buf) = Vec::<T>::raw_decode(buf)?;
980                Ok((right, buf))
981            }
982            DiffOpCode::SetNone => {
983                // 设置为None
984                Ok((Vec::new(), buf))
985            }
986            DiffOpCode::Add => {
987                // 通过Add重建
988                let (change_list, buf) = Vec::<ItemChange<T>>::raw_decode(buf)?;
989
990                // 重建
991                println!("change_list:{}", change_list.len());
992
993                for change in change_list {
994                    match change.code {
995                        DiffOpCode::Add => {
996                            if change.value.is_none() {
997                                return Err(BuckyError::from("missing add value"));
998                            }
999
1000                            println!("insert value at {}", change.index);
1001                            left.insert(change.index, change.value.unwrap());
1002                        }
1003                        DiffOpCode::Remove => {
1004                            println!("remove value at {}", change.index);
1005                            left.remove(change.index);
1006                        }
1007                        DiffOpCode::TrimEnd => {
1008                            println!("truncate value at {}", change.index);
1009                            left.truncate(change.index);
1010                        }
1011                        _ => {
1012                            return Err(BuckyError::from("missing add value"));
1013                        }
1014                    }
1015                }
1016
1017                Ok((left, buf))
1018            }
1019            _ => Err(BuckyError::from(format!(
1020                "Vec<T> Type Can not patch by opcode:{:?}",
1021                code
1022            ))),
1023        }
1024    }
1025}
1026
1027//--------------------------
1028// SizedOwnedData<T>
1029//--------------------------
1030impl<'v, T: From<usize> + RawFixedBytes + RawEncode> RawDiffWithContext<'v, VecDiffContext<'v, u8>>
1031    for SizedOwnedData<T>
1032{
1033    fn diff_measure(
1034        &self,
1035        right: &'v Self,
1036        ctx: &mut VecDiffContext<'v, u8>,
1037    ) -> BuckyResult<usize> {
1038        // TODO: 优化
1039        let data = self.as_ref();
1040        let r = right.as_ref();
1041        data.diff_measure(r, ctx)
1042    }
1043
1044    fn diff<'d>(
1045        &self,
1046        right: &Self,
1047        buf: &'d mut [u8],
1048        ctx: &mut VecDiffContext<'v, u8>,
1049    ) -> BuckyResult<&'d mut [u8]> {
1050        // TODO: 优化
1051        self.as_ref().diff(right.as_ref(), buf, ctx)
1052    }
1053}
1054
1055impl<'de, T: From<usize> + RawDecode<'de> + Into<usize>> RawPatch<'de> for SizedOwnedData<T> {
1056    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
1057        // TODO: 优化
1058        let data: Vec<u8> = self.into();
1059        let (data, buf) = data.patch(buf)?;
1060        Ok((SizedOwnedData::<T>::from(data), buf))
1061    }
1062}
1063
1064//--------------------------
1065// HashValue
1066//--------------------------
1067
1068impl RawDiff for HashValue {
1069    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
1070        let data = self.as_ref();
1071        let r = right.as_ref();
1072        data.diff_measure(r)
1073    }
1074
1075    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
1076        self.as_ref().diff(right.as_ref(), buf)
1077    }
1078}
1079
1080impl<'de> RawPatch<'de> for HashValue {
1081    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
1082        let data: GenericArray<u8, U32> = self.into();
1083        let (data, buf) = data.patch(buf)?;
1084        Ok((HashValue::from(data), buf))
1085    }
1086}
1087
1088//--------------------------
1089// AesKey
1090//--------------------------
1091
1092impl RawDiff for AesKey {
1093    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
1094        let data = self.as_ref();
1095        let r = right.as_ref();
1096        data.diff_measure(r)
1097    }
1098
1099    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
1100        self.as_ref().diff(right.as_ref(), buf)
1101    }
1102}
1103
1104impl<'de> RawPatch<'de> for AesKey {
1105    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
1106        let data: GenericArray<u8, U48> = self.into();
1107        let (data, buf) = data.patch(buf)?;
1108        Ok((AesKey::from(data), buf))
1109    }
1110}
1111
1112//--------------------------
1113// Unit Test
1114//--------------------------
1115
1116#[cfg(test)]
1117mod test_diff {
1118    use crate::*;
1119    use super::*;
1120    use generic_array::typenum::{U32, U48};
1121    use generic_array::GenericArray;
1122    use crate::objects::raw_diff::RawDiff;
1123
1124    #[test]
1125    fn test_u8_diff_patch() {
1126        let no = 10u8;
1127        let other = 11u8;
1128
1129        let size = no.diff_measure(&other).unwrap();
1130        let mut buf = vec![0u8; size];
1131
1132        let old = no;
1133
1134        let _ = no.diff(&other, &mut buf).unwrap();
1135        let (new_no, _) = no.patch(&buf).unwrap();
1136
1137        println!("old_no:{}, new_no:{}", old, new_no);
1138
1139        assert!(new_no == other);
1140    }
1141
1142    #[test]
1143    fn test_string_diff() {
1144        let left = String::from("Hello");
1145        let right = String::from("HelloWorld");
1146
1147        let size = (&left).diff_measure(&right).unwrap();
1148        let mut buf = vec![0u8; size];
1149
1150        let _ = (&left).diff(&right, &mut buf).unwrap();
1151        let (left, _) = left.patch(&buf).unwrap();
1152
1153        assert_eq!(left, right);
1154    }
1155
1156    #[test]
1157    fn test_str_diff() {
1158        let left = "Hello";
1159        let right = "HelloWorld";
1160
1161        let size = left.diff_measure(&right).unwrap();
1162        let mut buf = vec![0u8; size];
1163
1164        println!("size:{}", size);
1165        let _ = left.diff(&right, &mut buf).unwrap();
1166        let (left, _) = left.to_string().patch(&buf).unwrap();
1167
1168        assert_eq!(left, right);
1169    }
1170
1171    #[test]
1172    fn test_generic_array_diff() {
1173        let left = GenericArray::<u8, U32>::default();
1174        let right = GenericArray::<u8, U32>::default();
1175
1176        let size = left.diff_measure(&right).unwrap();
1177        let mut buf = vec![0u8; size];
1178
1179        println!("size:{}", size);
1180        let _ = left.diff(&right, &mut buf).unwrap();
1181        let (left, _) = left.patch(&buf).unwrap();
1182
1183        assert_eq!(left, right);
1184
1185        // assert!(false)
1186    }
1187
1188    #[test]
1189    fn test_optoin_t_diff() {
1190        // some some
1191        {
1192            let left = Some(10u8);
1193            let right = Some(11u8);
1194
1195            let size = left.diff_measure(&right).unwrap();
1196            let mut buf = vec![0u8; size];
1197
1198            println!("size:{}", size);
1199
1200            let _ = left.diff(&right, &mut buf).unwrap();
1201            let (left, _) = left.patch(&buf).unwrap();
1202
1203            println!("left:{:?}, right:{:?}", left, right);
1204
1205            assert_eq!(left, right);
1206        }
1207
1208        {
1209            let left = Some("Hello World!".to_string());
1210            let right = Some("你好,世界".to_string());
1211
1212            let size = left.diff_measure(&right).unwrap();
1213            let mut buf = vec![0u8; size];
1214
1215            println!("size:{}", size);
1216
1217            let _ = left.diff(&right, &mut buf).unwrap();
1218            let (left, _) = left.patch(&buf).unwrap();
1219
1220            println!("left:{:?}, right:{:?}", left, right);
1221
1222            assert_eq!(left, right);
1223        }
1224
1225        // some none
1226        {
1227            let left = Some("Hello World".to_string());
1228            let right = None;
1229
1230            let size = left.diff_measure(&right).unwrap();
1231            let mut buf = vec![0u8; size];
1232
1233            println!("size:{}", size);
1234
1235            let _ = left.diff(&right, &mut buf).unwrap();
1236            let (left, _) = left.patch(&buf).unwrap();
1237
1238            println!("left:{:?}, right:{:?}", left, right);
1239
1240            assert_eq!(left, right);
1241        }
1242
1243        // none none
1244        {
1245            let left: Option<u128> = None;
1246            let right = None;
1247
1248            let size = left.diff_measure(&right).unwrap();
1249            let mut buf = vec![0u8; size];
1250
1251            println!("size:{}", size);
1252
1253            let _ = left.diff(&right, &mut buf).unwrap();
1254            let (left, _) = left.patch(&buf).unwrap();
1255
1256            println!("left:{:?}, right:{:?}", left, right);
1257
1258            assert_eq!(left, right);
1259        }
1260
1261        // none some
1262        {
1263            let left: Option<GenericArray<u8, U32>> = None;
1264            let right = Some(GenericArray::<u8, U32>::default());
1265
1266            let size = left.diff_measure(&right).unwrap();
1267            let mut buf = vec![0u8; size];
1268
1269            println!("size:{}", size);
1270
1271            let _ = left.diff(&right, &mut buf).unwrap();
1272            let (left, _) = left.patch(&buf).unwrap();
1273
1274            println!("left:{:?}, right:{:?}", left, right);
1275
1276            assert_eq!(left, right);
1277        }
1278
1279        // assert!(false)
1280    }
1281
1282    #[test]
1283    fn test_vec_diff() {
1284        println!("\n\n");
1285        // left.len() == right.len()
1286        {
1287            let left = vec![1u8, 2u8, 3u8];
1288            let right = vec![1u8, 4u8, 3u8];
1289
1290            println!("left before diff and patch:{:?}", left);
1291            println!("right before diff and patch:{:?}", right);
1292
1293            let mut ctx = VecDiffContext::default();
1294            let size = left.diff_measure(&right, &mut ctx).unwrap();
1295            let mut buf = vec![0u8; size];
1296            println!("size:{}", size);
1297
1298            let _ = left.diff(&right, &mut buf, &mut ctx).unwrap();
1299            let (left, _) = left.patch(&buf).unwrap();
1300
1301            println!("left after diff and patch:{:?}", left);
1302
1303            assert_eq!(left, right);
1304        }
1305
1306        println!("\n\n");
1307        // left.len() < right.len()
1308        {
1309            let left = vec![1u8, 2u8];
1310            let right = vec![1u8, 4u8, 3u8];
1311
1312            println!("left before diff and patch:{:?}", left);
1313            println!("right before diff and patch:{:?}", right);
1314
1315            let mut ctx = VecDiffContext::default();
1316            let size = left.diff_measure(&right, &mut ctx).unwrap();
1317            let mut buf = vec![0u8; size];
1318            println!("size:{}", size);
1319
1320            let _ = left.diff(&right, &mut buf, &mut ctx).unwrap();
1321            let (left, _) = left.patch(&buf).unwrap();
1322
1323            println!("left after diff and patch:{:?}", left);
1324
1325            // assert_eq!(left, right);
1326        }
1327
1328        println!("\n\n");
1329        // left.len() > right.len()
1330        {
1331            let left = vec![1u8, 2u8, 3u8, 5u8];
1332            let right = vec![1u8, 4u8, 3u8];
1333
1334            println!("left before diff and patch:{:?}", left);
1335            println!("right before diff and patch:{:?}", right);
1336
1337            let mut ctx = VecDiffContext::default();
1338            let size = left.diff_measure(&right, &mut ctx).unwrap();
1339            let mut buf = vec![0u8; size];
1340            println!("size:{}", size);
1341
1342            let _ = left.diff(&right, &mut buf, &mut ctx).unwrap();
1343            let (left, _) = left.patch(&buf).unwrap();
1344
1345            println!("left after diff and patch:{:?}", left);
1346
1347            assert_eq!(left, right);
1348        }
1349
1350        println!("\n\n");
1351
1352        // assert!(false)
1353    }
1354
1355    #[test]
1356    fn test_sizedowneddata_diff() {
1357        let left = SizedOwnedData::<SizeU32>::from(vec![1u8, 2u8, 3u8]);
1358        let right = SizedOwnedData::<SizeU32>::from(vec![1u8, 4u8, 3u8]);
1359
1360        println!("left before diff and patch:{:?}", left);
1361        println!("right before diff and patch:{:?}", right);
1362
1363        let mut ctx = VecDiffContext::default();
1364        let size = left.diff_measure(&right, &mut ctx).unwrap();
1365        let mut buf = vec![0u8; size];
1366        println!("size:{}", size);
1367
1368        let _ = left.diff(&right, &mut buf, &mut ctx).unwrap();
1369        let (left, _) = left.patch(&buf).unwrap();
1370
1371        println!("left after diff and patch:{:?}", left);
1372
1373        assert_eq!(left, right);
1374    }
1375
1376    #[test]
1377    fn test_hashvalue_diff() {
1378        let left = HashValue::from(GenericArray::<u8, U32>::default());
1379        let right = HashValue::from(GenericArray::<u8, U32>::default());
1380
1381        let size = left.diff_measure(&right).unwrap();
1382        let mut buf = vec![0u8; size];
1383
1384        println!("size:{}", size);
1385        let _ = left.diff(&right, &mut buf).unwrap();
1386        let (left, _) = left.patch(&buf).unwrap();
1387
1388        assert_eq!(left, right);
1389
1390        // assert!(false)
1391    }
1392
1393    #[test]
1394    fn test_aes_key_diff() {
1395        let left = AesKey::from(GenericArray::<u8, U48>::default());
1396        let right = AesKey::from(GenericArray::<u8, U48>::default());
1397
1398        let size = left.diff_measure(&right).unwrap();
1399        let mut buf = vec![0u8; size];
1400
1401        println!("size:{}", size);
1402        let _ = left.diff(&right, &mut buf).unwrap();
1403        let (left, _) = left.patch(&buf).unwrap();
1404
1405        assert_eq!(left, right);
1406
1407        // assert!(false)
1408    }
1409}