You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: bind.rs
    path of file: ./repos/diesel/diesel/src/mysql/connection
    
    the code of the file until where you have to start completion: #![allow(unsafe_code)] // module uses ffi
use mysqlclient_sys as ffi;
use std::mem;
use std::mem::MaybeUninit;
use std::ops::Index;
use std::os::raw as libc;
use std::ptr::NonNull;

use super::stmt::MysqlFieldMetadata;
use super::stmt::StatementUse;
use crate::mysql::connection::stmt::StatementMetadata;
use crate::mysql::types::date_and_time::MysqlTime;
use crate::mysql::{MysqlType, MysqlValue};
use crate::result::QueryResult;

pub(super) struct PreparedStatementBinds(Binds);

pub(super) struct OutputBinds(Binds);

impl Clone for OutputBinds {
    fn clone(&self) -> Self {
        Self(Binds {
            data: self.0.data.clone(),
        })
    }
}

struct Binds {
    data: Vec<BindData>,
}

impl PreparedStatementBinds {
    pub(super) fn from_input_data<Iter>(input: Iter) -> Self
    where
        Iter: IntoIterator<Item = (MysqlType, Option<Vec<u8>>)>,
    {
        let data = input
            .into_iter()
            .map(BindData::for_input)
            .collect::<Vec<_>>();

        Self(Binds { data })
    }

    pub(super) fn with_mysql_binds<F, T>(&mut self, f: F) -> T
    where
        F: FnOnce(*mut ffi::MYSQL_BIND) -> T,
    {
        self.0.with_mysql_binds(f)
    }
}

impl OutputBinds {
    pub(super) fn from_output_types(
        types: &[Option<MysqlType>],
        metadata: &StatementMetadata,
    ) -> Self {
        let data = metadata
            .fields()
            .iter()
            .zip(types.iter().copied().chain(std::iter::repeat(None)))
            .map(|(field, tpe)| BindData::for_output(tpe, field))
            .collect();

        Self(Binds { data })
    }

    pub(super) fn populate_dynamic_buffers(&mut self, stmt: &StatementUse<'_>) -> QueryResult<()> {
        for (i, data) in self.0.data.iter_mut().enumerate() {
            data.did_numeric_overflow_occur()?;
            // This is safe because we are re-binding the invalidated buffers
            // at the end of this function
            unsafe {
                if let Some((mut bind, offset)) = data.bind_for_truncated_data() {
                    stmt.fetch_column(&mut bind, i, offset)?
                } else {
                    data.update_buffer_length()
                }
            }
        }

        unsafe { self.with_mysql_binds(|bind_ptr| stmt.bind_result(bind_ptr)) }
    }

    pub(super) fn update_buffer_lengths(&mut self) {
        for data in &mut self.0.data {
            data.update_buffer_length();
        }
    }

    pub(super) fn with_mysql_binds<F, T>(&mut self, f: F) -> T
    where
        F: FnOnce(*mut ffi::MYSQL_BIND) -> T,
    {
        self.0.with_mysql_binds(f)
    }
}

impl Binds {
    fn with_mysql_binds<F, T>(&mut self, f: F) -> T
    where
        F: FnOnce(*mut ffi::MYSQL_BIND) -> T,
    {
        let mut binds = self
            .data
            .iter_mut()
            .map(|x| unsafe { x.mysql_bind() })
            .collect::<Vec<_>>();
        f(binds.as_mut_ptr())
    }
}

impl Index<usize> for OutputBinds {
    type Output = BindData;
    fn index(&self, index: usize) -> &Self::Output {
        &self.0.data[index]
    }
}

bitflags::bitflags! {
    #[derive(Clone, Copy, Debug)]
    pub(crate) struct Flags: u32 {
        const NOT_NULL_FLAG = 1;
        const PRI_KEY_FLAG = 2;
        const UNIQUE_KEY_FLAG = 4;
        const MULTIPLE_KEY_FLAG = 8;
        const BLOB_FLAG = 16;
        const UNSIGNED_FLAG = 32;
        const ZEROFILL_FLAG = 64;
        const BINARY_FLAG = 128;
        const ENUM_FLAG = 256;
        const AUTO_INCREMENT_FLAG = 512;
        const TIMESTAMP_FLAG = 1024;
        const SET_FLAG = 2048;
        const NO_DEFAULT_VALUE_FLAG = 4096;
        const ON_UPDATE_N
    
    fn check_set_bind() {
        let conn = &mut crate::test_helpers::connection();

        crate::sql_query("DROP TABLE IF EXISTS set_test CASCADE")
            .execute(conn)
            .unwrap();

        crate::sql_query("CREATE TABLE set_test(id INTEGER PRIMARY KEY, set_field SET('red', 'green', 'blue') NOT NULL)").execute(conn)
            .unwrap();

        crate::sql_query("INSERT INTO set_test(id, set_field) VALUES (1, 'green')")
            .execute(conn)
            .unwrap();

        let set_col_as_set: BindData =
            query_single_table("SELECT set_field FROM set_test", conn, MysqlType::Set);

        assert_eq!(set_col_as_set.tpe, ffi::enum_field_types::MYSQL_TYPE_STRING);
        assert!(!set_col_as_set.flags.contains(Flags::NUM_FLAG));
        assert!(!set_col_as_set.flags.contains(Flags::BLOB_FLAG));
        assert!(set_col_as_set.flags.contains(Flags::SET_FLAG));
        assert!(!set_col_as_set.flags.contains(Flags::ENUM_FLAG));
        assert!(!set_col_as_set.flags.contains(Flags::BINARY_FLAG));
        assert_eq!(to_value::<Text, String>(&set_col_as_set).unwrap(), "green");

        for tpe in &[
            ffi::enum_field_types::MYSQL_TYPE_BLOB,
            ffi::enum_field_types::MYSQL_TYPE_VAR_STRING,
            ffi::enum_field_types::MYSQL_TYPE_TINY_BLOB,
            ffi::enum_field_types::MYSQL_TYPE_MEDIUM_BLOB,
            ffi::enum_field_types::MYSQL_TYPE_LONG_BLOB,
        ] {
            let set_col_as_text = query_single_table(
                "SELECT set_field FROM set_test",
                conn,
                (*tpe, Flags::SET_FLAG),
            );

            assert_eq!(set_col_as_text.tpe, *tpe);
            assert!(!set_col_as_text.flags.contains(Flags::NUM_FLAG));
            assert!(!set_col_as_text.flags.contains(Flags::BLOB_FLAG));
            assert!(set_col_as_text.flags.contains(Flags::SET_FLAG));
            assert!(!set_col_as_text.flags.contains(Flags::ENUM_FLAG));
            assert!(!set_col_as_text.flags.contains(Flags::BINARY_FLAG));
            assert_eq!(to_value::<Text, String>(&set_col_as_text).unwrap(), "green");
            assert_eq!(
                set_col_as_set.value().unwrap().as_bytes(),
                set_col_as_text.value().unwrap().as_bytes()
            );
        }
        let set_col_as_text = query_single_table(
            "SELECT set_field FROM set_test",
            conn,
            (ffi::enum_field_types::MYSQL_TYPE_BLOB, Flags::empty()),
        );

        assert_eq!(set_col_as_text.tpe, ffi::enum_field_types::MYSQL_TYPE_BLOB);
        assert!(!set_col_as_text.flags.contains(Flags::NUM_FLAG));
        assert!(!set_col_as_text.flags.contains(Flags::BLOB_FLAG));
        assert!(!set_col_as_text.flags.contains(Flags::SET_FLAG));
        assert!(!set_col_as_text.flags.contains(Flags::ENUM_FLAG));
        assert!(!set_col_as_text.flags.contains(Flags::BINARY_FLAG));
        assert_eq!(to_value::<Text, String>(&set_col_as_text).unwrap(), "green");
        assert_eq!(
            set_col_as_set.value().unwrap().as_bytes(),
            set_col_as_text.value().unwrap().as_bytes()
        );

        crate::sql_query("DELETE FROM set_test")
            .execute(conn)
            .unwrap();

        input_bind(
            "INSERT INTO set_test(id, set_field) VALUES (?, ?)",
            conn,
            41,
            (b"blue".to_vec(), MysqlType::Set),
        );

        let set_col_as_set =
            query_single_table("SELECT set_field FROM set_test", conn, MysqlType::Set);

        assert_eq!(set_col_as_set.tpe, ffi::enum_field_types::MYSQL_TYPE_STRING);
        assert!(!set_col_as_set.flags.contains(Flags::NUM_FLAG));
        assert!(!set_col_as_set.flags.contains(Flags::BLOB_FLAG));
        assert!(set_col_as_set.flags.contains(Flags::SET_FLAG));
        assert!(!set_col_as_set.flags.contains(Flags::ENUM_FLAG));
        assert!(!set_col_as_set.flags.contains(Flags::BINARY_FLAG));
        assert_eq!(to_value::<Text, String>(&set_col_as_set).unwrap(), "blue");

        let set_col_as_text = query_single_table(
            "SELECT set_field FROM set_test",
            conn,
            (ffi::enum_field_types::MYSQL_TYPE_BLOB, Flags::SET_FLAG),
        );

        assert_eq!(set_col_as_text.tpe, ffi::enum_field_types::MYSQL_TYPE_BLOB);
        assert!(!set_col_as_text.flags.contains(Flags::NUM_FLAG));
        assert!(!set_col_as_text.flags.contains(Flags::BLOB_FLAG));
        assert!(set_col_as_text.flags.contains(Flags::SET_FLAG));
        assert!(!set_col_as_text.flags.contains(Flags::ENUM_FLAG));
        assert!(!set_col_as_text.flags.contains(Flags::BINARY_FLAG));
        assert_eq!(to_value::<Text, String>(&set_col_as_text).unwrap(), "blue");
        assert_eq!(
            set_col_as_set.value().unwrap().as_bytes(),
            set_col_as_text.value().unwrap().as_bytes()
        );

        crate::sql_query("DELETE FROM set_test")
            .execute(conn)
            .unwrap();

        input_bind(
            "INSERT INTO set_test(id, set_field) VALUES (?, ?)",
            conn,
            41,
            (b"red".to_vec(), MysqlType::String),
        );

        let set_col_as_set =
            query_single_table("SELECT set_field FROM set_test", conn, MysqlType::Set);

        assert_eq!(set_col_as_set.tpe, ffi::enum_field_types::MYSQL_TYPE_STRING);
        assert!(!set_col_as_set.flags.contains(Flags::NUM_FLAG));
        assert!(!set_col_as_set.flags.contains(Flags::BLOB_FLAG));
        assert!(set_col_as_set.flags.contains(Flags::SET_FLAG));
        assert!(!set_col_as_set.flags.contains(Flags::ENUM_FLAG));
        assert!(!set_col_as_set.flags.contains(Flags::BINARY_FLAG));
        assert_eq!(to_value::<Text, String>(&set_col_as_set).unwrap(), "red");

        let set_col_as_text = query_single_table(
            "SELECT set_field FROM set_test",
            conn,
            (ffi::enum_field_types::MYSQL_TYPE_BLOB, Flags::SET_FLAG),
        );

        assert_eq!(set_col_as_text.tpe, ffi::enum_field_types::MYSQL_TYPE_BLOB);
        assert!(!set_col_as_text.flags.contains(Flags::NUM_FLAG));
        assert!(!set_col_as_text.flags.contains(Flags::BLOB_FLAG));
        assert!(set_col_as_text.flags.contains(Flags::SET_FLAG));
        assert!(!set_col_as_text.flags.contains(Flags::ENUM_FLAG));
        assert!(!set_col_as_text.flags.contains(Flags::BINARY_FLAG));
        assert_eq!(to_value::<Text, String>(&set_col_as_text).unwrap(), "red");
        assert_eq!(
            set_col_as_set.value().unwrap().as_bytes(),
            set_col_as_text.value().unwrap().as_bytes()
        );
    }