json0_rs/
operation.rs

1use std::{
2    fmt::{Debug, Display},
3    mem,
4    ops::{Deref, DerefMut},
5    rc::Rc,
6    vec,
7};
8
9use itertools::Itertools;
10use serde_json::{Map, Value};
11
12use crate::{
13    common::Validation,
14    error::JsonError,
15    error::Result,
16    path::{Path, PathElement},
17    sub_type::{SubType, SubTypeFunctions, SubTypeFunctionsHolder},
18};
19
20pub enum Operator {
21    Noop(),
22    SubType(SubType, Value, Box<dyn SubTypeFunctions>),
23    ListInsert(Value),
24    ListDelete(Value),
25    // Replace value from last value to first value in json array.
26    // First value is the new value.
27    // Last value is the old value.
28    ListReplace(Value, Value),
29    ListMove(usize),
30    ObjectInsert(Value),
31    ObjectDelete(Value),
32    // Replace value from last value to first value in json object.
33    // First value is the new value.
34    // Last value is the old value.
35    ObjectReplace(Value, Value),
36}
37
38impl Debug for Operator {
39    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40        match self {
41            Self::Noop() => f.debug_tuple("Noop").finish(),
42            Self::SubType(arg0, arg1, _) => {
43                f.debug_tuple("SubType2").field(arg0).field(arg1).finish()
44            }
45            Self::ListInsert(arg0) => f.debug_tuple("ListInsert").field(arg0).finish(),
46            Self::ListDelete(arg0) => f.debug_tuple("ListDelete").field(arg0).finish(),
47            Self::ListReplace(arg0, arg1) => f
48                .debug_tuple("ListReplace")
49                .field(arg0)
50                .field(arg1)
51                .finish(),
52            Self::ListMove(arg0) => f.debug_tuple("ListMove").field(arg0).finish(),
53            Self::ObjectInsert(arg0) => f.debug_tuple("ObjectInsert").field(arg0).finish(),
54            Self::ObjectDelete(arg0) => f.debug_tuple("ObjectDelete").field(arg0).finish(),
55            Self::ObjectReplace(arg0, arg1) => f
56                .debug_tuple("ObjectReplace")
57                .field(arg0)
58                .field(arg1)
59                .finish(),
60        }
61    }
62}
63
64impl PartialEq for Operator {
65    fn eq(&self, other: &Self) -> bool {
66        match (self, other) {
67            (Self::SubType(l0, l1, _), Self::SubType(r0, r1, _)) => l0 == r0 && l1 == r1,
68            (Self::ListInsert(l0), Self::ListInsert(r0)) => l0 == r0,
69            (Self::ListDelete(l0), Self::ListDelete(r0)) => l0 == r0,
70            (Self::ListReplace(l0, l1), Self::ListReplace(r0, r1)) => l0 == r0 && l1 == r1,
71            (Self::ListMove(l0), Self::ListMove(r0)) => l0 == r0,
72            (Self::ObjectInsert(l0), Self::ObjectInsert(r0)) => l0 == r0,
73            (Self::ObjectDelete(l0), Self::ObjectDelete(r0)) => l0 == r0,
74            (Self::ObjectReplace(l0, l1), Self::ObjectReplace(r0, r1)) => l0 == r0 && l1 == r1,
75            _ => core::mem::discriminant(self) == core::mem::discriminant(other),
76        }
77    }
78}
79
80impl Clone for Operator {
81    fn clone(&self) -> Self {
82        match self {
83            Self::Noop() => Self::Noop(),
84            Self::SubType(arg0, arg1, arg2) => {
85                Self::SubType(arg0.clone(), arg1.clone(), arg2.clone())
86            }
87            Self::ListInsert(arg0) => Self::ListInsert(arg0.clone()),
88            Self::ListDelete(arg0) => Self::ListDelete(arg0.clone()),
89            Self::ListReplace(arg0, arg1) => Self::ListReplace(arg0.clone(), arg1.clone()),
90            Self::ListMove(arg0) => Self::ListMove(*arg0),
91            Self::ObjectInsert(arg0) => Self::ObjectInsert(arg0.clone()),
92            Self::ObjectDelete(arg0) => Self::ObjectDelete(arg0.clone()),
93            Self::ObjectReplace(arg0, arg1) => Self::ObjectReplace(arg0.clone(), arg1.clone()),
94        }
95    }
96}
97
98impl Operator {
99    fn value_to_index(val: &Value) -> Result<usize> {
100        if let Some(i) = val.as_u64() {
101            return Ok(i as usize);
102        }
103        Err(JsonError::InvalidOperation(format!(
104            "{} can not parsed to index",
105            val
106        )))
107    }
108}
109
110impl Validation for Operator {
111    fn validates(&self) -> Result<()> {
112        if let Operator::SubType(_, operand, f) = self {
113            return f.validate_operand(operand);
114        }
115        Ok(())
116    }
117}
118
119impl Display for Operator {
120    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121        let s: String = match self {
122            Operator::Noop() => "".into(),
123            Operator::SubType(t, o, _) => format!("t: {}, o: {}", t, o),
124            Operator::ListInsert(i) => format!("li: {}", i),
125            Operator::ListDelete(d) => format!("ld: {}", d),
126            Operator::ListReplace(i, d) => format!("li: {}, ld: {}", i, d),
127            Operator::ListMove(m) => format!("lm: {}", m),
128            Operator::ObjectInsert(i) => format!("oi: {}", i),
129            Operator::ObjectDelete(d) => format!("od: {}", d),
130            Operator::ObjectReplace(i, d) => {
131                format!("oi: {}, od: {}", i, d)
132            }
133        };
134        f.write_str(&s)?;
135        Ok(())
136    }
137}
138
139#[derive(Clone, Debug, PartialEq)]
140pub struct OperationComponent {
141    pub path: Path,
142    pub operator: Operator,
143}
144
145impl OperationComponent {
146    pub fn new(path: Path, operator: Operator) -> Result<OperationComponent> {
147        let op = OperationComponent { path, operator };
148        op.validates()?;
149        Ok(op)
150    }
151
152    pub fn noop(&self) -> OperationComponent {
153        OperationComponent {
154            path: self.path.clone(),
155            operator: Operator::Noop(),
156        }
157    }
158
159    pub fn clone_not_noop(&self) -> Option<OperationComponent> {
160        if let Operator::Noop() = self.operator {
161            None
162        } else {
163            Some(self.clone())
164        }
165    }
166
167    pub fn not_noop(self) -> Option<OperationComponent> {
168        if let Operator::Noop() = self.operator {
169            None
170        } else {
171            Some(self)
172        }
173    }
174
175    pub fn invert(&self) -> Result<OperationComponent> {
176        self.validates()?;
177
178        let mut path = self.path.clone();
179        let operator = match &self.operator {
180            Operator::Noop() => Operator::Noop(),
181            Operator::SubType(_, o, f) => f.invert(&path, o)?,
182            Operator::ListInsert(v) => Operator::ListDelete(v.clone()),
183            Operator::ListDelete(v) => Operator::ListInsert(v.clone()),
184            Operator::ListReplace(new_v, old_v) => {
185                Operator::ListReplace(old_v.clone(), new_v.clone())
186            }
187            Operator::ListMove(new) => {
188                let old_p = path.replace(path.len() - 1, PathElement::Index(*new));
189                if let Some(PathElement::Index(i)) = old_p {
190                    Operator::ListMove(i)
191                } else {
192                    return Err(JsonError::BadPath);
193                }
194            }
195            Operator::ObjectInsert(v) => Operator::ObjectDelete(v.clone()),
196            Operator::ObjectDelete(v) => Operator::ObjectInsert(v.clone()),
197            Operator::ObjectReplace(new_v, old_v) => {
198                Operator::ObjectReplace(old_v.clone(), new_v.clone())
199            }
200        };
201        OperationComponent::new(path, operator)
202    }
203
204    /**
205     *
206     */
207    pub fn merge(&mut self, op: OperationComponent) -> Option<OperationComponent> {
208        if let Some(new_operator) = match &self.operator {
209            Operator::Noop() => Some(op.operator.clone()),
210            Operator::SubType(_, base_v, f) => f.merge(base_v, &op.operator),
211
212            Operator::ListInsert(v1) => match &op.operator {
213                Operator::ListDelete(v2) => {
214                    if v1.eq(v2) {
215                        Some(Operator::Noop())
216                    } else {
217                        None
218                    }
219                }
220                Operator::ListReplace(new_v, old_v) => {
221                    if old_v.eq(v1) {
222                        Some(Operator::ListInsert(new_v.clone()))
223                    } else {
224                        None
225                    }
226                }
227                _ => None,
228            },
229            Operator::ListReplace(new_v1, old_v1) => match &op.operator {
230                Operator::ListDelete(v2) => {
231                    if new_v1.eq(v2) {
232                        Some(Operator::ListDelete(old_v1.clone()))
233                    } else {
234                        None
235                    }
236                }
237                Operator::ListReplace(new_v2, old_v2) => {
238                    if new_v1.eq(old_v2) {
239                        Some(Operator::ListReplace(new_v2.clone(), old_v1.clone()))
240                    } else {
241                        None
242                    }
243                }
244                _ => None,
245            },
246            Operator::ObjectInsert(v1) => match &op.operator {
247                Operator::ObjectDelete(v2) => {
248                    if v1.eq(v2) {
249                        Some(Operator::Noop())
250                    } else {
251                        None
252                    }
253                }
254                Operator::ObjectReplace(new_v2, old_v2) => {
255                    if v1.eq(old_v2) {
256                        Some(Operator::ObjectInsert(new_v2.clone()))
257                    } else {
258                        None
259                    }
260                }
261                _ => None,
262            },
263            Operator::ObjectDelete(v1) => match &op.operator {
264                Operator::ObjectInsert(v2) => Some(Operator::ObjectReplace(v1.clone(), v2.clone())),
265                _ => None,
266            },
267            Operator::ObjectReplace(new_v1, old_v1) => match &op.operator {
268                Operator::ObjectDelete(v2) => {
269                    if new_v1.eq(v2) {
270                        Some(Operator::ObjectDelete(old_v1.clone()))
271                    } else {
272                        None
273                    }
274                }
275                Operator::ObjectReplace(new_v2, old_v2) => {
276                    if new_v1.eq(old_v2) {
277                        Some(Operator::ObjectReplace(new_v2.clone(), old_v1.clone()))
278                    } else {
279                        None
280                    }
281                }
282                _ => None,
283            },
284            _ => None,
285        } {
286            _ = mem::replace(&mut self.operator, new_operator);
287            return None;
288        }
289
290        Some(op)
291    }
292
293    pub fn operate_path_len(&self) -> usize {
294        match self.operator {
295            Operator::SubType(_, _, _) => self.path.clone().len(),
296            _ => {
297                let mut p = self.path.clone();
298                p.get_mut_elements().pop();
299                p.len()
300            }
301        }
302    }
303}
304
305impl Validation for OperationComponent {
306    fn validates(&self) -> Result<()> {
307        if self.path.is_empty() {
308            return Err(JsonError::InvalidOperation("Path is empty".into()));
309        }
310
311        self.operator.validates()
312    }
313}
314
315impl Validation for Vec<OperationComponent> {
316    fn validates(&self) -> Result<()> {
317        for op in self.iter() {
318            op.validates()?;
319        }
320        Ok(())
321    }
322}
323
324impl Display for OperationComponent {
325    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
326        f.write_fmt(format_args!(r#"{{"p": {}, {}}}"#, self.path, self.operator))?;
327        Ok(())
328    }
329}
330
331#[derive(Debug, Clone, PartialEq)]
332pub struct Operation {
333    operations: Vec<OperationComponent>,
334}
335
336impl Operation {
337    pub fn empty_operation() -> Operation {
338        Operation { operations: vec![] }
339    }
340
341    pub fn new(operations: Vec<OperationComponent>) -> Result<Operation> {
342        operations.validates()?;
343        Ok(Operation { operations })
344    }
345
346    pub fn append(&mut self, op: OperationComponent) -> Result<()> {
347        if let Operator::ListMove(m) = op.operator {
348            if op
349                .path
350                .get(op.path.len() - 1)
351                .unwrap()
352                .eq(&PathElement::Index(m))
353            {
354                return Ok(());
355            }
356        }
357
358        if self.is_empty() {
359            self.push(op);
360            return Ok(());
361        }
362
363        let last = self.last_mut().unwrap();
364        if last.path.eq(&op.path) {
365            if let Some(o) = last.merge(op) {
366                self.push(o);
367            } else {
368                if last.operator.eq(&Operator::Noop()) {
369                    self.pop();
370                }
371                return Ok(());
372            }
373        } else {
374            self.push(op);
375        }
376
377        Ok(())
378    }
379
380    pub fn compose(&mut self, other: Operation) -> Result<()> {
381        for op in other.into_iter() {
382            self.append(op)?;
383        }
384
385        Ok(())
386    }
387}
388
389impl Deref for Operation {
390    type Target = Vec<OperationComponent>;
391
392    fn deref(&self) -> &Self::Target {
393        &self.operations
394    }
395}
396
397impl DerefMut for Operation {
398    fn deref_mut(&mut self) -> &mut Self::Target {
399        &mut self.operations
400    }
401}
402
403impl IntoIterator for Operation {
404    type Item = OperationComponent;
405
406    type IntoIter = std::vec::IntoIter<Self::Item>;
407
408    fn into_iter(self) -> Self::IntoIter {
409        self.operations.into_iter()
410    }
411}
412
413impl Validation for Operation {
414    fn validates(&self) -> Result<()> {
415        self.operations.validates()
416    }
417}
418
419impl From<OperationComponent> for Operation {
420    fn from(input: OperationComponent) -> Self {
421        Operation {
422            operations: vec![input],
423        }
424    }
425}
426
427impl From<Vec<OperationComponent>> for Operation {
428    fn from(operations: Vec<OperationComponent>) -> Self {
429        Operation { operations }
430    }
431}
432
433impl Display for Operation {
434    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
435        f.write_str("[")?;
436        f.write_str(
437            self.operations
438                .iter()
439                .map(|op| op.to_string())
440                .join(",")
441                .as_str(),
442        )?;
443        f.write_str("]")?;
444        Ok(())
445    }
446}
447
448pub struct ListOperationBuilder {
449    path: Path,
450    insert: Option<Value>,
451    delete: Option<Value>,
452    move_to: Option<usize>,
453}
454
455impl ListOperationBuilder {
456    fn new(path: Path) -> ListOperationBuilder {
457        ListOperationBuilder {
458            path,
459            insert: None,
460            delete: None,
461            move_to: None,
462        }
463    }
464
465    pub fn insert(mut self, val: Value) -> Self {
466        self.insert = Some(val);
467        self
468    }
469
470    pub fn delete(mut self, val: Value) -> Self {
471        self.delete = Some(val);
472        self
473    }
474
475    pub fn replace(mut self, old: Value, new: Value) -> Self {
476        self.insert = Some(new);
477        self.delete = Some(old);
478        self
479    }
480
481    pub fn move_to(mut self, new_index: usize) -> Self {
482        self.move_to = Some(new_index);
483        self
484    }
485
486    pub fn build(self) -> Result<OperationComponent> {
487        if let Some(new_index) = self.move_to {
488            return OperationComponent::new(self.path, Operator::ListMove(new_index));
489        }
490
491        if let Some(del_val) = self.delete {
492            if let Some(ins_val) = self.insert {
493                return OperationComponent::new(self.path, Operator::ListReplace(ins_val, del_val));
494            }
495            return OperationComponent::new(self.path, Operator::ListDelete(del_val));
496        }
497
498        if let Some(ins_val) = self.insert {
499            return OperationComponent::new(self.path, Operator::ListInsert(ins_val));
500        }
501
502        OperationComponent::new(self.path, Operator::Noop())
503    }
504}
505
506pub struct ObjectOperationBuilder {
507    path: Path,
508    insert: Option<Value>,
509    delete: Option<Value>,
510}
511
512impl ObjectOperationBuilder {
513    fn new(path: Path) -> ObjectOperationBuilder {
514        ObjectOperationBuilder {
515            path,
516            insert: None,
517            delete: None,
518        }
519    }
520
521    pub fn insert(mut self, val: Value) -> Self {
522        self.insert = Some(val);
523        self
524    }
525
526    pub fn delete(mut self, val: Value) -> Self {
527        self.delete = Some(val);
528        self
529    }
530
531    pub fn replace(mut self, old: Value, new: Value) -> Self {
532        self.insert = Some(new);
533        self.delete = Some(old);
534        self
535    }
536
537    pub fn build(self) -> Result<OperationComponent> {
538        if let Some(del_val) = self.delete {
539            if let Some(ins_val) = self.insert {
540                return OperationComponent::new(
541                    self.path,
542                    Operator::ObjectReplace(ins_val, del_val),
543                );
544            }
545            return OperationComponent::new(self.path, Operator::ObjectDelete(del_val));
546        }
547
548        if let Some(ins_val) = self.insert {
549            return OperationComponent::new(self.path, Operator::ObjectInsert(ins_val));
550        }
551
552        OperationComponent::new(self.path, Operator::Noop())
553    }
554}
555
556pub struct NumberAddOperationBuilder {
557    path: Path,
558    number_i64: Option<i64>,
559    number_f64: Option<f64>,
560    sub_type_function: Box<dyn SubTypeFunctions>,
561}
562
563impl NumberAddOperationBuilder {
564    pub fn new(
565        path: Path,
566        sub_type_function: Box<dyn SubTypeFunctions>,
567    ) -> NumberAddOperationBuilder {
568        NumberAddOperationBuilder {
569            path,
570            number_i64: None,
571            number_f64: None,
572            sub_type_function,
573        }
574    }
575
576    pub fn add_int(mut self, num: i64) -> Self {
577        self.number_i64 = Some(num);
578        self
579    }
580
581    pub fn add_float(mut self, num: f64) -> Self {
582        self.number_f64 = Some(num);
583        self
584    }
585
586    pub fn build(self) -> Result<OperationComponent> {
587        // support insert/delete multipul numbers
588        if self.number_f64.is_some() && self.number_i64.is_some() {
589            return Err(JsonError::InvalidOperation(
590                "only one number can be add".into(),
591            ));
592        }
593
594        if let Some(v) = self.number_i64 {
595            let o = serde_json::to_value(v).unwrap();
596            OperationComponent::new(
597                self.path,
598                Operator::SubType(SubType::NumberAdd, o, self.sub_type_function),
599            )
600        } else if let Some(v) = self.number_f64 {
601            let o = serde_json::to_value(v).unwrap();
602            OperationComponent::new(
603                self.path,
604                Operator::SubType(SubType::NumberAdd, o, self.sub_type_function),
605            )
606        } else {
607            return Err(JsonError::InvalidOperation("need a number to add".into()));
608        }
609    }
610}
611
612pub struct TextOperationBuilder {
613    path: Path,
614    offset: usize,
615    insert_val: Option<String>,
616    delete_val: Option<String>,
617    sub_type_function: Box<dyn SubTypeFunctions>,
618}
619
620impl TextOperationBuilder {
621    pub fn new(path: Path, sub_type_function: Box<dyn SubTypeFunctions>) -> TextOperationBuilder {
622        TextOperationBuilder {
623            path,
624            offset: 0,
625            insert_val: None,
626            delete_val: None,
627            sub_type_function,
628        }
629    }
630
631    pub fn insert_string(mut self, offset: usize, insert: String) -> Self {
632        self.insert_val = Some(insert);
633        self.offset = offset;
634        self
635    }
636
637    pub fn insert_str(mut self, offset: usize, insert: &str) -> Self {
638        self.insert_val = Some(insert.into());
639        self.offset = offset;
640        self
641    }
642
643    pub fn delete_string(mut self, offset: usize, delete: String) -> Self {
644        self.delete_val = Some(delete);
645        self.offset = offset;
646        self
647    }
648
649    pub fn delete_str(mut self, offset: usize, delete: &str) -> Self {
650        self.delete_val = Some(delete.into());
651        self.offset = offset;
652        self
653    }
654
655    pub fn build(self) -> Result<OperationComponent> {
656        // support insert/delete multipul strings
657        if self.insert_val.is_none() && self.delete_val.is_none()
658            || (self.insert_val.is_some() && self.delete_val.is_some())
659        {
660            return Err(JsonError::InvalidOperation(
661                "text operation must either insert or delete".into(),
662            ));
663        }
664
665        let mut op_map = Map::new();
666        op_map.insert("p".into(), serde_json::to_value(self.offset).unwrap());
667        if let Some(v) = self.insert_val {
668            op_map.insert("i".into(), Value::String(v));
669        } else if let Some(v) = self.delete_val {
670            op_map.insert("d".into(), Value::String(v));
671        }
672
673        let o = Value::Object(op_map);
674        OperationComponent::new(
675            self.path,
676            Operator::SubType(SubType::Text, o, self.sub_type_function),
677        )
678    }
679}
680
681pub struct SubTypeOperationBuilder {
682    path: Path,
683    sub_type: SubType,
684    sub_type_operator: Option<Value>,
685    sub_type_function: Option<Box<dyn SubTypeFunctions>>,
686}
687
688impl SubTypeOperationBuilder {
689    fn new(
690        path: Path,
691        sub_type: SubType,
692        sub_type_function: Option<Box<dyn SubTypeFunctions>>,
693    ) -> SubTypeOperationBuilder {
694        SubTypeOperationBuilder {
695            path,
696            sub_type,
697            sub_type_operator: None,
698            sub_type_function,
699        }
700    }
701
702    pub fn sub_type_operand(mut self, val: Value) -> Self {
703        self.sub_type_operator = Some(val);
704        self
705    }
706
707    pub fn sub_type_functions(mut self, val: Box<dyn SubTypeFunctions>) -> Self {
708        self.sub_type_function = Some(val);
709        self
710    }
711
712    pub fn build(self) -> Result<OperationComponent> {
713        if let Some(o) = self.sub_type_operator {
714            if let Some(f) = self.sub_type_function {
715                OperationComponent::new(self.path, Operator::SubType(self.sub_type, o, f))
716            } else {
717                Err(JsonError::InvalidOperation(
718                    "sub type functions is required".into(),
719                ))
720            }
721        } else {
722            Err(JsonError::InvalidOperation(
723                "sub type operator is required".into(),
724            ))
725        }
726    }
727}
728
729pub struct OperationFactory {
730    sub_type_holder: Rc<SubTypeFunctionsHolder>,
731}
732
733impl OperationFactory {
734    pub fn new(sub_type_holder: Rc<SubTypeFunctionsHolder>) -> OperationFactory {
735        OperationFactory { sub_type_holder }
736    }
737
738    pub fn from_value(&self, value: Value) -> Result<Operation> {
739        let mut operations = vec![];
740        match value {
741            Value::Array(arr) => {
742                for v in arr {
743                    let op: OperationComponent = self.operation_component_from_value(v)?;
744                    operations.push(op);
745                }
746            }
747            _ => {
748                operations.push(self.operation_component_from_value(value)?);
749            }
750        }
751        Operation::new(operations)
752    }
753
754    pub fn list_operation_builder(&self, path: Path) -> ListOperationBuilder {
755        ListOperationBuilder::new(path)
756    }
757
758    pub fn object_operation_builder(&self, path: Path) -> ObjectOperationBuilder {
759        ObjectOperationBuilder::new(path)
760    }
761
762    pub fn number_add_operation_builder(&self, path: Path) -> NumberAddOperationBuilder {
763        let f = self
764            .sub_type_holder
765            .get(&SubType::NumberAdd)
766            .map(|f| f.value().clone())
767            .unwrap();
768        NumberAddOperationBuilder::new(path, f)
769    }
770
771    pub fn text_operation_builder(&self, path: Path) -> TextOperationBuilder {
772        let f = self
773            .sub_type_holder
774            .get(&SubType::Text)
775            .map(|f| f.value().clone())
776            .unwrap();
777        TextOperationBuilder::new(path, f)
778    }
779
780    pub fn sub_type_operation_builder(
781        &self,
782        path: Path,
783        sub_type_name: String,
784    ) -> SubTypeOperationBuilder {
785        let sub_type = SubType::Custome(sub_type_name);
786        let f = self
787            .sub_type_holder
788            .get(&sub_type)
789            .map(|f| f.value().clone());
790        SubTypeOperationBuilder::new(path, sub_type, f)
791    }
792
793    fn operation_component_from_value(&self, value: Value) -> Result<OperationComponent> {
794        let path_value = value.get("p");
795
796        if path_value.is_none() {
797            return Err(JsonError::InvalidOperation("Missing path".into()));
798        }
799
800        let paths = Path::try_from(path_value.unwrap())?;
801        let operator = self.operator_from_value(value)?;
802
803        Ok(OperationComponent {
804            path: paths,
805            operator,
806        })
807    }
808
809    fn operator_from_value(&self, value: Value) -> Result<Operator> {
810        match &value {
811            Value::Object(obj) => {
812                let operator = self.map_to_operator(obj)?;
813                Ok(operator)
814            }
815            _ => Err(JsonError::InvalidOperation(
816                "Operator can only be parsed from JSON Object".into(),
817            )),
818        }
819    }
820
821    fn map_to_operator(&self, obj: &Map<String, Value>) -> Result<Operator> {
822        if let Some(na) = obj.get("na") {
823            self.validate_operation_object_size(obj, 2)?;
824            return Ok(Operator::SubType(
825                SubType::NumberAdd,
826                na.clone(),
827                self.sub_type_holder
828                    .get(&SubType::NumberAdd)
829                    .map(|f| f.value().clone())
830                    .unwrap(),
831            ));
832        }
833
834        if let Some(t) = obj.get("t") {
835            self.validate_operation_object_size(obj, 3)?;
836            let sub_type = t.try_into()?;
837            let op = obj.get("o").cloned().unwrap_or(Value::Null);
838            let sub_op_func = self
839                .sub_type_holder
840                .get(&sub_type)
841                .map(|f| f.value().clone())
842                .ok_or(JsonError::InvalidOperation(format!(
843                    "no sub type functions for sub type: {}",
844                    sub_type
845                )))?;
846            return Ok(Operator::SubType(sub_type, op, sub_op_func));
847        }
848
849        if let Some(lm) = obj.get("lm") {
850            self.validate_operation_object_size(obj, 2)?;
851            let i = Operator::value_to_index(lm)?;
852            return Ok(Operator::ListMove(i));
853        }
854
855        if let Some(li) = obj.get("li") {
856            if let Some(ld) = obj.get("ld") {
857                self.validate_operation_object_size(obj, 3)?;
858                return Ok(Operator::ListReplace(li.clone(), ld.clone()));
859            }
860            self.validate_operation_object_size(obj, 2)?;
861            return Ok(Operator::ListInsert(li.clone()));
862        }
863
864        if let Some(ld) = obj.get("ld") {
865            self.validate_operation_object_size(obj, 2)?;
866            return Ok(Operator::ListDelete(ld.clone()));
867        }
868
869        if let Some(oi) = obj.get("oi") {
870            if let Some(od) = obj.get("od") {
871                self.validate_operation_object_size(obj, 3)?;
872                return Ok(Operator::ObjectReplace(oi.clone(), od.clone()));
873            }
874            self.validate_operation_object_size(obj, 2)?;
875            return Ok(Operator::ObjectInsert(oi.clone()));
876        }
877
878        if let Some(od) = obj.get("od") {
879            self.validate_operation_object_size(obj, 2)?;
880            return Ok(Operator::ObjectDelete(od.clone()));
881        }
882
883        self.validate_operation_object_size(obj, 1)?;
884        Ok(Operator::Noop())
885    }
886
887    fn validate_operation_object_size(
888        &self,
889        origin_operation: &Map<String, Value>,
890        expect_size: usize,
891    ) -> Result<()> {
892        if origin_operation.len() != expect_size {
893            return Err(JsonError::InvalidOperation(
894                "JSON object size bigger than operator required".into(),
895            ));
896        }
897        Ok(())
898    }
899}
900
901#[cfg(test)]
902mod tests {
903    use super::*;
904    use test_log::test;
905
906    #[test]
907    fn test_number_add_operator() {
908        let path: Path = r#"["p1","p2"]"#.try_into().unwrap();
909        let op_factory = OperationFactory::new(Rc::new(SubTypeFunctionsHolder::new()));
910        let op = op_factory
911            .number_add_operation_builder(path)
912            .add_int(100)
913            .build()
914            .unwrap();
915
916        let Operator::SubType(sub_type, op_value, _) = op.operator else {
917            panic!()
918        };
919        assert_eq!(SubType::NumberAdd, sub_type);
920        assert_eq!(serde_json::to_value(100).unwrap(), op_value);
921    }
922
923    #[test]
924    fn test_text_operator() {
925        let sub_type_operand: Value = serde_json::from_str(r#"{"p":1, "i":"hello"}"#).unwrap();
926        let path: Path = r#"["p1","p2"]"#.try_into().unwrap();
927        let op_factory = OperationFactory::new(Rc::new(SubTypeFunctionsHolder::new()));
928        let op = op_factory
929            .text_operation_builder(path)
930            .insert_str(1, "hello")
931            .build()
932            .unwrap();
933
934        let Operator::SubType(sub_type, op_value, _) = op.operator else {
935                panic!()
936            };
937        assert_eq!(SubType::Text, sub_type);
938        assert_eq!(sub_type_operand, op_value);
939    }
940}