cyfs_base/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 RawFixedBytes for str {
396    fn raw_min_bytes() -> Option<usize> {
397        u16::raw_bytes()
398    }
399}
400
401impl RawEncode for str {
402    fn raw_measure(&self, _purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
403        Ok(u16::raw_bytes().unwrap() + self.len())
404    }
405    fn raw_encode<'a>(
406        &self,
407        buf: &'a mut [u8],
408        purpose: &Option<RawEncodePurpose>,
409    ) -> BuckyResult<&'a mut [u8]> {
410        let size = self.raw_measure(purpose).unwrap();
411        if buf.len() < size {
412            return Err(BuckyError::new(
413                BuckyErrorCode::OutOfLimit,
414                "[raw_encode] not enough buffer for str",
415            ));
416        }
417
418        let buf = (self.len() as u16).raw_encode(buf, purpose)?;
419        if self.len() == 0 {
420            Ok(buf)
421        } else {
422            unsafe {
423                std::ptr::copy::<u8>(self.as_ptr() as *mut u8, buf.as_mut_ptr(), self.len());
424            }
425            println!("buf len {}, self len {}", buf.len(), self.len());
426            Ok(&mut buf[self.len()..])
427        }
428    }
429}
430
431impl RawDiff for str {
432    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
433        let code = if self == right {
434            DiffOpCode::None
435        } else {
436            DiffOpCode::Set
437        };
438        match code {
439            DiffOpCode::None => Ok(u8::raw_bytes().unwrap()),
440            DiffOpCode::Set => Ok(u8::raw_bytes().unwrap() + right.raw_measure(&None)?),
441            _ => Err(BuckyError::from(format!(
442                "Scalar Type Can not diff by opcode:{:?}",
443                code
444            ))),
445        }
446    }
447
448    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
449        let size = self.raw_measure(&None).unwrap();
450        if buf.len() < size {
451            return Err(BuckyError::new(
452                BuckyErrorCode::OutOfLimit,
453                "[raw_diff] not enough buffer for str diff",
454            ));
455        }
456
457        let code = if self == right {
458            DiffOpCode::None
459        } else {
460            DiffOpCode::Set
461        };
462
463        let ucode: u8 = (&code).into();
464        let buf = ucode.raw_encode(buf, &None)?;
465
466        match code {
467            DiffOpCode::None => Ok(buf),
468            DiffOpCode::Set => {
469                let buf = right.raw_encode(buf, &None)?;
470                Ok(buf)
471            }
472            _ => Err(BuckyError::from(format!(
473                "Scalar Type Can not diff by opcode:{:?}",
474                code
475            ))),
476        }
477    }
478}
479
480//--------------------------
481// GenericArray
482//--------------------------
483impl<T: RawEncode + PartialEq, U: ArrayLength<T>> RawDiff for GenericArray<T, U> {
484    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
485        let op = DiffOpRef::<Self> {
486            code: DiffOpCode::eq_or_set(self, right),
487            value: right,
488        };
489        op.raw_measure(&None)
490    }
491
492    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
493        let op = DiffOpRef::<Self> {
494            code: DiffOpCode::eq_or_set(self, right),
495            value: right,
496        };
497        op.raw_encode(buf, &None)
498    }
499}
500
501impl<'de, T: RawEncode + RawDecode<'de> + Default, U: ArrayLength<T>> RawPatch<'de>
502    for GenericArray<T, U>
503{
504    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
505        let (op, buf) = DiffOp::<Self>::raw_decode(buf)?;
506        match op.code {
507            DiffOpCode::None => {
508                println!("genneric array patch is none");
509                Ok((self, buf))
510            }
511            DiffOpCode::Set => Ok((op.value.unwrap(), buf)),
512            _ => Err(BuckyError::from(format!(
513                "Scalar Type Can not diff by opcode:{:?}",
514                op.code
515            ))),
516        }
517    }
518}
519
520//--------------------------
521// Option<T>
522//--------------------------
523impl<T: RawDiff> RawDiff for Option<T> {
524    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
525        match self {
526            Some(left) => {
527                match right {
528                    Some(right) => {
529                        // Compare
530                        left.diff_measure(right)
531                    }
532                    None => {
533                        // SetNone
534                        Ok(u8::raw_bytes().unwrap())
535                    }
536                }
537            }
538            None => {
539                match right {
540                    Some(right) => {
541                        // Set+right
542                        let op = DiffOpRef::<T> {
543                            code: DiffOpCode::Set,
544                            value: right,
545                        };
546                        op.raw_measure(&None)
547                    }
548                    None => {
549                        // None
550                        Ok(u8::raw_bytes().unwrap())
551                    }
552                }
553            }
554        }
555    }
556
557    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
558        match self {
559            Some(left) => {
560                match right {
561                    Some(right) => {
562                        // Compare
563                        left.diff(right, buf)
564                    }
565                    None => {
566                        // SetNone
567                        let code: u8 = DiffOpCode::SetNone.into();
568                        code.raw_encode(buf, &None)
569                    }
570                }
571            }
572            None => {
573                match right {
574                    Some(right) => {
575                        // Set+right
576                        let op = DiffOpRef::<T> {
577                            code: DiffOpCode::Set,
578                            value: right,
579                        };
580                        op.raw_encode(buf, &None)
581                    }
582                    None => {
583                        // None
584                        let code: u8 = DiffOpCode::None.into();
585                        code.raw_encode(buf, &None)
586                    }
587                }
588            }
589        }
590    }
591}
592
593impl<'v, U, T: RawDiffWithContext<'v, VecDiffContext<'v, U>>>
594    RawDiffWithContext<'v, VecDiffContext<'v, U>> for OptionRef<'v, T>
595{
596    fn diff_measure(&self, right: &'v Self, ctx: &mut VecDiffContext<'v, U>) -> BuckyResult<usize> {
597        let left: Option<&'v T> = self.option();
598        let right: Option<&'v T> = right.option();
599        match left {
600            Some(left) => {
601                match right {
602                    Some(right) => {
603                        // Compare
604                        left.diff_measure(right, ctx)
605                    }
606                    None => {
607                        // SetNone
608                        Ok(u8::raw_bytes().unwrap())
609                    }
610                }
611            }
612            None => {
613                match right {
614                    Some(right) => {
615                        // Set+right
616                        let op = DiffOpRef::<T> {
617                            code: DiffOpCode::Set,
618                            value: right,
619                        };
620                        op.raw_measure(&None)
621                    }
622                    None => {
623                        // None
624                        Ok(u8::raw_bytes().unwrap())
625                    }
626                }
627            }
628        }
629    }
630
631    fn diff<'d>(
632        &self,
633        right: &Self,
634        buf: &'d mut [u8],
635        ctx: &mut VecDiffContext<'v, U>,
636    ) -> BuckyResult<&'d mut [u8]> {
637        let left: Option<&'v T> = self.option();
638        let right: Option<&'v T> = right.option();
639        match left {
640            Some(left) => {
641                match right {
642                    Some(right) => {
643                        // Compare
644                        left.diff(right, buf, ctx)
645                    }
646                    None => {
647                        // SetNone
648                        let code: u8 = DiffOpCode::SetNone.into();
649                        code.raw_encode(buf, &None)
650                    }
651                }
652            }
653            None => {
654                match right {
655                    Some(right) => {
656                        // Set+right
657                        let op = DiffOpRef::<T> {
658                            code: DiffOpCode::Set,
659                            value: right,
660                        };
661                        op.raw_encode(buf, &None)
662                    }
663                    None => {
664                        // None
665                        let code: u8 = DiffOpCode::None.into();
666                        code.raw_encode(buf, &None)
667                    }
668                }
669            }
670        }
671    }
672}
673
674impl<'de, T> RawPatch<'de> for Option<T>
675where
676    T: RawDecode<'de>,
677{
678    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
679        let (op, buf) = u8::raw_decode(buf)?;
680        let code = op.into();
681        match code {
682            DiffOpCode::None => {
683                // 没有改变
684                Ok((self, buf))
685            }
686            DiffOpCode::Set => {
687                // 设置为right
688                let (right, buf) = T::raw_decode(buf)?;
689                Ok((Some(right), buf))
690            }
691            DiffOpCode::SetNone => {
692                // 设置为None
693                Ok((None, buf))
694            }
695            _ => Err(BuckyError::from(format!(
696                "Opton<T> Type Can not patch by opcode:{:?}",
697                code
698            ))),
699        }
700    }
701}
702
703//--------------------------
704// Vec<T>
705//--------------------------
706pub struct ItemChangeRef<'v, T> {
707    pub code: DiffOpCode,
708    pub index: usize,
709    pub value: Option<&'v T>,
710}
711
712impl<'v, T> ItemChangeRef<'v, T> {
713    pub fn new(code: DiffOpCode, index: usize, value: Option<&'v T>) -> Self {
714        Self { code, index, value }
715    }
716}
717
718impl<'v, T> RawEncode for ItemChangeRef<'v, T>
719where
720    T: RawEncode,
721{
722    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
723        let mut size = u8::raw_bytes().unwrap() + u32::raw_bytes().unwrap();
724
725        if self.value.is_some() {
726            size = size + self.value.unwrap().raw_measure(purpose)?;
727        } else {
728            //
729        }
730
731        Ok(size)
732    }
733    fn raw_encode<'a>(
734        &self,
735        buf: &'a mut [u8],
736        purpose: &Option<RawEncodePurpose>,
737    ) -> BuckyResult<&'a mut [u8]> {
738        let size = self.raw_measure(purpose)?;
739        if buf.len() < size {
740            return Err(BuckyError::new(
741                BuckyErrorCode::OutOfLimit,
742                "[raw_encode] not enough buffer for ItemChangeRef",
743            ));
744        }
745
746        let code: u8 = (&self.code).into();
747        let buf = code.raw_encode(buf, purpose)?;
748        let buf = (self.index as u32).raw_encode(buf, purpose)?;
749
750        if self.value.is_some() {
751            let buf = self.value.unwrap().raw_encode(buf, purpose)?;
752            Ok(buf)
753        } else {
754            Ok(buf)
755        }
756    }
757}
758
759pub struct ItemChange<T> {
760    pub code: DiffOpCode,
761    pub index: usize,
762    pub value: Option<T>,
763}
764
765impl<T> RawEncode for ItemChange<T>
766where
767    T: RawEncode,
768{
769    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
770        let mut size = u8::raw_bytes().unwrap() + u32::raw_bytes().unwrap();
771
772        if self.value.is_some() {
773            size = size + self.value.as_ref().unwrap().raw_measure(purpose)?;
774        } else {
775            //
776        }
777
778        Ok(size)
779    }
780
781    fn raw_encode<'a>(
782        &self,
783        buf: &'a mut [u8],
784        purpose: &Option<RawEncodePurpose>,
785    ) -> BuckyResult<&'a mut [u8]> {
786        let size = self.raw_measure(purpose)?;
787        if buf.len() < size {
788            return Err(BuckyError::new(
789                BuckyErrorCode::OutOfLimit,
790                "[raw_encode] not enough buffer for ItemChange",
791            ));
792        }
793
794        let code: u8 = (&self.code).into();
795        let buf = code.raw_encode(buf, purpose)?;
796        let buf = (self.index as u32).raw_encode(buf, purpose)?;
797
798        if self.value.is_some() {
799            let buf = self.value.as_ref().unwrap().raw_encode(buf, purpose)?;
800            Ok(buf)
801        } else {
802            Ok(buf)
803        }
804    }
805}
806
807impl<'de, T> RawDecode<'de> for ItemChange<T>
808where
809    T: RawDecode<'de>,
810{
811    fn raw_decode(buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
812        if buf.len() < 1 {
813            let msg = format!(
814                "not enough buffer for encode ItemChange, min bytes={}, got={}",
815                1,
816                buf.len()
817            );
818            error!("{}", msg);
819
820            return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
821        }
822
823        let (code, buf) = u8::raw_decode(buf)?;
824        let (index, buf) = u32::raw_decode(buf)?;
825
826        let code: DiffOpCode = code.into();
827        match code {
828            DiffOpCode::Add => {
829                let (value, buf) = T::raw_decode(buf)?;
830                Ok((
831                    Self {
832                        code,
833                        index: index as usize,
834                        value: Some(value),
835                    },
836                    buf,
837                ))
838            }
839            _ => Ok((
840                Self {
841                    code,
842                    index: index as usize,
843                    value: None,
844                },
845                buf,
846            )),
847        }
848    }
849}
850
851pub struct VecDiffContext<'v, T> {
852    change_list: Vec<ItemChangeRef<'v, T>>,
853}
854
855impl<'v, T> Default for VecDiffContext<'v, T> {
856    fn default() -> Self {
857        Self {
858            change_list: Vec::new(),
859        }
860    }
861}
862
863impl<'v, T> VecDiffContext<'v, T> {
864    pub fn change(&mut self, range: ItemChangeRef<'v, T>) {
865        self.change_list.push(range);
866    }
867
868    pub fn change_list(&self) -> &Vec<ItemChangeRef<'v, T>> {
869        &self.change_list
870    }
871}
872
873impl<'v, T: RawDiff + PartialEq> RawDiffWithContext<'v, VecDiffContext<'v, T>> for Vec<T> {
874    fn diff_measure(&self, right: &'v Self, ctx: &mut VecDiffContext<'v, T>) -> BuckyResult<usize> {
875        // diff here
876
877        if self.len() == 0 && right.len() == 0 {
878            // 两边都是空,没有变化,None
879            Ok(u8::raw_bytes().unwrap())
880        } else if self.len() == 0 {
881            // 左边为空,右边非空,设置为右边 Set
882            Ok(u8::raw_bytes().unwrap() + right.raw_measure(&None)?)
883        } else if right.len() == 0 {
884            // 左边非空,右边为空,清空 SetNone
885            Ok(u8::raw_bytes().unwrap())
886        } else {
887            // 两边都非空
888
889            let mut right_start = 0;
890
891            // 比对
892            {
893                let mut i = 0;
894                let mut k = 0;
895
896                while i < self.len() {
897                    // 左边还有剩余,右边结束,左边剩余的全部移除
898                    if right_start == right.len() {
899                        println!("==> truncate at:{}", k);
900                        ctx.change(ItemChangeRef::<T>::new(DiffOpCode::TrimEnd, k, None));
901                        break;
902                    }
903
904                    // 从right_start开始扫描右边,查找和self[i]相等的元素
905                    // 如果找不到,则移除self[i]
906                    // 否则,添加right[right_start...j]
907                    let mut hint = None;
908                    for j in right_start..right.len() {
909                        if self[i] == right[j] {
910                            hint = Some(j)
911                        }
912                    }
913
914                    // 添加或移除
915                    match hint {
916                        Some(hint) => {
917                            // 反复插入元素,并更新下一个变动点k
918                            for j in right_start..hint {
919                                println!("==> add at:{}, hint:{}", k, hint);
920                                ctx.change(ItemChangeRef::<T>::new(
921                                    DiffOpCode::Add,
922                                    k,
923                                    Some(&right[j]),
924                                ));
925                                k = k + 1;
926                            }
927
928                            println!("==> keep at:{}", k);
929                            k = k + 1;
930
931                            // 到hint为止的right已经被处理
932                            right_start = hint + 1;
933                        }
934                        None => {
935                            println!("==> remove at:{}", k);
936                            // 在k处移除元素,k不动
937                            ctx.change(ItemChangeRef::<T>::new(DiffOpCode::Remove, k, None));
938                        }
939                    }
940
941                    i = i + 1;
942                }
943
944                // 右边还有剩余,左边结束,把右边剩余的全部添加
945                if right_start < right.len() {
946                    for j in right_start..right.len() {
947                        println!("==> add at:{}, right_start:{}", k, right_start);
948                        ctx.change(ItemChangeRef::<T>::new(DiffOpCode::Add, k, Some(&right[j])));
949                        k = k + 1;
950                    }
951                }
952            }
953
954            Ok(u8::raw_bytes().unwrap() + ctx.change_list().raw_measure(&None)?)
955        }
956    }
957
958    fn diff<'d>(
959        &self,
960        right: &Self,
961        buf: &'d mut [u8],
962        ctx: &mut VecDiffContext<'v, T>,
963    ) -> BuckyResult<&'d mut [u8]> {
964        let size = self.raw_measure(&None)?;
965        if buf.len() < size {
966            return Err(BuckyError::new(
967                BuckyErrorCode::OutOfLimit,
968                "[raw_diff] not enough buffer for VecDiffContext",
969            ));
970        }
971
972        if self.len() == 0 && right.len() == 0 {
973            // 两边都是空,没有变化,None
974            let code: u8 = DiffOpCode::None.into();
975            let buf = code.raw_encode(buf, &None)?;
976            Ok(buf)
977        } else if self.len() == 0 {
978            // 左边为空,右边非空,设置为右边 Set
979            let code: u8 = DiffOpCode::Set.into();
980            let buf = code.raw_encode(buf, &None)?;
981            let buf = right.raw_encode(buf, &None)?;
982            Ok(buf)
983        } else if right.len() == 0 {
984            // 左边非空,右边为空,清空 SetNone
985            let code: u8 = DiffOpCode::SetNone.into();
986            let buf = code.raw_encode(buf, &None)?;
987            Ok(buf)
988        } else {
989            // 两边都非空
990            let code: u8 = DiffOpCode::Add.into();
991            let buf = code.raw_encode(buf, &None)?;
992            let buf = ctx.change_list().raw_encode(buf, &None)?;
993            Ok(buf)
994        }
995    }
996}
997
998impl<'de, T> RawPatch<'de> for Vec<T>
999where
1000    T: RawDecode<'de> + RawEncode,
1001{
1002    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
1003        let (op, buf) = u8::raw_decode(buf)?;
1004        let code = op.into();
1005
1006        let mut left = self;
1007
1008        match code {
1009            DiffOpCode::None => {
1010                // 没有改变
1011                Ok((left, buf))
1012            }
1013            DiffOpCode::Set => {
1014                // 设置为right
1015                let (right, buf) = Vec::<T>::raw_decode(buf)?;
1016                Ok((right, buf))
1017            }
1018            DiffOpCode::SetNone => {
1019                // 设置为None
1020                Ok((Vec::new(), buf))
1021            }
1022            DiffOpCode::Add => {
1023                // 通过Add重建
1024                let (change_list, buf) = Vec::<ItemChange<T>>::raw_decode(buf)?;
1025
1026                // 重建
1027                println!("change_list:{}", change_list.len());
1028
1029                for change in change_list {
1030                    match change.code {
1031                        DiffOpCode::Add => {
1032                            if change.value.is_none() {
1033                                return Err(BuckyError::from("missing add value"));
1034                            }
1035
1036                            println!("insert value at {}", change.index);
1037                            left.insert(change.index, change.value.unwrap());
1038                        }
1039                        DiffOpCode::Remove => {
1040                            println!("remove value at {}", change.index);
1041                            left.remove(change.index);
1042                        }
1043                        DiffOpCode::TrimEnd => {
1044                            println!("truncate value at {}", change.index);
1045                            left.truncate(change.index);
1046                        }
1047                        _ => {
1048                            return Err(BuckyError::from("missing add value"));
1049                        }
1050                    }
1051                }
1052
1053                Ok((left, buf))
1054            }
1055            _ => Err(BuckyError::from(format!(
1056                "Vec<T> Type Can not patch by opcode:{:?}",
1057                code
1058            ))),
1059        }
1060    }
1061}
1062
1063//--------------------------
1064// SizedOwnedData<T>
1065//--------------------------
1066impl<'v, T: From<usize> + RawFixedBytes + RawEncode> RawDiffWithContext<'v, VecDiffContext<'v, u8>>
1067    for SizedOwnedData<T>
1068{
1069    fn diff_measure(
1070        &self,
1071        right: &'v Self,
1072        ctx: &mut VecDiffContext<'v, u8>,
1073    ) -> BuckyResult<usize> {
1074        // TODO: 优化
1075        let data = self.as_ref();
1076        let r = right.as_ref();
1077        data.diff_measure(r, ctx)
1078    }
1079
1080    fn diff<'d>(
1081        &self,
1082        right: &Self,
1083        buf: &'d mut [u8],
1084        ctx: &mut VecDiffContext<'v, u8>,
1085    ) -> BuckyResult<&'d mut [u8]> {
1086        // TODO: 优化
1087        self.as_ref().diff(right.as_ref(), buf, ctx)
1088    }
1089}
1090
1091impl<'de, T: From<usize> + RawDecode<'de> + Into<usize>> RawPatch<'de> for SizedOwnedData<T> {
1092    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
1093        // TODO: 优化
1094        let data: Vec<u8> = self.into();
1095        let (data, buf) = data.patch(buf)?;
1096        Ok((SizedOwnedData::<T>::from(data), buf))
1097    }
1098}
1099
1100//--------------------------
1101// HashValue
1102//--------------------------
1103
1104impl RawDiff for HashValue {
1105    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
1106        let data = self.as_ref();
1107        let r = right.as_ref();
1108        data.diff_measure(r)
1109    }
1110
1111    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
1112        self.as_ref().diff(right.as_ref(), buf)
1113    }
1114}
1115
1116impl<'de> RawPatch<'de> for HashValue {
1117    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
1118        let data: GenericArray<u8, U32> = self.into();
1119        let (data, buf) = data.patch(buf)?;
1120        Ok((HashValue::from(data), buf))
1121    }
1122}
1123
1124//--------------------------
1125// AesKey
1126//--------------------------
1127
1128impl RawDiff for AesKey {
1129    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
1130        let data = self.as_ref();
1131        let r = right.as_ref();
1132        data.diff_measure(r)
1133    }
1134
1135    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
1136        self.as_ref().diff(right.as_ref(), buf)
1137    }
1138}
1139
1140impl<'de> RawPatch<'de> for AesKey {
1141    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
1142        let data: GenericArray<u8, U48> = self.into();
1143        let (data, buf) = data.patch(buf)?;
1144        Ok((AesKey::from(data), buf))
1145    }
1146}
1147
1148//--------------------------
1149// Unit Test
1150//--------------------------
1151
1152#[cfg(test)]
1153mod test_diff {
1154    use crate::codec::{SizeU32, SizedOwnedData};
1155    use crate::crypto::{AesKey, HashValue};
1156    use super::*;
1157    use generic_array::typenum::{U32, U48};
1158    use generic_array::GenericArray;
1159    use crate::objects::raw_diff::RawDiff;
1160
1161    #[test]
1162    fn test_u8_diff_patch() {
1163        let no = 10u8;
1164        let other = 11u8;
1165
1166        let size = no.diff_measure(&other).unwrap();
1167        let mut buf = vec![0u8; size];
1168
1169        let old = no;
1170
1171        let _ = no.diff(&other, &mut buf).unwrap();
1172        let (new_no, _) = no.patch(&buf).unwrap();
1173
1174        println!("old_no:{}, new_no:{}", old, new_no);
1175
1176        assert!(new_no == other);
1177    }
1178
1179    #[test]
1180    fn test_string_diff() {
1181        let left = String::from("Hello");
1182        let right = String::from("HelloWorld");
1183
1184        let size = (&left).diff_measure(&right).unwrap();
1185        let mut buf = vec![0u8; size];
1186
1187        let _ = (&left).diff(&right, &mut buf).unwrap();
1188        let (left, _) = left.patch(&buf).unwrap();
1189
1190        assert_eq!(left, right);
1191    }
1192
1193    #[test]
1194    fn test_str_diff() {
1195        let left = "Hello";
1196        let right = "HelloWorld";
1197
1198        let size = left.diff_measure(&right).unwrap();
1199        let mut buf = vec![0u8; size];
1200
1201        println!("size:{}", size);
1202        let _ = left.diff(&right, &mut buf).unwrap();
1203        let (left, _) = left.to_string().patch(&buf).unwrap();
1204
1205        assert_eq!(left, right);
1206    }
1207
1208    #[test]
1209    fn test_generic_array_diff() {
1210        let left = GenericArray::<u8, U32>::default();
1211        let right = GenericArray::<u8, U32>::default();
1212
1213        let size = left.diff_measure(&right).unwrap();
1214        let mut buf = vec![0u8; size];
1215
1216        println!("size:{}", size);
1217        let _ = left.diff(&right, &mut buf).unwrap();
1218        let (left, _) = left.patch(&buf).unwrap();
1219
1220        assert_eq!(left, right);
1221
1222        // assert!(false)
1223    }
1224
1225    #[test]
1226    fn test_optoin_t_diff() {
1227        // some some
1228        {
1229            let left = Some(10u8);
1230            let right = Some(11u8);
1231
1232            let size = left.diff_measure(&right).unwrap();
1233            let mut buf = vec![0u8; size];
1234
1235            println!("size:{}", size);
1236
1237            let _ = left.diff(&right, &mut buf).unwrap();
1238            let (left, _) = left.patch(&buf).unwrap();
1239
1240            println!("left:{:?}, right:{:?}", left, right);
1241
1242            assert_eq!(left, right);
1243        }
1244
1245        {
1246            let left = Some("Hello World!".to_string());
1247            let right = Some("你好,世界".to_string());
1248
1249            let size = left.diff_measure(&right).unwrap();
1250            let mut buf = vec![0u8; size];
1251
1252            println!("size:{}", size);
1253
1254            let _ = left.diff(&right, &mut buf).unwrap();
1255            let (left, _) = left.patch(&buf).unwrap();
1256
1257            println!("left:{:?}, right:{:?}", left, right);
1258
1259            assert_eq!(left, right);
1260        }
1261
1262        // some none
1263        {
1264            let left = Some("Hello World".to_string());
1265            let right = None;
1266
1267            let size = left.diff_measure(&right).unwrap();
1268            let mut buf = vec![0u8; size];
1269
1270            println!("size:{}", size);
1271
1272            let _ = left.diff(&right, &mut buf).unwrap();
1273            let (left, _) = left.patch(&buf).unwrap();
1274
1275            println!("left:{:?}, right:{:?}", left, right);
1276
1277            assert_eq!(left, right);
1278        }
1279
1280        // none none
1281        {
1282            let left: Option<u128> = None;
1283            let right = None;
1284
1285            let size = left.diff_measure(&right).unwrap();
1286            let mut buf = vec![0u8; size];
1287
1288            println!("size:{}", size);
1289
1290            let _ = left.diff(&right, &mut buf).unwrap();
1291            let (left, _) = left.patch(&buf).unwrap();
1292
1293            println!("left:{:?}, right:{:?}", left, right);
1294
1295            assert_eq!(left, right);
1296        }
1297
1298        // none some
1299        {
1300            let left: Option<GenericArray<u8, U32>> = None;
1301            let right = Some(GenericArray::<u8, U32>::default());
1302
1303            let size = left.diff_measure(&right).unwrap();
1304            let mut buf = vec![0u8; size];
1305
1306            println!("size:{}", size);
1307
1308            let _ = left.diff(&right, &mut buf).unwrap();
1309            let (left, _) = left.patch(&buf).unwrap();
1310
1311            println!("left:{:?}, right:{:?}", left, right);
1312
1313            assert_eq!(left, right);
1314        }
1315
1316        // assert!(false)
1317    }
1318
1319    #[test]
1320    fn test_vec_diff() {
1321        println!("\n\n");
1322        // left.len() == right.len()
1323        {
1324            let left = vec![1u8, 2u8, 3u8];
1325            let right = vec![1u8, 4u8, 3u8];
1326
1327            println!("left before diff and patch:{:?}", left);
1328            println!("right before diff and patch:{:?}", right);
1329
1330            let mut ctx = VecDiffContext::default();
1331            let size = left.diff_measure(&right, &mut ctx).unwrap();
1332            let mut buf = vec![0u8; size];
1333            println!("size:{}", size);
1334
1335            let _ = left.diff(&right, &mut buf, &mut ctx).unwrap();
1336            let (left, _) = left.patch(&buf).unwrap();
1337
1338            println!("left after diff and patch:{:?}", left);
1339
1340            assert_eq!(left, right);
1341        }
1342
1343        println!("\n\n");
1344        // left.len() < right.len()
1345        {
1346            let left = vec![1u8, 2u8];
1347            let right = vec![1u8, 4u8, 3u8];
1348
1349            println!("left before diff and patch:{:?}", left);
1350            println!("right before diff and patch:{:?}", right);
1351
1352            let mut ctx = VecDiffContext::default();
1353            let size = left.diff_measure(&right, &mut ctx).unwrap();
1354            let mut buf = vec![0u8; size];
1355            println!("size:{}", size);
1356
1357            let _ = left.diff(&right, &mut buf, &mut ctx).unwrap();
1358            let (left, _) = left.patch(&buf).unwrap();
1359
1360            println!("left after diff and patch:{:?}", left);
1361
1362            // assert_eq!(left, right);
1363        }
1364
1365        println!("\n\n");
1366        // left.len() > right.len()
1367        {
1368            let left = vec![1u8, 2u8, 3u8, 5u8];
1369            let right = vec![1u8, 4u8, 3u8];
1370
1371            println!("left before diff and patch:{:?}", left);
1372            println!("right before diff and patch:{:?}", right);
1373
1374            let mut ctx = VecDiffContext::default();
1375            let size = left.diff_measure(&right, &mut ctx).unwrap();
1376            let mut buf = vec![0u8; size];
1377            println!("size:{}", size);
1378
1379            let _ = left.diff(&right, &mut buf, &mut ctx).unwrap();
1380            let (left, _) = left.patch(&buf).unwrap();
1381
1382            println!("left after diff and patch:{:?}", left);
1383
1384            assert_eq!(left, right);
1385        }
1386
1387        println!("\n\n");
1388
1389        // assert!(false)
1390    }
1391
1392    #[test]
1393    fn test_sizedowneddata_diff() {
1394        let left = SizedOwnedData::<SizeU32>::from(vec![1u8, 2u8, 3u8]);
1395        let right = SizedOwnedData::<SizeU32>::from(vec![1u8, 4u8, 3u8]);
1396
1397        println!("left before diff and patch:{:?}", left);
1398        println!("right before diff and patch:{:?}", right);
1399
1400        let mut ctx = VecDiffContext::default();
1401        let size = left.diff_measure(&right, &mut ctx).unwrap();
1402        let mut buf = vec![0u8; size];
1403        println!("size:{}", size);
1404
1405        let _ = left.diff(&right, &mut buf, &mut ctx).unwrap();
1406        let (left, _) = left.patch(&buf).unwrap();
1407
1408        println!("left after diff and patch:{:?}", left);
1409
1410        assert_eq!(left, right);
1411    }
1412
1413    #[test]
1414    fn test_hashvalue_diff() {
1415        let left = HashValue::from(GenericArray::<u8, U32>::default());
1416        let right = HashValue::from(GenericArray::<u8, U32>::default());
1417
1418        let size = left.diff_measure(&right).unwrap();
1419        let mut buf = vec![0u8; size];
1420
1421        println!("size:{}", size);
1422        let _ = left.diff(&right, &mut buf).unwrap();
1423        let (left, _) = left.patch(&buf).unwrap();
1424
1425        assert_eq!(left, right);
1426
1427        // assert!(false)
1428    }
1429
1430    #[test]
1431    fn test_aes_key_diff() {
1432        let left = AesKey::from(GenericArray::<u8, U48>::default());
1433        let right = AesKey::from(GenericArray::<u8, U48>::default());
1434
1435        let size = left.diff_measure(&right).unwrap();
1436        let mut buf = vec![0u8; size];
1437
1438        println!("size:{}", size);
1439        let _ = left.diff(&right, &mut buf).unwrap();
1440        let (left, _) = left.patch(&buf).unwrap();
1441
1442        assert_eq!(left, right);
1443
1444        // assert!(false)
1445    }
1446}