rs_split_table/rdb/
tabchk.rs

1//! Functions to create a [`TableChecker`].
2
3use tonic::Status;
4
5/// Checks the table name to prevent unexpected sql(e.g, SQL injection).
6pub trait TableChecker: Sync + Send + 'static {
7    /// Checks the name of the table.
8    fn check(&self, table_name: &str) -> Result<(), Status>;
9
10    /// Converts the table name to the checked name if it is valid.
11    fn to_checked(&self, table_name: String) -> Result<String, Status> {
12        self.check(table_name.as_str())?;
13        Ok(table_name)
14    }
15}
16
17#[derive(Clone)]
18pub struct CheckFn<F> {
19    checker: F,
20}
21
22impl<F> TableChecker for CheckFn<F>
23where
24    F: Fn(&str) -> Result<(), Status> + Send + Sync + 'static,
25{
26    fn check(&self, table_name: &str) -> Result<(), Status> {
27        (self.checker)(table_name)
28    }
29}
30
31/// Creates a [`TableChecker`] from the specified function.
32pub fn fn2checker<F>(checker: F) -> impl TableChecker + Clone
33where
34    F: Fn(&str) -> Result<(), Status> + Send + Sync + Clone + 'static,
35{
36    CheckFn { checker }
37}
38
39/// Creates a [`TableChecker`] from the specified functions(AND).
40pub fn double_checker_new<A, B>(chk1: A, chk2: B) -> impl TableChecker
41where
42    A: Fn(&str) -> Result<(), Status> + Send + Sync + 'static,
43    B: Fn(&str) -> Result<(), Status> + Send + Sync + 'static,
44{
45    let dchk = move |tabname: &str| {
46        chk1(tabname)?;
47        chk2(tabname)?;
48        Ok(())
49    };
50    CheckFn { checker: dchk }
51}