//! Create virtual tables.
//!
//! Follow these steps to create your own virtual table:
//! 1. Write implementation of [`VTab`] and [`VTabCursor`] traits.
//! 2. Create an instance of the [`Module`] structure specialized for [`VTab`]
//! impl. from step 1.
//! 3. Register your [`Module`] structure using [`Connection::create_module`].
//! 4. Run a `CREATE VIRTUAL TABLE` command that specifies the new module in the
//! `USING` clause.
//!
//! (See [SQLite doc](http://sqlite.org/vtab.html))
use std::borrow::Cow::{self, Borrowed, Owned};
use std::marker::PhantomData;
use std::marker::Sync;
use std::os::raw::{c_char, c_int, c_void};
use std::ptr;
use std::slice;

use crate::context::set_result;
use crate::error::error_from_sqlite_code;
use crate::ffi;
pub use crate::ffi::{sqlite3_vtab, sqlite3_vtab_cursor};
use crate::types::{FromSql, FromSqlError, ToSql, ValueRef};
use crate::{str_to_cstring, Connection, Error, InnerConnection, Result};

// let conn: Connection = ...;
// let mod: Module = ...; // VTab builder
// conn.create_module("module", mod);
//
// conn.execute("CREATE VIRTUAL TABLE foo USING module(...)");
// \-> Module::xcreate
//  |-> let vtab: VTab = ...; // on the heap
//  \-> conn.declare_vtab("CREATE TABLE foo (...)");
// conn = Connection::open(...);
// \-> Module::xconnect
//  |-> let vtab: VTab = ...; // on the heap
//  \-> conn.declare_vtab("CREATE TABLE foo (...)");
//
// conn.close();
// \-> vtab.xdisconnect
// conn.execute("DROP TABLE foo");
// \-> vtab.xDestroy
//
// let stmt = conn.prepare("SELECT ... FROM foo WHERE ...");
// \-> vtab.xbestindex
// stmt.query().next();
// \-> vtab.xopen
//  |-> let cursor: VTabCursor = ...; // on the heap
//  |-> cursor.xfilter or xnext
//  |-> cursor.xeof
//  \-> if not eof { cursor.column or xrowid } else { cursor.xclose }
//

// db: *mut ffi::sqlite3 => VTabConnection
// module: *const ffi::sqlite3_module => Module
// aux: *mut c_void => Module::Aux
// ffi::sqlite3_vtab => VTab
// ffi::sqlite3_vtab_cursor => VTabCursor

/// Virtual table kind
pub enum VTabKind {
    /// Non-eponymous
    Default,
    /// [`create`](CreateVTab::create) == [`connect`](VTab::connect)
    ///
    /// See [SQLite doc](https://sqlite.org/vtab.html#eponymous_virtual_tables)
    Eponymous,
    /// No [`create`](CreateVTab::create) / [`destroy`](CreateVTab::destroy) or
    /// not used
    ///
    /// SQLite >= 3.9.0
    ///
    /// See [SQLite doc](https://sqlite.org/vtab.html#eponymous_only_virtual_tables)
    EponymousOnly,
}

/// Virtual table module
///
/// (See [SQLite doc](https://sqlite.org/c3ref/module.html))
#[repr(transparent)]
pub struct Module<'vtab, T: VTab<'vtab>> {
    base: ffi::sqlite3_module,
    phantom: PhantomData<&'vtab T>,
}

unsafe impl<'vtab, T: VTab<'vtab>> Send for Module<'vtab, T> {}
unsafe impl<'vtab, T: VTab<'vtab>> Sync for Module<'vtab, T> {}

union ModuleZeroHack {
    bytes: [u8; std::mem::size_of::<ffi::sqlite3_module>()],
    module: ffi::sqlite3_module,
}

// Used as a trailing initializer for sqlite3_module -- this way we avoid having
// the build fail if buildtime_bindgen is on. This is safe, as bindgen-generated
// structs are allowed to be zeroed.
const ZERO_MODULE: ffi::sqlite3_module = unsafe {
    ModuleZeroHack {
        bytes: [0_u8; std::mem::size_of::<ffi::sqlite3_module>()],
    }
    .module
};

macro_rules! module {
    ($lt:lifetime, $vt:ty, $ct:ty, $xc:expr, $xd:expr, $xu:expr) => {
    #[allow(clippy::needless_update)]
    &Module {
        base: ffi::sqlite3_module {
            // We don't use V3
            iVersion: 2,
            xCreate: $xc,
            xConnect: Some(rust_connect::<$vt>),
            xBestIndex: Some(rust_best_index::<$vt>),
            xDisconnect: Some(rust_disconnect::<$vt>),
            xDestroy: $xd,
            xOpen: Some(rust_open::<$vt>),
            xClose: Some(rust_close::<$ct>),
            xFilter: Some(rust_filter::<$ct>),
            xNext: Some(rust_next::<$ct>),
            xEof: Some(rust_eof::<$ct>),
            xColumn: Some(rust_column::<$ct>),
            xRowid: Some(rust_rowid::<$ct>), // FIXME optional
            xUpdate: $xu,
            xBegin: None,
            xSync: None,
            xCommit: None,
            xRollback: None,
            xFindFunction: None,
            xRename: None,
            xSavepoint: None,
            xRelease: None,
            xRollbackTo: None,
            ..ZERO_MODULE
        },
        phantom: PhantomData::<&$lt $vt>,
    }
    };
}

/// Create an modifiable virtual table implementation.
///
/// Step 2 of [Creating New Virtual Table Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
#[must_use]
pub fn update_module<'vtab, T: UpdateVTab<'vtab>>() -> &'static Module<'vtab, T> {
    match T::KIND {
        VTabKind::EponymousOnly => {
            module!('vtab, T, T::Cursor, None, None, Some(rust_update::<T>))
        }
        VTabKind::Eponymous => {
            module!('vtab, T, T::Cursor, Some(rust_connect::<T>), Some(rust_disconnect::<T>), Some(rust_update::<T>))
        }
        _ => {
            module!('vtab, T, T::Cursor, Some(rust_create::<T>), Some(rust_destroy::<T>), Some(rust_update::<T>))
        }
    }
}

/// Create a read-only virtual table implementation.
///
/// Step 2 of [Creating New Virtual Table Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
#[must_use]
pub fn read_only_module<'vtab, T: CreateVTab<'vtab>>() -> &'static Module<'vtab, T> {
    match T::KIND {
        VTabKind::EponymousOnly => eponymous_only_module(),
        VTabKind::Eponymous => {
            // A virtual table is eponymous if its xCreate method is the exact same function
            // as the xConnect method
            module!('vtab, T, T::Cursor, Some(rust_connect::<T>), Some(rust_disconnect::<T>), None)
        }
        _ => {
            // The xConnect and xCreate methods may do the same thing, but they must be
            // different so that the virtual table is not an eponymous virtual table.
            module!('vtab, T, T::Cursor, Some(rust_create::<T>), Some(rust_destroy::<T>), None)
        }
    }
}

/// Create an eponymous only virtual table implementation.
///
/// Step 2 of [Creating New Virtual Table Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
#[must_use]
pub fn eponymous_only_module<'vtab, T: VTab<'vtab>>() -> &'static Module<'vtab, T> {
    //  For eponymous-only virtual tables, the xCreate method is NULL
    module!('vtab, T, T::Cursor, None, None, None)
}

/// Virtual table configuration options
#[repr(i32)]
#[non_exhaustive]
#[cfg(feature = "modern_sqlite")] // 3.7.7
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum VTabConfig {
    /// Equivalent to SQLITE_VTAB_CONSTRAINT_SUPPORT
    ConstraintSupport = 1,
    /// Equivalent to SQLITE_VTAB_INNOCUOUS
    Innocuous = 2,
    /// Equivalent to SQLITE_VTAB_DIRECTONLY
    DirectOnly = 3,
}

/// `feature = "vtab"`
pub struct VTabConnection(*mut ffi::sqlite3);

impl VTabConnection {
    /// Configure various facets of the virtual table interface
    #[cfg(feature = "modern_sqlite")] // 3.7.7
    #[cfg_attr(docsrs, doc(cfg(feature = "modern_sqlite")))]
    pub fn config(&mut self, config: VTabConfig) -> Result<()> {
        crate::error::check(unsafe { ffi::sqlite3_vtab_config(self.0, config as c_int) })
    }

    // TODO sqlite3_vtab_on_conflict (http://sqlite.org/c3ref/vtab_on_conflict.html) & xUpdate

    /// Get access to the underlying SQLite database connection handle.
    ///
    /// # Warning
    ///
    /// You should not need to use this function. If you do need to, please
    /// [open an issue on the rusqlite repository](https://github.com/rusqlite/rusqlite/issues) and describe
    /// your use case.
    ///
    /// # Safety
    ///
    /// This function is unsafe because it gives you raw access
    /// to the SQLite connection, and what you do with it could impact the
    /// safety of this `Connection`.
    pub unsafe fn handle(&mut self) -> *mut ffi::sqlite3 {
        self.0
    }
}

/// Eponymous-only virtual table instance trait.
///
/// # Safety
///
/// The first item in a struct implementing `VTab` must be
/// `rusqlite::sqlite3_vtab`, and the struct must be `#[repr(C)]`.
///
/// ```rust,ignore
/// #[repr(C)]
/// struct MyTab {
///    /// Base class. Must be first
///    base: rusqlite::vtab::sqlite3_vtab,
///    /* Virtual table implementations will typically add additional fields */
/// }
/// ```
///
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab.html))
pub unsafe trait VTab<'vtab>: Sized {
    /// Client data passed to [`Connection::create_module`].
    type Aux;
    /// Specific cursor implementation
    type Cursor: VTabCursor;

    /// Establish a new connection to an existing virtual table.
    ///
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xconnect_method))
    fn connect(
        db: &mut VTabConnection,
        aux: Option<&Self::Aux>,
        args: &[&[u8]],
    ) -> Result<(String, Self)>;

    /// Determine the best way to access the virtual table.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xbestindex_method))
    fn best_index(&self, info: &mut IndexInfo) -> Result<()>;

    /// Create a new cursor used for accessing a virtual table.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xopen_method))
    fn open(&'vtab mut self) -> Result<Self::Cursor>;
}

/// Read-only virtual table instance trait.
///
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab.html))
pub trait CreateVTab<'vtab>: VTab<'vtab> {
    /// For [`EponymousOnly`](VTabKind::EponymousOnly),
    /// [`create`](CreateVTab::create) and [`destroy`](CreateVTab::destroy) are
    /// not called
    const KIND: VTabKind;
    /// Create a new instance of a virtual table in response to a CREATE VIRTUAL
    /// TABLE statement. The `db` parameter is a pointer to the SQLite
    /// database connection that is executing the CREATE VIRTUAL TABLE
    /// statement.
    ///
    /// Call [`connect`](VTab::connect) by default.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xcreate_method))
    fn create(
        db: &mut VTabConnection,
        aux: Option<&Self::Aux>,
        args: &[&[u8]],
    ) -> Result<(String, Self)> {
        Self::connect(db, aux, args)
    }

    /// Destroy the underlying table implementation. This method undoes the work
    /// of [`create`](CreateVTab::create).
    ///
    /// Do nothing by default.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xdestroy_method))
    fn destroy(&self) -> Result<()> {
        Ok(())
    }
}

/// Writable virtual table instance trait.
///
/// (See [SQLite doc](https://sqlite.org/vtab.html#xupdate))
pub trait UpdateVTab<'vtab>: CreateVTab<'vtab> {
    /// Delete rowid or PK
    fn delete(&mut self, arg: ValueRef<'_>) -> Result<()>;
    /// Insert: `args[0] == NULL: old rowid or PK, args[1]: new rowid or PK,
    /// args[2]: ...`
    ///
    /// Return the new rowid.
    // TODO Make the distinction between argv[1] == NULL and argv[1] != NULL ?
    fn insert(&mut self, args: &Values<'_>) -> Result<i64>;
    /// Update: `args[0] != NULL: old rowid or PK, args[1]: new row id or PK,
    /// args[2]: ...`
    fn update(&mut self, args: &Values<'_>) -> Result<()>;
}

/// Index constraint operator.
/// See [Virtual Table Constraint Operator Codes](https://sqlite.org/c3ref/c_index_constraint_eq.html) for details.
#[derive(Debug, Eq, PartialEq)]
#[allow(non_snake_case, non_camel_case_types, missing_docs)]
#[allow(clippy::upper_case_acronyms)]
pub enum IndexConstraintOp {
    SQLITE_INDEX_CONSTRAINT_EQ,
    SQLITE_INDEX_CONSTRAINT_GT,
    SQLITE_INDEX_CONSTRAINT_LE,
    SQLITE_INDEX_CONSTRAINT_LT,
    SQLITE_INDEX_CONSTRAINT_GE,
    SQLITE_INDEX_CONSTRAINT_MATCH,
    SQLITE_INDEX_CONSTRAINT_LIKE,         // 3.10.0
    SQLITE_INDEX_CONSTRAINT_GLOB,         // 3.10.0
    SQLITE_INDEX_CONSTRAINT_REGEXP,       // 3.10.0
    SQLITE_INDEX_CONSTRAINT_NE,           // 3.21.0
    SQLITE_INDEX_CONSTRAINT_ISNOT,        // 3.21.0
    SQLITE_INDEX_CONSTRAINT_ISNOTNULL,    // 3.21.0
    SQLITE_INDEX_CONSTRAINT_ISNULL,       // 3.21.0
    SQLITE_INDEX_CONSTRAINT_IS,           // 3.21.0
    SQLITE_INDEX_CONSTRAINT_LIMIT,        // 3.38.0
    SQLITE_INDEX_CONSTRAINT_OFFSET,       // 3.38.0
    SQLITE_INDEX_CONSTRAINT_FUNCTION(u8), // 3.25.0
}

impl From<u8> for IndexConstraintOp {
    fn from(code: u8) -> IndexConstraintOp {
        match code {
            2 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_EQ,
            4 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_GT,
            8 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_LE,
            16 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_LT,
            32 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_GE,
            64 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_MATCH,
            65 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_LIKE,
            66 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_GLOB,
            67 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_REGEXP,
            68 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_NE,
            69 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_ISNOT,
            70 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_ISNOTNULL,
            71 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_ISNULL,
            72 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_IS,
            73 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_LIMIT,
            74 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_OFFSET,
            v => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_FUNCTION(v),
        }
    }
}

#[cfg(feature = "modern_sqlite")] // 3.9.0
bitflags::bitflags! {
    /// Virtual table scan flags
    /// See [Function Flags](https://sqlite.org/c3ref/c_index_scan_unique.html) for details.
    #[repr(C)]
    pub struct IndexFlags: ::std::os::raw::c_int {
        /// Default
        const NONE     = 0;
        /// Scan visits at most 1 row.
        const SQLITE_INDEX_SCAN_UNIQUE  = ffi::SQLITE_INDEX_SCAN_UNIQUE;
    }
}

/// Pass information into and receive the reply from the
/// [`VTab::best_index`] method.
///
/// (See [SQLite doc](http://sqlite.org/c3ref/index_info.html))
#[derive(Debug)]
pub struct IndexInfo(*mut ffi::sqlite3_index_info);

impl IndexInfo {
    /// Iterate on index constraint and its associated usage.
    #[inline]
    pub fn constraints_and_usages(&mut self) -> IndexConstraintAndUsageIter<'_> {
        let constraints =
            unsafe { slice::from_raw_parts((*self.0).aConstraint, (*self.0).nConstraint as usize) };
        let constraint_usages = unsafe {
            slice::from_raw_parts_mut((*self.0).aConstraintUsage, (*self.0).nConstraint as usize)
        };
        IndexConstraintAndUsageIter {
            iter: constraints.iter().zip(constraint_usages.iter_mut()),
        }
    }

    /// Record WHERE clause constraints.
    #[inline]
    #[must_use]
    pub fn constraints(&self) -> IndexConstraintIter<'_> {
        let constraints =
            unsafe { slice::from_raw_parts((*self.0).aConstraint, (*self.0).nConstraint as usize) };
        IndexConstraintIter {
            iter: constraints.iter(),
        }
    }

    /// Information about the ORDER BY clause.
    #[inline]
    #[must_use]
    pub fn order_bys(&self) -> OrderByIter<'_> {
        let order_bys =
            unsafe { slice::from_raw_parts((*self.0).aOrderBy, (*self.0).nOrderBy as usize) };
        OrderByIter {
            iter: order_bys.iter(),
        }
    }

    /// Number of terms in the ORDER BY clause
    #[inline]
    #[must_use]
    pub fn num_of_order_by(&self) -> usize {
        unsafe { (*self.0).nOrderBy as usize }
    }

    /// Information about what parameters to pass to [`VTabCursor::filter`].
    #[inline]
    pub fn constraint_usage(&mut self, constraint_idx: usize) -> IndexConstraintUsage<'_> {
        let constraint_usages = unsafe {
            slice::from_raw_parts_mut((*self.0).aConstraintUsage, (*self.0).nConstraint as usize)
        };
        IndexConstraintUsage(&mut constraint_usages[constraint_idx])
    }

    /// Number used to identify the index
    #[inline]
    pub fn set_idx_num(&mut self, idx_num: c_int) {
        unsafe {
            (*self.0).idxNum = idx_num;
        }
    }

    /// String used to identify the index
    pub fn set_idx_str(&mut self, idx_str: &str) {
        unsafe {
            (*self.0).idxStr = alloc(idx_str);
            (*self.0).needToFreeIdxStr = 1;
        }
    }

    /// True if output is already ordered
    #[inline]
    pub fn set_order_by_consumed(&mut self, order_by_consumed: bool) {
        unsafe {
            (*self.0).orderByConsumed = if order_by_consumed { 1 } else { 0 };
        }
    }

    /// Estimated cost of using this index
    #[inline]
    pub fn set_estimated_cost(&mut self, estimated_ost: f64) {
        unsafe {
            (*self.0).estimatedCost = estimated_ost;
        }
    }

    /// Estimated number of rows returned.
    #[cfg(feature = "modern_sqlite")] // SQLite >= 3.8.2
    #[cfg_attr(docsrs, doc(cfg(feature = "modern_sqlite")))]
    #[inline]
    pub fn set_estimated_rows(&mut self, estimated_rows: i64) {
        unsafe {
            (*self.0).estimatedRows = estimated_rows;
        }
    }

    /// Mask of SQLITE_INDEX_SCAN_* flags.
    #[cfg(feature = "modern_sqlite")] // SQLite >= 3.9.0
    #[cfg_attr(docsrs, doc(cfg(feature = "modern_sqlite")))]
    #[inline]
    pub fn set_idx_flags(&mut self, flags: IndexFlags) {
        unsafe { (*self.0).idxFlags = flags.bits() };
    }

    /// Mask of columns used by statement
    #[cfg(feature = "modern_sqlite")] // SQLite >= 3.10.0
    #[cfg_attr(docsrs, doc(cfg(feature = "modern_sqlite")))]
    #[inline]
    pub fn col_used(&self) -> u64 {
        unsafe { (*self.0).colUsed }
    }

    /// Determine the collation for a virtual table constraint
    #[cfg(feature = "modern_sqlite")] // SQLite >= 3.22.0
    #[cfg_attr(docsrs, doc(cfg(feature = "modern_sqlite")))]
    pub fn collation(&self, constraint_idx: usize) -> Result<&str> {
        use std::ffi::CStr;
        let idx = constraint_idx as c_int;
        let collation = unsafe { ffi::sqlite3_vtab_collation(self.0, idx) };
        if collation.is_null() {
            return Err(Error::SqliteFailure(
                ffi::Error::new(ffi::SQLITE_MISUSE),
                Some(format!("{} is out of range", constraint_idx)),
            ));
        }
        Ok(unsafe { CStr::from_ptr(collation) }.to_str()?)
    }

    /*/// Determine if a virtual table query is DISTINCT
    #[cfg(feature = "modern_sqlite")] // SQLite >= 3.38.0
    #[cfg_attr(docsrs, doc(cfg(feature = "modern_sqlite")))]
    pub fn distinct(&self) -> c_int {
        unsafe { ffi::sqlite3_vtab_distinct(self.0) }
    }

    /// Constraint values
    #[cfg(feature = "modern_sqlite")] // SQLite >= 3.38.0
    #[cfg_attr(docsrs, doc(cfg(feature = "modern_sqlite")))]
    pub fn set_rhs_value(&mut self, constraint_idx: c_int, value: ValueRef) -> Result<()> {
        // TODO ValueRef to sqlite3_value
        crate::error::check(unsafe { ffi::sqlite3_vtab_rhs_value(self.O, constraint_idx, value) })
    }

    /// Identify and handle IN constraints
    #[cfg(feature = "modern_sqlite")] // SQLite >= 3.38.0
    #[cfg_attr(docsrs, doc(cfg(feature = "modern_sqlite")))]
    pub fn set_in_constraint(&mut self, constraint_idx: c_int, b_handle: c_int) -> bool {
        unsafe { ffi::sqlite3_vtab_in(self.0, constraint_idx, b_handle) != 0 }
    } // TODO sqlite3_vtab_in_first / sqlite3_vtab_in_next https://sqlite.org/c3ref/vtab_in_first.html
    */
}

/// Iterate on index constraint and its associated usage.
pub struct IndexConstraintAndUsageIter<'a> {
    iter: std::iter::Zip<
        slice::Iter<'a, ffi::sqlite3_index_constraint>,
        slice::IterMut<'a, ffi::sqlite3_index_constraint_usage>,
    >,
}

impl<'a> Iterator for IndexConstraintAndUsageIter<'a> {
    type Item = (IndexConstraint<'a>, IndexConstraintUsage<'a>);

    #[inline]
    fn next(&mut self) -> Option<(IndexConstraint<'a>, IndexConstraintUsage<'a>)> {
        self.iter
            .next()
            .map(|raw| (IndexConstraint(raw.0), IndexConstraintUsage(raw.1)))
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

/// `feature = "vtab"`
pub struct IndexConstraintIter<'a> {
    iter: slice::Iter<'a, ffi::sqlite3_index_constraint>,
}

impl<'a> Iterator for IndexConstraintIter<'a> {
    type Item = IndexConstraint<'a>;

    #[inline]
    fn next(&mut self) -> Option<IndexConstraint<'a>> {
        self.iter.next().map(IndexConstraint)
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

/// WHERE clause constraint.
pub struct IndexConstraint<'a>(&'a ffi::sqlite3_index_constraint);

impl IndexConstraint<'_> {
    /// Column constrained.  -1 for ROWID
    #[inline]
    #[must_use]
    pub fn column(&self) -> c_int {
        self.0.iColumn
    }

    /// Constraint operator
    #[inline]
    #[must_use]
    pub fn operator(&self) -> IndexConstraintOp {
        IndexConstraintOp::from(self.0.op)
    }

    /// True if this constraint is usable
    #[inline]
    #[must_use]
    pub fn is_usable(&self) -> bool {
        self.0.usable != 0
    }
}

/// Information about what parameters to pass to
/// [`VTabCursor::filter`].
pub struct IndexConstraintUsage<'a>(&'a mut ffi::sqlite3_index_constraint_usage);

impl IndexConstraintUsage<'_> {
    /// if `argv_index` > 0, constraint is part of argv to
    /// [`VTabCursor::filter`]
    #[inline]
    pub fn set_argv_index(&mut self, argv_index: c_int) {
        self.0.argvIndex = argv_index;
    }

    /// if `omit`, do not code a test for this constraint
    #[inline]
    pub fn set_omit(&mut self, omit: bool) {
        self.0.omit = if omit { 1 } else { 0 };
    }
}

/// `feature = "vtab"`
pub struct OrderByIter<'a> {
    iter: slice::Iter<'a, ffi::sqlite3_index_info_sqlite3_index_orderby>,
}

impl<'a> Iterator for OrderByIter<'a> {
    type Item = OrderBy<'a>;

    #[inline]
    fn next(&mut self) -> Option<OrderBy<'a>> {
        self.iter.next().map(OrderBy)
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

/// A column of the ORDER BY clause.
pub struct OrderBy<'a>(&'a ffi::sqlite3_index_info_sqlite3_index_orderby);

impl OrderBy<'_> {
    /// Column number
    #[inline]
    #[must_use]
    pub fn column(&self) -> c_int {
        self.0.iColumn
    }

    /// True for DESC.  False for ASC.
    #[inline]
    #[must_use]
    pub fn is_order_by_desc(&self) -> bool {
        self.0.desc != 0
    }
}

/// Virtual table cursor trait.
///
/// # Safety
///
/// Implementations must be like:
/// ```rust,ignore
/// #[repr(C)]
/// struct MyTabCursor {
///    /// Base class. Must be first
///    base: rusqlite::vtab::sqlite3_vtab_cursor,
///    /* Virtual table implementations will typically add additional fields */
/// }
/// ```
///
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab_cursor.html))
pub unsafe trait VTabCursor: Sized {
    /// Begin a search of a virtual table.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xfilter_method))
    fn filter(&mut self, idx_num: c_int, idx_str: Option<&str>, args: &Values<'_>) -> Result<()>;
    /// Advance cursor to the next row of a result set initiated by
    /// [`filter`](VTabCursor::filter). (See [SQLite doc](https://sqlite.org/vtab.html#the_xnext_method))
    fn next(&mut self) -> Result<()>;
    /// Must return `false` if the cursor currently points to a valid row of
    /// data, or `true` otherwise.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xeof_method))
    fn eof(&self) -> bool;
    /// Find the value for the `i`-th column of the current row.
    /// `i` is zero-based so the first column is numbered 0.
    /// May return its result back to SQLite using one of the specified `ctx`.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xcolumn_method))
    fn column(&self, ctx: &mut Context, i: c_int) -> Result<()>;
    /// Return the rowid of row that the cursor is currently pointing at.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xrowid_method))
    fn rowid(&self) -> Result<i64>;
}

/// Context is used by [`VTabCursor::column`] to specify the
/// cell value.
pub struct Context(*mut ffi::sqlite3_context);

impl Context {
    /// Set current cell value
    #[inline]
    pub fn set_result<T: ToSql>(&mut self, value: &T) -> Result<()> {
        let t = value.to_sql()?;
        unsafe { set_result(self.0, &t) };
        Ok(())
    }

    // TODO sqlite3_vtab_nochange (http://sqlite.org/c3ref/vtab_nochange.html) // 3.22.0 & xColumn
}

/// Wrapper to [`VTabCursor::filter`] arguments, the values
/// requested by [`VTab::best_index`].
pub struct Values<'a> {
    args: &'a [*mut ffi::sqlite3_value],
}

impl Values<'_> {
    /// Returns the number of values.
    #[inline]
    #[must_use]
    pub fn len(&self) -> usize {
        self.args.len()
    }

    /// Returns `true` if there is no value.
    #[inline]
    #[must_use]
    pub fn is_empty(&self) -> bool {
        self.args.is_empty()
    }

    /// Returns value at `idx`
    pub fn get<T: FromSql>(&self, idx: usize) -> Result<T> {
        let arg = self.args[idx];
        let value = unsafe { ValueRef::from_value(arg) };
        FromSql::column_result(value).map_err(|err| match err {
            FromSqlError::InvalidType => Error::InvalidFilterParameterType(idx, value.data_type()),
            FromSqlError::Other(err) => {
                Error::FromSqlConversionFailure(idx, value.data_type(), err)
            }
            FromSqlError::InvalidBlobSize { .. } => {
                Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))
            }
            FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i),
        })
    }

    // `sqlite3_value_type` returns `SQLITE_NULL` for pointer.
    // So it seems not possible to enhance `ValueRef::from_value`.
    #[cfg(feature = "array")]
    #[cfg_attr(docsrs, doc(cfg(feature = "array")))]
    fn get_array(&self, idx: usize) -> Option<array::Array> {
        use crate::types::Value;
        let arg = self.args[idx];
        let ptr = unsafe { ffi::sqlite3_value_pointer(arg, array::ARRAY_TYPE) };
        if ptr.is_null() {
            None
        } else {
            Some(unsafe {
                let rc = array::Array::from_raw(ptr as *const Vec<Value>);
                let array = rc.clone();
                array::Array::into_raw(rc); // don't consume it
                array
            })
        }
    }

    /// Turns `Values` into an iterator.
    #[inline]
    #[must_use]
    pub fn iter(&self) -> ValueIter<'_> {
        ValueIter {
            iter: self.args.iter(),
        }
    }
    // TODO sqlite3_vtab_in_first / sqlite3_vtab_in_next https://sqlite.org/c3ref/vtab_in_first.html & 3.38.0
}

impl<'a> IntoIterator for &'a Values<'a> {
    type IntoIter = ValueIter<'a>;
    type Item = ValueRef<'a>;

    #[inline]
    fn into_iter(self) -> ValueIter<'a> {
        self.iter()
    }
}

/// [`Values`] iterator.
pub struct ValueIter<'a> {
    iter: slice::Iter<'a, *mut ffi::sqlite3_value>,
}

impl<'a> Iterator for ValueIter<'a> {
    type Item = ValueRef<'a>;

    #[inline]
    fn next(&mut self) -> Option<ValueRef<'a>> {
        self.iter
            .next()
            .map(|&raw| unsafe { ValueRef::from_value(raw) })
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl Connection {
    /// Register a virtual table implementation.
    ///
    /// Step 3 of [Creating New Virtual Table
    /// Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
    #[inline]
    pub fn create_module<'vtab, T: VTab<'vtab>>(
        &self,
        module_name: &str,
        module: &'static Module<'vtab, T>,
        aux: Option<T::Aux>,
    ) -> Result<()> {
        self.db.borrow_mut().create_module(module_name, module, aux)
    }
}

impl InnerConnection {
    fn create_module<'vtab, T: VTab<'vtab>>(
        &mut self,
        module_name: &str,
        module: &'static Module<'vtab, T>,
        aux: Option<T::Aux>,
    ) -> Result<()> {
        use crate::version;
        if version::version_number() < 3_009_000 && module.base.xCreate.is_none() {
            return Err(Error::ModuleError(format!(
                "Eponymous-only virtual table not supported by SQLite version {}",
                version::version()
            )));
        }
        let c_name = str_to_cstring(module_name)?;
        let r = match aux {
            Some(aux) => {
                let boxed_aux: *mut T::Aux = Box::into_raw(Box::new(aux));
                unsafe {
                    ffi::sqlite3_create_module_v2(
                        self.db(),
                        c_name.as_ptr(),
                        &module.base,
                        boxed_aux.cast::<c_void>(),
                        Some(free_boxed_value::<T::Aux>),
                    )
                }
            }
            None => unsafe {
                ffi::sqlite3_create_module_v2(
                    self.db(),
                    c_name.as_ptr(),
                    &module.base,
                    ptr::null_mut(),
                    None,
                )
            },
        };
        self.decode_result(r)
    }
}

/// Escape double-quote (`"`) character occurrences by
/// doubling them (`""`).
#[must_use]
pub fn escape_double_quote(identifier: &str) -> Cow<'_, str> {
    if identifier.contains('"') {
        // escape quote by doubling them
        Owned(identifier.replace('"', "\"\""))
    } else {
        Borrowed(identifier)
    }
}
/// Dequote string
#[must_use]
pub fn dequote(s: &str) -> &str {
    if s.len() < 2 {
        return s;
    }
    match s.bytes().next() {
        Some(b) if b == b'"' || b == b'\'' => match s.bytes().rev().next() {
            Some(e) if e == b => &s[1..s.len() - 1], // FIXME handle inner escaped quote(s)
            _ => s,
        },
        _ => s,
    }
}
/// The boolean can be one of:
/// ```text
/// 1 yes true on
/// 0 no false off
/// ```
#[must_use]
pub fn parse_boolean(s: &str) -> Option<bool> {
    if s.eq_ignore_ascii_case("yes")
        || s.eq_ignore_ascii_case("on")
        || s.eq_ignore_ascii_case("true")
        || s.eq("1")
    {
        Some(true)
    } else if s.eq_ignore_ascii_case("no")
        || s.eq_ignore_ascii_case("off")
        || s.eq_ignore_ascii_case("false")
        || s.eq("0")
    {
        Some(false)
    } else {
        None
    }
}

/// `<param_name>=['"]?<param_value>['"]?` => `(<param_name>, <param_value>)`
pub fn parameter(c_slice: &[u8]) -> Result<(&str, &str)> {
    let arg = std::str::from_utf8(c_slice)?.trim();
    let mut split = arg.split('=');
    if let Some(key) = split.next() {
        if let Some(value) = split.next() {
            let param = key.trim();
            let value = dequote(value);
            return Ok((param, value));
        }
    }
    Err(Error::ModuleError(format!("illegal argument: '{}'", arg)))
}

// FIXME copy/paste from function.rs
unsafe extern "C" fn free_boxed_value<T>(p: *mut c_void) {
    drop(Box::from_raw(p.cast::<T>()));
}

unsafe extern "C" fn rust_create<'vtab, T>(
    db: *mut ffi::sqlite3,
    aux: *mut c_void,
    argc: c_int,
    argv: *const *const c_char,
    pp_vtab: *mut *mut ffi::sqlite3_vtab,
    err_msg: *mut *mut c_char,
) -> c_int
where
    T: CreateVTab<'vtab>,
{
    use std::ffi::CStr;

    let mut conn = VTabConnection(db);
    let aux = aux.cast::<T::Aux>();
    let args = slice::from_raw_parts(argv, argc as usize);
    let vec = args
        .iter()
        .map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error>
        .collect::<Vec<_>>();
    match T::create(&mut conn, aux.as_ref(), &vec[..]) {
        Ok((sql, vtab)) => match std::ffi::CString::new(sql) {
            Ok(c_sql) => {
                let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
                if rc == ffi::SQLITE_OK {
                    let boxed_vtab: *mut T = Box::into_raw(Box::new(vtab));
                    *pp_vtab = boxed_vtab.cast::<ffi::sqlite3_vtab>();
                    ffi::SQLITE_OK
                } else {
                    let err = error_from_sqlite_code(rc, None);
                    *err_msg = alloc(&err.to_string());
                    rc
                }
            }
            Err(err) => {
                *err_msg = alloc(&err.to_string());
                ffi::SQLITE_ERROR
            }
        },
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(s) = s {
                *err_msg = alloc(&s);
            }
            err.extended_code
        }
        Err(err) => {
            *err_msg = alloc(&err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

unsafe extern "C" fn rust_connect<'vtab, T>(
    db: *mut ffi::sqlite3,
    aux: *mut c_void,
    argc: c_int,
    argv: *const *const c_char,
    pp_vtab: *mut *mut ffi::sqlite3_vtab,
    err_msg: *mut *mut c_char,
) -> c_int
where
    T: VTab<'vtab>,
{
    use std::ffi::CStr;

    let mut conn = VTabConnection(db);
    let aux = aux.cast::<T::Aux>();
    let args = slice::from_raw_parts(argv, argc as usize);
    let vec = args
        .iter()
        .map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error>
        .collect::<Vec<_>>();
    match T::connect(&mut conn, aux.as_ref(), &vec[..]) {
        Ok((sql, vtab)) => match std::ffi::CString::new(sql) {
            Ok(c_sql) => {
                let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
                if rc == ffi::SQLITE_OK {
                    let boxed_vtab: *mut T = Box::into_raw(Box::new(vtab));
                    *pp_vtab = boxed_vtab.cast::<ffi::sqlite3_vtab>();
                    ffi::SQLITE_OK
                } else {
                    let err = error_from_sqlite_code(rc, None);
                    *err_msg = alloc(&err.to_string());
                    rc
                }
            }
            Err(err) => {
                *err_msg = alloc(&err.to_string());
                ffi::SQLITE_ERROR
            }
        },
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(s) = s {
                *err_msg = alloc(&s);
            }
            err.extended_code
        }
        Err(err) => {
            *err_msg = alloc(&err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

unsafe extern "C" fn rust_best_index<'vtab, T>(
    vtab: *mut ffi::sqlite3_vtab,
    info: *mut ffi::sqlite3_index_info,
) -> c_int
where
    T: VTab<'vtab>,
{
    let vt = vtab.cast::<T>();
    let mut idx_info = IndexInfo(info);
    match (*vt).best_index(&mut idx_info) {
        Ok(_) => ffi::SQLITE_OK,
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg(vtab, &err_msg);
            }
            err.extended_code
        }
        Err(err) => {
            set_err_msg(vtab, &err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

unsafe extern "C" fn rust_disconnect<'vtab, T>(vtab: *mut ffi::sqlite3_vtab) -> c_int
where
    T: VTab<'vtab>,
{
    if vtab.is_null() {
        return ffi::SQLITE_OK;
    }
    let vtab = vtab.cast::<T>();
    drop(Box::from_raw(vtab));
    ffi::SQLITE_OK
}

unsafe extern "C" fn rust_destroy<'vtab, T>(vtab: *mut ffi::sqlite3_vtab) -> c_int
where
    T: CreateVTab<'vtab>,
{
    if vtab.is_null() {
        return ffi::SQLITE_OK;
    }
    let vt = vtab.cast::<T>();
    match (*vt).destroy() {
        Ok(_) => {
            drop(Box::from_raw(vt));
            ffi::SQLITE_OK
        }
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg(vtab, &err_msg);
            }
            err.extended_code
        }
        Err(err) => {
            set_err_msg(vtab, &err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

unsafe extern "C" fn rust_open<'vtab, T: 'vtab>(
    vtab: *mut ffi::sqlite3_vtab,
    pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor,
) -> c_int
where
    T: VTab<'vtab>,
{
    let vt = vtab.cast::<T>();
    match (*vt).open() {
        Ok(cursor) => {
            let boxed_cursor: *mut T::Cursor = Box::into_raw(Box::new(cursor));
            *pp_cursor = boxed_cursor.cast::<ffi::sqlite3_vtab_cursor>();
            ffi::SQLITE_OK
        }
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg(vtab, &err_msg);
            }
            err.extended_code
        }
        Err(err) => {
            set_err_msg(vtab, &err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

unsafe extern "C" fn rust_close<C>(cursor: *mut ffi::sqlite3_vtab_cursor) -> c_int
where
    C: VTabCursor,
{
    let cr = cursor.cast::<C>();
    drop(Box::from_raw(cr));
    ffi::SQLITE_OK
}

unsafe extern "C" fn rust_filter<C>(
    cursor: *mut ffi::sqlite3_vtab_cursor,
    idx_num: c_int,
    idx_str: *const c_char,
    argc: c_int,
    argv: *mut *mut ffi::sqlite3_value,
) -> c_int
where
    C: VTabCursor,
{
    use std::ffi::CStr;
    use std::str;
    let idx_name = if idx_str.is_null() {
        None
    } else {
        let c_slice = CStr::from_ptr(idx_str).to_bytes();
        Some(str::from_utf8_unchecked(c_slice))
    };
    let args = slice::from_raw_parts_mut(argv, argc as usize);
    let values = Values { args };
    let cr = cursor as *mut C;
    cursor_error(cursor, (*cr).filter(idx_num, idx_name, &values))
}

unsafe extern "C" fn rust_next<C>(cursor: *mut ffi::sqlite3_vtab_cursor) -> c_int
where
    C: VTabCursor,
{
    let cr = cursor as *mut C;
    cursor_error(cursor, (*cr).next())
}

unsafe extern "C" fn rust_eof<C>(cursor: *mut ffi::sqlite3_vtab_cursor) -> c_int
where
    C: VTabCursor,
{
    let cr = cursor.cast::<C>();
    (*cr).eof() as c_int
}

unsafe extern "C" fn rust_column<C>(
    cursor: *mut ffi::sqlite3_vtab_cursor,
    ctx: *mut ffi::sqlite3_context,
    i: c_int,
) -> c_int
where
    C: VTabCursor,
{
    let cr = cursor.cast::<C>();
    let mut ctxt = Context(ctx);
    result_error(ctx, (*cr).column(&mut ctxt, i))
}

unsafe extern "C" fn rust_rowid<C>(
    cursor: *mut ffi::sqlite3_vtab_cursor,
    p_rowid: *mut ffi::sqlite3_int64,
) -> c_int
where
    C: VTabCursor,
{
    let cr = cursor.cast::<C>();
    match (*cr).rowid() {
        Ok(rowid) => {
            *p_rowid = rowid;
            ffi::SQLITE_OK
        }
        err => cursor_error(cursor, err),
    }
}

unsafe extern "C" fn rust_update<'vtab, T: 'vtab>(
    vtab: *mut ffi::sqlite3_vtab,
    argc: c_int,
    argv: *mut *mut ffi::sqlite3_value,
    p_rowid: *mut ffi::sqlite3_int64,
) -> c_int
where
    T: UpdateVTab<'vtab>,
{
    assert!(argc >= 1);
    let args = slice::from_raw_parts_mut(argv, argc as usize);
    let vt = vtab.cast::<T>();
    let r = if args.len() == 1 {
        (*vt).delete(ValueRef::from_value(args[0]))
    } else if ffi::sqlite3_value_type(args[0]) == ffi::SQLITE_NULL {
        // TODO Make the distinction between argv[1] == NULL and argv[1] != NULL ?
        let values = Values { args };
        match (*vt).insert(&values) {
            Ok(rowid) => {
                *p_rowid = rowid;
                Ok(())
            }
            Err(e) => Err(e),
        }
    } else {
        let values = Values { args };
        (*vt).update(&values)
    };
    match r {
        Ok(_) => ffi::SQLITE_OK,
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg(vtab, &err_msg);
            }
            err.extended_code
        }
        Err(err) => {
            set_err_msg(vtab, &err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

/// Virtual table cursors can set an error message by assigning a string to
/// `zErrMsg`.
#[cold]
unsafe fn cursor_error<T>(cursor: *mut ffi::sqlite3_vtab_cursor, result: Result<T>) -> c_int {
    match result {
        Ok(_) => ffi::SQLITE_OK,
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg((*cursor).pVtab, &err_msg);
            }
            err.extended_code
        }
        Err(err) => {
            set_err_msg((*cursor).pVtab, &err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

/// Virtual tables methods can set an error message by assigning a string to
/// `zErrMsg`.
#[cold]
unsafe fn set_err_msg(vtab: *mut ffi::sqlite3_vtab, err_msg: &str) {
    if !(*vtab).zErrMsg.is_null() {
        ffi::sqlite3_free((*vtab).zErrMsg.cast::<c_void>());
    }
    (*vtab).zErrMsg = alloc(err_msg);
}

/// To raise an error, the `column` method should use this method to set the
/// error message and return the error code.
#[cold]
unsafe fn result_error<T>(ctx: *mut ffi::sqlite3_context, result: Result<T>) -> c_int {
    match result {
        Ok(_) => ffi::SQLITE_OK,
        Err(Error::SqliteFailure(err, s)) => {
            match err.extended_code {
                ffi::SQLITE_TOOBIG => {
                    ffi::sqlite3_result_error_toobig(ctx);
                }
                ffi::SQLITE_NOMEM => {
                    ffi::sqlite3_result_error_nomem(ctx);
                }
                code => {
                    ffi::sqlite3_result_error_code(ctx, code);
                    if let Some(Ok(cstr)) = s.map(|s| str_to_cstring(&s)) {
                        ffi::sqlite3_result_error(ctx, cstr.as_ptr(), -1);
                    }
                }
            };
            err.extended_code
        }
        Err(err) => {
            ffi::sqlite3_result_error_code(ctx, ffi::SQLITE_ERROR);
            if let Ok(cstr) = str_to_cstring(&err.to_string()) {
                ffi::sqlite3_result_error(ctx, cstr.as_ptr(), -1);
            }
            ffi::SQLITE_ERROR
        }
    }
}

// Space to hold this string must be obtained
// from an SQLite memory allocation function
fn alloc(s: &str) -> *mut c_char {
    crate::util::SqliteMallocString::from_str(s).into_raw()
}

#[cfg(feature = "array")]
#[cfg_attr(docsrs, doc(cfg(feature = "array")))]
pub mod array;
#[cfg(feature = "csvtab")]
#[cfg_attr(docsrs, doc(cfg(feature = "csvtab")))]
pub mod csvtab;
#[cfg(feature = "series")]
#[cfg_attr(docsrs, doc(cfg(feature = "series")))]
pub mod series; // SQLite >= 3.9.0
#[cfg(test)]
mod vtablog;

#[cfg(test)]
mod test {
    #[test]
    fn test_dequote() {
        assert_eq!("", super::dequote(""));
        assert_eq!("'", super::dequote("'"));
        assert_eq!("\"", super::dequote("\""));
        assert_eq!("'\"", super::dequote("'\""));
        assert_eq!("", super::dequote("''"));
        assert_eq!("", super::dequote("\"\""));
        assert_eq!("x", super::dequote("'x'"));
        assert_eq!("x", super::dequote("\"x\""));
        assert_eq!("x", super::dequote("x"));
    }
    #[test]
    fn test_parse_boolean() {
        assert_eq!(None, super::parse_boolean(""));
        assert_eq!(Some(true), super::parse_boolean("1"));
        assert_eq!(Some(true), super::parse_boolean("yes"));
        assert_eq!(Some(true), super::parse_boolean("on"));
        assert_eq!(Some(true), super::parse_boolean("true"));
        assert_eq!(Some(false), super::parse_boolean("0"));
        assert_eq!(Some(false), super::parse_boolean("no"));
        assert_eq!(Some(false), super::parse_boolean("off"));
        assert_eq!(Some(false), super::parse_boolean("false"));
    }
}
