1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
// Copyright 2015-2018 Aerospike, Inc.
//
// Portions may be licensed to Aerospike, Inc. under one or more contributor
// license agreements.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

//! List bin operations. Create list operations used by the client's `operate()` method.
//!
//! List operations support negative indexing. If the index is negative, the resolved index starts
//! backwards from the end of the list.
//!
//! Index/Count examples:
//!
//! * Index 0: First item in list.
//! * Index 4: Fifth item in list.
//! * Index -1: Last item in list.
//! * Index -3: Third to last item in list.
//! * Index 1, Count 2: Second and third item in list.
//! * Index -3, Count 3: Last three items in list.
//! * Index -5, Count 4: Range between fifth to last item to second to last item inclusive.
//!
//! If an index is out of bounds, a parameter error will be returned. If a range is partially out of
//! bounds, the valid part of the range will be returned.

use operations::cdt::{CdtArgument, CdtOpType, CdtOperation};
use operations::{Operation, OperationBin, OperationData, OperationType};
use Value;

/// Create list append operation. Server appends value to the end of list bin. Server returns
/// list size.
pub fn append<'a>(bin: &'a str, value: &'a Value) -> Operation<'a> {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListAppend,
        args: vec![CdtArgument::Value(value)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list append items operation. Server appends each input list item to the end of list
/// bin. Server returns list size.
pub fn append_items<'a>(bin: &'a str, values: &'a [Value]) -> Operation<'a> {
    assert!(!values.is_empty());

    let cdt_op = CdtOperation {
        op: CdtOpType::ListAppendItems,
        args: vec![CdtArgument::List(values)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list insert operation. Server inserts value to the specified index of the list bin.
/// Server returns list size.
pub fn insert<'a>(bin: &'a str, index: i64, value: &'a Value) -> Operation<'a> {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListInsert,
        args: vec![CdtArgument::Int(index), CdtArgument::Value(value)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list insert items operation. Server inserts each input list item starting at the
/// specified index of the list bin. Server returns list size.
pub fn insert_items<'a>(bin: &'a str, index: i64, values: &'a [Value]) -> Operation<'a> {
    assert!(!values.is_empty());

    let cdt_op = CdtOperation {
        op: CdtOpType::ListInsertItems,
        args: vec![CdtArgument::Int(index), CdtArgument::List(values)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list pop operation. Server returns the item at the specified index and removes the
/// item from the list bin.
pub fn pop(bin: &str, index: i64) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListPop,
        args: vec![CdtArgument::Int(index)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list pop range operation. Server returns `count` items starting at the specified
/// index and removes the items from the list bin.
pub fn pop_range(bin: &str, index: i64, count: i64) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListPopRange,
        args: vec![CdtArgument::Int(index), CdtArgument::Int(count)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list pop range operation. Server returns the items starting at the specified index
/// to the end of the list and removes those items from the list bin.
pub fn pop_range_from(bin: &str, index: i64) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListPopRange,
        args: vec![CdtArgument::Int(index)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list remove operation. Server removes the item at the specified index from the list
/// bin. Server returns the number of items removed.
pub fn remove(bin: &str, index: i64) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListRemove,
        args: vec![CdtArgument::Int(index)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list remove range operation. Server removes `count` items starting at the specified
/// index from the list bin. Server returns the number of items removed.
pub fn remove_range(bin: &str, index: i64, count: i64) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListRemoveRange,
        args: vec![CdtArgument::Int(index), CdtArgument::Int(count)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list remove range operation. Server removes the items starting at the specified
/// index to the end of the list. Server returns the number of items removed.
pub fn remove_range_from(bin: &str, index: i64) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListRemoveRange,
        args: vec![CdtArgument::Int(index)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list set operation. Server sets the item value at the specified index in the list
/// bin. Server does not return a result by default.
pub fn set<'a>(bin: &'a str, index: i64, value: &'a Value) -> Operation<'a> {
    assert!(!value.is_nil());

    let cdt_op = CdtOperation {
        op: CdtOpType::ListSet,
        args: vec![CdtArgument::Int(index), CdtArgument::Value(value)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list trim operation. Server removes `count` items in the list bin that do not fall
/// into the range specified by `index` and `count`. If the range is out of bounds, then all
/// items will be removed. Server returns list size after trim.
pub fn trim(bin: &str, index: i64, count: i64) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListTrim,
        args: vec![CdtArgument::Int(index), CdtArgument::Int(count)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list clear operation. Server removes all items in the list bin. Server does not
/// return a result by default.
pub fn clear(bin: &str) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListClear,
        args: vec![],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list increment operation. Server increments the item value at the specified index by the
/// given amount and returns the final result.
pub fn increment(bin: &str, index: i64, value: i64) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListIncrement,
        args: vec![CdtArgument::Int(index), CdtArgument::Int(value)],
    };
    Operation {
        op: OperationType::CdtWrite,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list size operation. Server returns size of the list.
pub fn size(bin: &str) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListSize,
        args: vec![],
    };
    Operation {
        op: OperationType::CdtRead,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list get operation. Server returns the item at the specified index in the list bin.
pub fn get(bin: &str, index: i64) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListGet,
        args: vec![CdtArgument::Int(index)],
    };
    Operation {
        op: OperationType::CdtRead,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list get range operation. Server returns `count` items starting at the specified
/// index in the list bin.
pub fn get_range(bin: &str, index: i64, count: i64) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListGetRange,
        args: vec![CdtArgument::Int(index), CdtArgument::Int(count)],
    };
    Operation {
        op: OperationType::CdtRead,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}

/// Create list get range operation. Server returns items starting at the index to the end of
/// the list.
pub fn get_range_from(bin: &str, index: i64) -> Operation {
    let cdt_op = CdtOperation {
        op: CdtOpType::ListGetRange,
        args: vec![CdtArgument::Int(index)],
    };
    Operation {
        op: OperationType::CdtRead,
        bin: OperationBin::Name(bin),
        data: OperationData::CdtListOp(cdt_op),
    }
}