tarantool_rs/client/dmo/
operation.rs1use std::io::Write;
2
3use rmpv::ValueRef;
4
5use crate::{errors::EncodingError, Tuple, TupleElement};
6
7#[derive(Debug)]
11pub struct DmoOperationFieldKey<'a>(ValueRef<'a>);
12
13impl<'a> From<&'a str> for DmoOperationFieldKey<'a> {
14 fn from(value: &'a str) -> Self {
15 Self(value.into())
16 }
17}
18
19impl<'a> From<u32> for DmoOperationFieldKey<'a> {
20 fn from(value: u32) -> Self {
21 Self(value.into())
22 }
23}
24
25impl<'a> From<i32> for DmoOperationFieldKey<'a> {
26 fn from(value: i32) -> Self {
27 Self(value.into())
28 }
29}
30
31#[derive(Debug)]
34pub struct DmoOperation<'a> {
35 operation: &'static str,
38 field_name: ValueRef<'a>,
39 args: Args<'a>,
40}
41
42impl<'a> DmoOperation<'a> {
43 fn new(
44 operation: &'static str,
45 field_name: impl Into<DmoOperationFieldKey<'a>>,
46 args: Args<'a>,
47 ) -> Self {
48 Self {
49 operation,
50 field_name: field_name.into().0,
51 args,
52 }
53 }
54
55 pub fn add(
56 field_name: impl Into<DmoOperationFieldKey<'a>>,
57 value: impl Into<ValueRef<'a>>,
58 ) -> Self {
59 Self::new(ops::ADD, field_name, Args::One(value.into()))
60 }
61
62 pub fn sub(
63 field_name: impl Into<DmoOperationFieldKey<'a>>,
64 value: impl Into<ValueRef<'a>>,
65 ) -> Self {
66 Self::new(ops::SUB, field_name, Args::One(value.into()))
67 }
68
69 pub fn and(
70 field_name: impl Into<DmoOperationFieldKey<'a>>,
71 value: impl Into<ValueRef<'a>>,
72 ) -> Self {
73 Self::new(ops::AND, field_name, Args::One(value.into()))
74 }
75
76 pub fn or(
77 field_name: impl Into<DmoOperationFieldKey<'a>>,
78 value: impl Into<ValueRef<'a>>,
79 ) -> Self {
80 Self::new(ops::OR, field_name, Args::One(value.into()))
81 }
82
83 pub fn xor(
84 field_name: impl Into<DmoOperationFieldKey<'a>>,
85 value: impl Into<ValueRef<'a>>,
86 ) -> Self {
87 Self::new(ops::XOR, field_name, Args::One(value.into()))
88 }
89
90 pub fn string_splice(
91 field_name: impl Into<DmoOperationFieldKey<'a>>,
92 from: usize,
93 len: usize,
94 value: &'a str,
95 ) -> Self {
96 Self::new(
97 ops::STRING_SPLICE,
98 field_name,
99 Args::Three(from.into(), len.into(), value.into()),
100 )
101 }
102
103 pub fn insert(
104 field_name: impl Into<DmoOperationFieldKey<'a>>,
105 value: impl Into<ValueRef<'a>>,
106 ) -> Self {
107 Self::new(ops::INSERT, field_name, Args::One(value.into()))
108 }
109
110 pub fn assign(
111 field_name: impl Into<DmoOperationFieldKey<'a>>,
112 value: impl Into<ValueRef<'a>>,
113 ) -> Self {
114 Self::new(ops::ASSIGN, field_name, Args::One(value.into()))
115 }
116
117 pub fn delete(field_name: impl Into<DmoOperationFieldKey<'a>>) -> Self {
118 Self::new(ops::DEL, field_name, Args::None)
119 }
120}
121
122impl<'a> TupleElement for DmoOperation<'a> {
123 fn encode_into_writer<W: Write>(&self, mut buf: W) -> Result<(), EncodingError> {
124 let arr_len = 2 + match self.args {
125 Args::None => 0,
126 Args::One(_) => 1,
127 Args::Three(_, _, _) => 3,
128 };
129 rmp::encode::write_array_len(&mut buf, arr_len)?;
130 rmp::encode::write_str(&mut buf, self.operation)?;
131 rmpv::encode::write_value_ref(&mut buf, &self.field_name)?;
132 match &self.args {
133 Args::None => {}
134 Args::One(x) => {
135 rmpv::encode::write_value_ref(&mut buf, x)?;
136 }
137 Args::Three(x, y, z) => {
138 rmpv::encode::write_value_ref(&mut buf, x)?;
139 rmpv::encode::write_value_ref(&mut buf, y)?;
140 rmpv::encode::write_value_ref(&mut buf, z)?;
141 }
142 }
143 Ok(())
144 }
145}
146
147impl<'a> Tuple for DmoOperation<'a> {
149 fn encode_into_writer<W: Write>(&self, mut buf: W) -> Result<(), EncodingError> {
150 rmp::encode::write_array_len(&mut buf, 1)?;
151 TupleElement::encode_into_writer(self, &mut buf)?;
152 Ok(())
153 }
154}
155
156#[derive(Debug)]
157enum Args<'a> {
158 None,
159 One(rmpv::ValueRef<'a>),
160 Three(rmpv::ValueRef<'a>, rmpv::ValueRef<'a>, rmpv::ValueRef<'a>),
161}
162
163mod ops {
164 pub(super) const ADD: &str = "+";
165 pub(super) const SUB: &str = "-";
166 pub(super) const AND: &str = "&";
167 pub(super) const OR: &str = "|";
168 pub(super) const XOR: &str = "^";
169 pub(super) const STRING_SPLICE: &str = ":";
170 pub(super) const INSERT: &str = "|";
171 pub(super) const DEL: &str = "#";
172 pub(super) const ASSIGN: &str = "=";
173}