common_meta/key/
txn_helper.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use serde::de::DeserializeOwned;
16use serde::Serialize;
17
18use crate::error::Result;
19use crate::key::{DeserializedValueWithBytes, MetadataValue};
20use crate::kv_backend::txn::TxnOpResponse;
21use crate::rpc::KeyValue;
22
23/// The response set of [TxnOpResponse::ResponseGet]
24pub struct TxnOpGetResponseSet(Vec<KeyValue>);
25
26impl TxnOpGetResponseSet {
27    /// Returns a filter to consume a [KeyValue] where the key equals `key`.
28    pub fn filter(key: Vec<u8>) -> impl FnMut(&mut TxnOpGetResponseSet) -> Option<Vec<u8>> {
29        move |set| {
30            let pos = set.0.iter().position(|kv| kv.key == key);
31            match pos {
32                Some(pos) => Some(set.0.remove(pos).value),
33                None => None,
34            }
35        }
36    }
37
38    /// Returns a decoder to decode bytes to `DeserializedValueWithBytes<T>`.
39    pub fn decode_with<F, T>(
40        mut f: F,
41    ) -> impl FnMut(&mut TxnOpGetResponseSet) -> Result<Option<DeserializedValueWithBytes<T>>>
42    where
43        F: FnMut(&mut TxnOpGetResponseSet) -> Option<Vec<u8>>,
44        T: Serialize + DeserializeOwned + MetadataValue,
45    {
46        move |set| {
47            f(set)
48                .map(|value| DeserializedValueWithBytes::from_inner_slice(&value))
49                .transpose()
50        }
51    }
52}
53
54impl From<&mut Vec<TxnOpResponse>> for TxnOpGetResponseSet {
55    fn from(value: &mut Vec<TxnOpResponse>) -> Self {
56        let value = value
57            .extract_if(.., |resp| matches!(resp, TxnOpResponse::ResponseGet(_)))
58            .flat_map(|resp| {
59                // Safety: checked
60                let TxnOpResponse::ResponseGet(r) = resp else {
61                    unreachable!()
62                };
63
64                r.kvs
65            })
66            .collect::<Vec<_>>();
67        TxnOpGetResponseSet(value)
68    }
69}