<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::path::{Path, PathBuf};

use devicemapper::{Bytes, DM, DmDevice, DmName, DmUuid, IEC, SECTOR_SIZE, Sectors, ThinDev,
                   ThinDevId, ThinPoolDev, ThinStatus};

use mnt::{MountIter, MountParam};
use nix::mount::{MsFlags, mount, umount};
use nix::sys::statvfs::statvfs;
use tempdir::TempDir;

use super::super::super::engine::Filesystem;
use super::super::super::errors::{EngineError, EngineResult, ErrorEnum};
use super::super::super::types::{FilesystemUuid, Name};

use super::super::serde_structs::FilesystemSave;

use super::util::{create_fs, set_uuid, xfs_growfs};

/// TODO: confirm that 256 MiB leaves enough time for stratisd to respond and extend before
/// the filesystem is out of space.
pub const FILESYSTEM_LOWATER: Sectors = Sectors(256 * IEC::Mi / (SECTOR_SIZE as u64)); // = 256 MiB

#[derive(Debug)]
pub struct StratFilesystem {
    thin_dev: ThinDev,
}

pub enum FilesystemStatus {
    Good,
    XfsGrowFailed,
    ThinDevExtendFailed,
    Failed,
}

impl StratFilesystem {
    /// Create a StratFilesystem on top of the given ThinDev.
    pub fn initialize(fs_id: FilesystemUuid, thin_dev: ThinDev) -> EngineResult<StratFilesystem> {
        let fs = StratFilesystem::setup(thin_dev);

        create_fs(&fs.devnode(), fs_id)?;
        Ok(fs)
    }

    /// Build a StratFilesystem that includes the ThinDev and related info.
    pub fn setup(thin_dev: ThinDev) -> StratFilesystem {
        StratFilesystem { thin_dev }
    }

    /// Create a snapshot of the filesystem. Return the resulting filesystem/ThinDev
    /// to the caller.  Use snapshot_name for the Stratis filesystem name.  Use
    /// snapshot_dmname for the new name of the ThinDev allocated for the snapshot.
    /// Mounting a filesystem with a duplicate UUID would require special handling,
    /// so snapshot_fs_uuid is used to update the new snapshot filesystem so it has
    /// a unique UUID.
    #[allow(too_many_arguments)]
    pub fn snapshot(&self,
                    dm: &DM,
                    thin_pool: &ThinPoolDev,
                    snapshot_name: &str,
                    snapshot_dm_name: &DmName,
                    snapshot_dm_uuid: Option<&DmUuid>,
                    snapshot_fs_name: &Name,
                    snapshot_fs_uuid: FilesystemUuid,
                    snapshot_thin_id: ThinDevId)
                    -> EngineResult<StratFilesystem> {

        match self.thin_dev
                  .snapshot(dm,
                            snapshot_dm_name,
                            snapshot_dm_uuid,
                            thin_pool,
                            snapshot_thin_id) {
            Ok(thin_dev) => {
                // If the source is mounted, XFS puts a dummy record in the
                // log to enforce replay of the snapshot to deal with any
                // orphaned inodes. The dummy record put the log in a dirty
                // state. xfs_admin won't allow a filesystem UUID
                // to be updated when the log is dirty.  To clear the log
                // we mount/unmount the filesystem before updating the UUID.
                //
                // If the source is unmounted the XFS log will be clean so
                // we can skip the mount/unmount.
                if self.get_mount_point()?.is_some() {
                    let tmp_dir = TempDir::new("stratis_mp_")?;
                    // Mount the snapshot with the "nouuid" option. mount
                    // will fail due to duplicate UUID otherwise.
                    mount(Some(&thin_dev.devnode()),
                          tmp_dir.path(),
                          Some("xfs"),
                          MsFlags::empty(),
                          Some("nouuid"))?;
                    umount(tmp_dir.path())?;
                }
                set_uuid(&thin_dev.devnode(), snapshot_fs_uuid)?;
                Ok(StratFilesystem::setup(thin_dev))
            }
            Err(e) => {
                Err(EngineError::Engine(ErrorEnum::Error,
                                        format!("failed to create {} snapshot for {} - {}",
                                                snapshot_name,
                                                snapshot_fs_name,
                                                e)))
            }
        }
    }

    /// check if filesystem is getting full and needs to be extended
    /// TODO: deal with the thindev in a Fail state.
    pub fn check(&mut self, dm: &DM) -> EngineResult<FilesystemStatus> {
        match self.thin_dev.status(dm)? {
            ThinStatus::Working(_) => {
                if let Some(mount_point) = self.get_mount_point()? {
                    let (fs_total_bytes, fs_total_used_bytes) = fs_usage(&mount_point)?;
                    let free_bytes = fs_total_bytes - fs_total_used_bytes;
                    if free_bytes.sectors() < FILESYSTEM_LOWATER {
                        let extend_size = self.extend_size(self.thin_dev.size());
                        if self.thin_dev.extend(dm, extend_size).is_err() {
                            return Ok(FilesystemStatus::ThinDevExtendFailed);
                        }
                        if xfs_growfs(&mount_point).is_err() {
                            return Ok(FilesystemStatus::XfsGrowFailed);
                        }
                    }
                }
                // TODO: do anything when filesystem is not mounted?
                // TODO: periodically kick off fstrim?
            }
            ThinStatus::Fail => return Ok(FilesystemStatus::Failed),
        }
        Ok(FilesystemStatus::Good)
    }

    /// The thin id for the thin device that backs this filesystem.
    #[cfg(test)]
    pub fn thin_id(&self) -> ThinDevId {
        self.thin_dev.id()
    }

    /// Return an extend size for the thindev under the filesystem
    /// TODO: returning the current size will double the space provisioned to
    /// the thin device.  We should determine if this is a reasonable value.
    fn extend_size(&self, current_size: Sectors) -> Sectors {
        current_size
    }

    /// Get one (non-deterministic in the presence of errors) of the mount_point(s) for the file
    /// system that is contained on the block device referred to as self.devnode(), i.e. the device
    /// node, while ignoring parse errors as long as at least one mount point is found.
    pub fn get_mount_point(&self) -> EngineResult<Option<PathBuf>> {
        let device_node = self.devnode();
        let search = device_node.to_str().ok_or_else(|| EngineError::Engine(ErrorEnum::Error,
                                    format!("Unable to represent devnode as string {:?}", *self)))?;

        let m_iter = MountIter::new_from_proc()
            .map_err(|e| {
                         EngineError::Engine(ErrorEnum::Error,
                                             format!("Error reading /proc/mounts {:?}", e))
                     })?;

        let mut last_error: Option<String> = None;
        for mp in m_iter {
            match mp {
                Ok(mount) => {
                    if mount.contains(&MountParam::Spec(search)) {
                        return Ok(Some(mount.file));
                    }
                }
                Err(e) => {
                    last_error = Some(format!("Error during parsing {:?} {:?}", *self, e));
                }
            }
        }

        last_error.map_or(Ok(None), |e| Err(EngineError::Engine(ErrorEnum::Error, e)))
    }

    /// Tear down the filesystem.
    pub fn teardown(self, dm: &DM) -> EngineResult<()> {
        self.thin_dev.teardown(dm)?;
        Ok(())
    }

    /// Destroy the filesystem.
    pub fn destroy(self, dm: &DM, thin_pool: &ThinPoolDev) -> EngineResult<()> {
        self.thin_dev.destroy(dm, thin_pool)?;
        Ok(())
    }

    pub fn record(&self, name: &Name, uuid: FilesystemUuid) -> FilesystemSave {
        FilesystemSave {
            name: name.to_owned(),
            uuid: uuid,
            thin_id: self.thin_dev.id(),
            size: self.thin_dev.size(),
        }
    }
}

impl Filesystem for StratFilesystem {
    fn devnode(&self) -> PathBuf {
        self.thin_dev.devnode()
    }
}

/// Return total bytes allocated to the filesystem, total bytes used by data/metadata
pub fn fs_usage(mount_point: &Path) -> EngineResult<(Bytes, Bytes)> {
    let stat = statvfs(mount_point)?;

    // stat.block_size() is type c_ulong, which is 32 bits on some archs.
    // Upcast to u64.
    let f_bsize = stat.block_size() as u64;

    let blocks = stat.blocks();
    Ok((Bytes(f_bsize * blocks), Bytes(f_bsize * (blocks - stat.blocks_free()))))
}
<commit_msg>Fix redundant-field-names clippy error<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::path::{Path, PathBuf};

use devicemapper::{Bytes, DM, DmDevice, DmName, DmUuid, IEC, SECTOR_SIZE, Sectors, ThinDev,
                   ThinDevId, ThinPoolDev, ThinStatus};

use mnt::{MountIter, MountParam};
use nix::mount::{MsFlags, mount, umount};
use nix::sys::statvfs::statvfs;
use tempdir::TempDir;

use super::super::super::engine::Filesystem;
use super::super::super::errors::{EngineError, EngineResult, ErrorEnum};
use super::super::super::types::{FilesystemUuid, Name};

use super::super::serde_structs::FilesystemSave;

use super::util::{create_fs, set_uuid, xfs_growfs};

/// TODO: confirm that 256 MiB leaves enough time for stratisd to respond and extend before
/// the filesystem is out of space.
pub const FILESYSTEM_LOWATER: Sectors = Sectors(256 * IEC::Mi / (SECTOR_SIZE as u64)); // = 256 MiB

#[derive(Debug)]
pub struct StratFilesystem {
    thin_dev: ThinDev,
}

pub enum FilesystemStatus {
    Good,
    XfsGrowFailed,
    ThinDevExtendFailed,
    Failed,
}

impl StratFilesystem {
    /// Create a StratFilesystem on top of the given ThinDev.
    pub fn initialize(fs_id: FilesystemUuid, thin_dev: ThinDev) -> EngineResult<StratFilesystem> {
        let fs = StratFilesystem::setup(thin_dev);

        create_fs(&fs.devnode(), fs_id)?;
        Ok(fs)
    }

    /// Build a StratFilesystem that includes the ThinDev and related info.
    pub fn setup(thin_dev: ThinDev) -> StratFilesystem {
        StratFilesystem { thin_dev }
    }

    /// Create a snapshot of the filesystem. Return the resulting filesystem/ThinDev
    /// to the caller.  Use snapshot_name for the Stratis filesystem name.  Use
    /// snapshot_dmname for the new name of the ThinDev allocated for the snapshot.
    /// Mounting a filesystem with a duplicate UUID would require special handling,
    /// so snapshot_fs_uuid is used to update the new snapshot filesystem so it has
    /// a unique UUID.
    #[allow(too_many_arguments)]
    pub fn snapshot(&self,
                    dm: &DM,
                    thin_pool: &ThinPoolDev,
                    snapshot_name: &str,
                    snapshot_dm_name: &DmName,
                    snapshot_dm_uuid: Option<&DmUuid>,
                    snapshot_fs_name: &Name,
                    snapshot_fs_uuid: FilesystemUuid,
                    snapshot_thin_id: ThinDevId)
                    -> EngineResult<StratFilesystem> {

        match self.thin_dev
                  .snapshot(dm,
                            snapshot_dm_name,
                            snapshot_dm_uuid,
                            thin_pool,
                            snapshot_thin_id) {
            Ok(thin_dev) => {
                // If the source is mounted, XFS puts a dummy record in the
                // log to enforce replay of the snapshot to deal with any
                // orphaned inodes. The dummy record put the log in a dirty
                // state. xfs_admin won't allow a filesystem UUID
                // to be updated when the log is dirty.  To clear the log
                // we mount/unmount the filesystem before updating the UUID.
                //
                // If the source is unmounted the XFS log will be clean so
                // we can skip the mount/unmount.
                if self.get_mount_point()?.is_some() {
                    let tmp_dir = TempDir::new("stratis_mp_")?;
                    // Mount the snapshot with the "nouuid" option. mount
                    // will fail due to duplicate UUID otherwise.
                    mount(Some(&thin_dev.devnode()),
                          tmp_dir.path(),
                          Some("xfs"),
                          MsFlags::empty(),
                          Some("nouuid"))?;
                    umount(tmp_dir.path())?;
                }
                set_uuid(&thin_dev.devnode(), snapshot_fs_uuid)?;
                Ok(StratFilesystem::setup(thin_dev))
            }
            Err(e) => {
                Err(EngineError::Engine(ErrorEnum::Error,
                                        format!("failed to create {} snapshot for {} - {}",
                                                snapshot_name,
                                                snapshot_fs_name,
                                                e)))
            }
        }
    }

    /// check if filesystem is getting full and needs to be extended
    /// TODO: deal with the thindev in a Fail state.
    pub fn check(&mut self, dm: &DM) -> EngineResult<FilesystemStatus> {
        match self.thin_dev.status(dm)? {
            ThinStatus::Working(_) => {
                if let Some(mount_point) = self.get_mount_point()? {
                    let (fs_total_bytes, fs_total_used_bytes) = fs_usage(&mount_point)?;
                    let free_bytes = fs_total_bytes - fs_total_used_bytes;
                    if free_bytes.sectors() < FILESYSTEM_LOWATER {
                        let extend_size = self.extend_size(self.thin_dev.size());
                        if self.thin_dev.extend(dm, extend_size).is_err() {
                            return Ok(FilesystemStatus::ThinDevExtendFailed);
                        }
                        if xfs_growfs(&mount_point).is_err() {
                            return Ok(FilesystemStatus::XfsGrowFailed);
                        }
                    }
                }
                // TODO: do anything when filesystem is not mounted?
                // TODO: periodically kick off fstrim?
            }
            ThinStatus::Fail => return Ok(FilesystemStatus::Failed),
        }
        Ok(FilesystemStatus::Good)
    }

    /// The thin id for the thin device that backs this filesystem.
    #[cfg(test)]
    pub fn thin_id(&self) -> ThinDevId {
        self.thin_dev.id()
    }

    /// Return an extend size for the thindev under the filesystem
    /// TODO: returning the current size will double the space provisioned to
    /// the thin device.  We should determine if this is a reasonable value.
    fn extend_size(&self, current_size: Sectors) -> Sectors {
        current_size
    }

    /// Get one (non-deterministic in the presence of errors) of the mount_point(s) for the file
    /// system that is contained on the block device referred to as self.devnode(), i.e. the device
    /// node, while ignoring parse errors as long as at least one mount point is found.
    pub fn get_mount_point(&self) -> EngineResult<Option<PathBuf>> {
        let device_node = self.devnode();
        let search = device_node.to_str().ok_or_else(|| EngineError::Engine(ErrorEnum::Error,
                                    format!("Unable to represent devnode as string {:?}", *self)))?;

        let m_iter = MountIter::new_from_proc()
            .map_err(|e| {
                         EngineError::Engine(ErrorEnum::Error,
                                             format!("Error reading /proc/mounts {:?}", e))
                     })?;

        let mut last_error: Option<String> = None;
        for mp in m_iter {
            match mp {
                Ok(mount) => {
                    if mount.contains(&MountParam::Spec(search)) {
                        return Ok(Some(mount.file));
                    }
                }
                Err(e) => {
                    last_error = Some(format!("Error during parsing {:?} {:?}", *self, e));
                }
            }
        }

        last_error.map_or(Ok(None), |e| Err(EngineError::Engine(ErrorEnum::Error, e)))
    }

    /// Tear down the filesystem.
    pub fn teardown(self, dm: &DM) -> EngineResult<()> {
        self.thin_dev.teardown(dm)?;
        Ok(())
    }

    /// Destroy the filesystem.
    pub fn destroy(self, dm: &DM, thin_pool: &ThinPoolDev) -> EngineResult<()> {
        self.thin_dev.destroy(dm, thin_pool)?;
        Ok(())
    }

    pub fn record(&self, name: &Name, uuid: FilesystemUuid) -> FilesystemSave {
        FilesystemSave {
            name: name.to_owned(),
            uuid,
            thin_id: self.thin_dev.id(),
            size: self.thin_dev.size(),
        }
    }
}

impl Filesystem for StratFilesystem {
    fn devnode(&self) -> PathBuf {
        self.thin_dev.devnode()
    }
}

/// Return total bytes allocated to the filesystem, total bytes used by data/metadata
pub fn fs_usage(mount_point: &Path) -> EngineResult<(Bytes, Bytes)> {
    let stat = statvfs(mount_point)?;

    // stat.block_size() is type c_ulong, which is 32 bits on some archs.
    // Upcast to u64.
    let f_bsize = stat.block_size() as u64;

    let blocks = stat.blocks();
    Ok((Bytes(f_bsize * blocks), Bytes(f_bsize * (blocks - stat.blocks_free()))))
}
<|endoftext|>


<commit_before>use std::any::*;

use backend::Backend;
use expression::{Expression, NonAggregate, SelectableExpression};
use expression::operators::Eq;
use insertable::*;
#[cfg(feature = "mysql")]
use mysql::Mysql;
use query_builder::*;
#[cfg(feature = "sqlite")]
use query_dsl::methods::ExecuteDsl;
use query_dsl::RunQueryDsl;
use query_source::{Column, Table};
use result::QueryResult;
#[cfg(feature = "sqlite")]
use sqlite::{Sqlite, SqliteConnection};
use super::returning_clause::*;

/// The structure returned by [`insert_into`].
///
/// The provided methods [`values`] and [`default_values`] will insert
/// data into the targeted table.
///
/// [`insert_into`]: ../fn.insert_into.html
/// [`values`]: #method.values
/// [`default_values`]: #method.default_values
#[derive(Debug, Clone, Copy)]
pub struct IncompleteInsertStatement<T, Op> {
    target: T,
    operator: Op,
}

impl<T, Op> IncompleteInsertStatement<T, Op> {
    pub(crate) fn new(target: T, operator: Op) -> Self {
        IncompleteInsertStatement { target, operator }
    }

    /// Inserts `DEFAULT VALUES` into the targeted table.
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("../doctest_setup.rs");
    /// #
    /// # table! {
    /// #     users (name) {
    /// #         name -> Text,
    /// #         hair_color -> Text,
    /// #     }
    /// # }
    /// #
    /// # fn main() {
    /// #     run_test();
    /// # }
    /// #
    /// # fn run_test() -> QueryResult<()> {
    /// #     use diesel::insert_into;
    /// #     use users::dsl::*;
    /// #     let connection = connection_no_data();
    /// connection.execute("CREATE TABLE users (
    ///     name VARCHAR(255) NOT NULL DEFAULT 'Sean',
    ///     hair_color VARCHAR(255) NOT NULL DEFAULT 'Green'
    /// )")?;
    ///
    /// insert_into(users)
    ///     .default_values()
    ///     .execute(&connection)
    ///     .unwrap();
    /// let inserted_user = users.first(&connection)?;
    /// let expected_data = (String::from("Sean"), String::from("Green"));
    ///
    /// assert_eq!(expected_data, inserted_user);
    /// #     Ok(())
    /// # }
    /// ```
    pub fn default_values(self) -> InsertStatement<T, DefaultValues, Op> {
        static STATIC_DEFAULT_VALUES: &DefaultValues = &DefaultValues;
        self.values(STATIC_DEFAULT_VALUES)
    }

    /// Inserts the given values into the table passed to `insert_into`.
    ///
    /// See the documentation of [`insert_into`] for
    /// usage examples.
    ///
    /// This method can sometimes produce extremely opaque error messages due to
    /// limitations of the Rust language. If you receive an error about
    /// "overflow evaluating requirement" as a result of calling this method,
    /// you may need an `&` in front of the argument to this method.
    ///
    /// [`insert_into`]: ../fn.insert_into.html
    pub fn values<U>(self, records: U) -> InsertStatement<T, U::Values, Op>
    where
        U: Insertable<T>,
    {
        InsertStatement::new(
            self.target,
            records.values(),
            self.operator,
            NoReturningClause,
        )
    }
}

#[derive(Debug, Copy, Clone)]
/// A fully constructed insert statement.
///
/// The parameters of this struct represent:
///
/// - `T`: The table we are inserting into
/// - `U`: The data being inserted
/// - `Op`: The operation being performed. The specific types used to represent
///   this are private, but correspond to SQL such as `INSERT` or `REPLACE`.
///   You can safely rely on the default type representing `INSERT`
/// - `Ret`: The `RETURNING` clause of the query. The specific types used to
///   represent this are private. You can safely rely on the default type
///   representing a query without a `RETURNING` clause.
pub struct InsertStatement<T, U, Op = Insert, Ret = NoReturningClause> {
    operator: Op,
    target: T,
    records: U,
    returning: Ret,
}

impl<T, U, Op, Ret> InsertStatement<T, U, Op, Ret> {
    fn new(target: T, records: U, operator: Op, returning: Ret) -> Self {
        InsertStatement {
            operator: operator,
            target: target,
            records: records,
            returning: returning,
        }
    }

    #[cfg(feature = "postgres")]
    pub(crate) fn replace_values<F, V>(self, f: F) -> InsertStatement<T, V, Op, Ret>
    where
        F: FnOnce(U) -> V,
    {
        InsertStatement::new(self.target, f(self.records), self.operator, self.returning)
    }
}

impl<T, U, Op, Ret, DB> QueryFragment<DB> for InsertStatement<T, U, Op, Ret>
where
    DB: Backend,
    T: Table,
    T::FromClause: QueryFragment<DB>,
    U: InsertValues<T, DB> + CanInsertInSingleQuery<DB>,
    Op: QueryFragment<DB>,
    Ret: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();

        if self.records.rows_to_insert() == 0 {
            out.push_sql("SELECT 1 FROM ");
            self.target.from_clause().walk_ast(out.reborrow())?;
            out.push_sql(" WHERE 1=0");
            return Ok(());
        }

        self.operator.walk_ast(out.reborrow())?;
        out.push_sql(" INTO ");
        self.target.from_clause().walk_ast(out.reborrow())?;
        if self.records.is_noop() {
            out.push_sql(" DEFAULT VALUES");
        } else {
            out.push_sql(" (");
            self.records.column_names(out.reborrow())?;
            out.push_sql(") VALUES ");
            self.records.walk_ast(out.reborrow())?;
        }
        self.returning.walk_ast(out.reborrow())?;
        Ok(())
    }
}

#[cfg(feature = "sqlite")]
impl<'a, T, U, Op> ExecuteDsl<SqliteConnection> for InsertStatement<T, &'a [U], Op>
where
    &'a U: Insertable<T>,
    InsertStatement<T, <&'a U as Insertable<T>>::Values, Op>: QueryFragment<Sqlite>,
    T: Copy,
    Op: Copy,
{
    fn execute(query: Self, conn: &SqliteConnection) -> QueryResult<usize> {
        use connection::Connection;
        conn.transaction(|| {
            let mut result = 0;
            for record in query.records {
                result += InsertStatement::new(
                    query.target,
                    record.values(),
                    query.operator,
                    query.returning,
                ).execute(conn)?;
            }
            Ok(result)
        })
    }
}

impl<T, U, Op, Ret> QueryId for InsertStatement<T, U, Op, Ret> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<T, U, Op> AsQuery for InsertStatement<T, U, Op, NoReturningClause>
where
    T: Table,
    InsertStatement<T, U, Op, ReturningClause<T::AllColumns>>: Query,
{
    type SqlType = <Self::Query as Query>::SqlType;
    type Query = InsertStatement<T, U, Op, ReturningClause<T::AllColumns>>;

    fn as_query(self) -> Self::Query {
        self.returning(T::all_columns())
    }
}

impl<T, U, Op, Ret> Query for InsertStatement<T, U, Op, ReturningClause<Ret>>
where
    Ret: Expression + SelectableExpression<T> + NonAggregate,
{
    type SqlType = Ret::SqlType;
}

impl<T, U, Op, Ret, Conn> RunQueryDsl<Conn> for InsertStatement<T, U, Op, Ret> {}

impl<T, U, Op> InsertStatement<T, U, Op> {
    /// Specify what expression is returned after execution of the `insert`.
    /// # Examples
    ///
    /// ### Inserting records:
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("../doctest_setup.rs");
    /// #
    /// # #[cfg(feature = "postgres")]
    /// # fn main() {
    /// #     use schema::users::dsl::*;
    /// #     let connection = establish_connection();
    /// let inserted_names = diesel::insert_into(users)
    ///     .values(&vec![name.eq("Timmy"), name.eq("Jimmy")])
    ///     .returning(name)
    ///     .get_results(&connection);
    /// assert_eq!(Ok(vec!["Timmy".to_string(), "Jimmy".to_string()]), inserted_names);
    /// # }
    /// # #[cfg(not(feature = "postgres"))]
    /// # fn main() {}
    /// ```
    pub fn returning<E>(self, returns: E) -> InsertStatement<T, U, Op, ReturningClause<E>>
    where
        InsertStatement<T, U, Op, ReturningClause<E>>: Query,
    {
        InsertStatement::new(
            self.target,
            self.records,
            self.operator,
            ReturningClause(returns),
        )
    }
}

#[derive(Debug, Copy, Clone, QueryId)]
#[doc(hidden)]
pub struct Insert;

impl<DB: Backend> QueryFragment<DB> for Insert {
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql("INSERT");
        Ok(())
    }
}

#[derive(Debug, Copy, Clone, QueryId)]
#[doc(hidden)]
pub struct InsertOrIgnore;

#[cfg(feature = "sqlite")]
impl QueryFragment<Sqlite> for InsertOrIgnore {
    fn walk_ast(&self, mut out: AstPass<Sqlite>) -> QueryResult<()> {
        out.push_sql("INSERT OR IGNORE");
        Ok(())
    }
}

#[cfg(feature = "mysql")]
impl QueryFragment<Mysql> for InsertOrIgnore {
    fn walk_ast(&self, mut out: AstPass<Mysql>) -> QueryResult<()> {
        out.push_sql("INSERT IGNORE");
        Ok(())
    }
}

#[derive(Debug, Copy, Clone)]
#[doc(hidden)]
pub struct Replace;

#[cfg(feature = "sqlite")]
impl QueryFragment<Sqlite> for Replace {
    fn walk_ast(&self, mut out: AstPass<Sqlite>) -> QueryResult<()> {
        out.push_sql("REPLACE");
        Ok(())
    }
}

#[cfg(feature = "mysql")]
impl QueryFragment<Mysql> for Replace {
    fn walk_ast(&self, mut out: AstPass<Mysql>) -> QueryResult<()> {
        out.push_sql("REPLACE");
        Ok(())
    }
}

/// Marker trait to indicate that no additional operations have been added
/// to a record for insert.
///
/// This is used to prevent things like
/// `.on_conflict_do_nothing().on_conflict_do_nothing()`
/// from compiling.
pub trait UndecoratedInsertRecord<Table> {}

impl<'a, T, Tab> UndecoratedInsertRecord<Tab> for &'a T
where
    T: ?Sized + UndecoratedInsertRecord<Tab>,
{
}

impl<T, U> UndecoratedInsertRecord<T::Table> for ColumnInsertValue<T, U>
where
    T: Column,
{
}

impl<T, Table> UndecoratedInsertRecord<Table> for [T]
where
    T: UndecoratedInsertRecord<Table>,
{
}

impl<T, Table> UndecoratedInsertRecord<Table> for Vec<T>
where
    [T]: UndecoratedInsertRecord<Table>,
{
}

impl<Lhs, Rhs> UndecoratedInsertRecord<Lhs::Table> for Eq<Lhs, Rhs>
where
    Lhs: Column,
{
}

impl<Lhs, Rhs, Tab> UndecoratedInsertRecord<Tab> for Option<Eq<Lhs, Rhs>>
where
    Eq<Lhs, Rhs>: UndecoratedInsertRecord<Tab>,
{
}

#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct DefaultValues;

impl<DB: Backend> CanInsertInSingleQuery<DB> for DefaultValues {
    fn rows_to_insert(&self) -> usize {
        1
    }
}

impl<'a, Tab> Insertable<Tab> for &'a DefaultValues {
    type Values = DefaultValues;

    fn values(self) -> Self::Values {
        *self
    }
}

impl<Tab, DB> InsertValues<Tab, DB> for DefaultValues
where
    Tab: Table,
    DB: Backend + Any,
{
    fn column_names(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }

    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }

    #[cfg(not(feature = "mysql"))]
    fn is_noop(&self) -> bool {
        true
    }

    #[cfg(feature = "mysql")]
    fn is_noop(&self) -> bool {
        // The syntax for this on MySQL is
        // INSERT INTO table () VALUES ()
        //
        // This is hacky, but it's the easiest way to get this done without a
        // deeper restructuring of this code.
        TypeId::of::<DB>() != TypeId::of::<::mysql::Mysql>()
    }
}
<commit_msg>Fix `DefaultValues` on MySQL<commit_after>use std::any::*;

use backend::Backend;
use expression::{Expression, NonAggregate, SelectableExpression};
use expression::operators::Eq;
use insertable::*;
#[cfg(feature = "mysql")]
use mysql::Mysql;
use query_builder::*;
#[cfg(feature = "sqlite")]
use query_dsl::methods::ExecuteDsl;
use query_dsl::RunQueryDsl;
use query_source::{Column, Table};
use result::QueryResult;
#[cfg(feature = "sqlite")]
use sqlite::{Sqlite, SqliteConnection};
use super::returning_clause::*;

/// The structure returned by [`insert_into`].
///
/// The provided methods [`values`] and [`default_values`] will insert
/// data into the targeted table.
///
/// [`insert_into`]: ../fn.insert_into.html
/// [`values`]: #method.values
/// [`default_values`]: #method.default_values
#[derive(Debug, Clone, Copy)]
pub struct IncompleteInsertStatement<T, Op> {
    target: T,
    operator: Op,
}

impl<T, Op> IncompleteInsertStatement<T, Op> {
    pub(crate) fn new(target: T, operator: Op) -> Self {
        IncompleteInsertStatement { target, operator }
    }

    /// Inserts `DEFAULT VALUES` into the targeted table.
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("../doctest_setup.rs");
    /// #
    /// # table! {
    /// #     users (name) {
    /// #         name -> Text,
    /// #         hair_color -> Text,
    /// #     }
    /// # }
    /// #
    /// # fn main() {
    /// #     run_test();
    /// # }
    /// #
    /// # fn run_test() -> QueryResult<()> {
    /// #     use diesel::insert_into;
    /// #     use users::dsl::*;
    /// #     let connection = connection_no_data();
    /// connection.execute("CREATE TABLE users (
    ///     name VARCHAR(255) NOT NULL DEFAULT 'Sean',
    ///     hair_color VARCHAR(255) NOT NULL DEFAULT 'Green'
    /// )")?;
    ///
    /// insert_into(users)
    ///     .default_values()
    ///     .execute(&connection)
    ///     .unwrap();
    /// let inserted_user = users.first(&connection)?;
    /// let expected_data = (String::from("Sean"), String::from("Green"));
    ///
    /// assert_eq!(expected_data, inserted_user);
    /// #     Ok(())
    /// # }
    /// ```
    pub fn default_values(self) -> InsertStatement<T, DefaultValues, Op> {
        static STATIC_DEFAULT_VALUES: &DefaultValues = &DefaultValues;
        self.values(STATIC_DEFAULT_VALUES)
    }

    /// Inserts the given values into the table passed to `insert_into`.
    ///
    /// See the documentation of [`insert_into`] for
    /// usage examples.
    ///
    /// This method can sometimes produce extremely opaque error messages due to
    /// limitations of the Rust language. If you receive an error about
    /// "overflow evaluating requirement" as a result of calling this method,
    /// you may need an `&` in front of the argument to this method.
    ///
    /// [`insert_into`]: ../fn.insert_into.html
    pub fn values<U>(self, records: U) -> InsertStatement<T, U::Values, Op>
    where
        U: Insertable<T>,
    {
        InsertStatement::new(
            self.target,
            records.values(),
            self.operator,
            NoReturningClause,
        )
    }
}

#[derive(Debug, Copy, Clone)]
/// A fully constructed insert statement.
///
/// The parameters of this struct represent:
///
/// - `T`: The table we are inserting into
/// - `U`: The data being inserted
/// - `Op`: The operation being performed. The specific types used to represent
///   this are private, but correspond to SQL such as `INSERT` or `REPLACE`.
///   You can safely rely on the default type representing `INSERT`
/// - `Ret`: The `RETURNING` clause of the query. The specific types used to
///   represent this are private. You can safely rely on the default type
///   representing a query without a `RETURNING` clause.
pub struct InsertStatement<T, U, Op = Insert, Ret = NoReturningClause> {
    operator: Op,
    target: T,
    records: U,
    returning: Ret,
}

impl<T, U, Op, Ret> InsertStatement<T, U, Op, Ret> {
    fn new(target: T, records: U, operator: Op, returning: Ret) -> Self {
        InsertStatement {
            operator: operator,
            target: target,
            records: records,
            returning: returning,
        }
    }

    #[cfg(feature = "postgres")]
    pub(crate) fn replace_values<F, V>(self, f: F) -> InsertStatement<T, V, Op, Ret>
    where
        F: FnOnce(U) -> V,
    {
        InsertStatement::new(self.target, f(self.records), self.operator, self.returning)
    }
}

impl<T, U, Op, Ret, DB> QueryFragment<DB> for InsertStatement<T, U, Op, Ret>
where
    DB: Backend,
    T: Table,
    T::FromClause: QueryFragment<DB>,
    U: InsertValues<T, DB> + CanInsertInSingleQuery<DB>,
    Op: QueryFragment<DB>,
    Ret: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();

        if self.records.rows_to_insert() == 0 {
            out.push_sql("SELECT 1 FROM ");
            self.target.from_clause().walk_ast(out.reborrow())?;
            out.push_sql(" WHERE 1=0");
            return Ok(());
        }

        self.operator.walk_ast(out.reborrow())?;
        out.push_sql(" INTO ");
        self.target.from_clause().walk_ast(out.reborrow())?;
        if self.records.is_noop() {
            out.push_sql(" DEFAULT VALUES");
        } else {
            out.push_sql(" (");
            self.records.column_names(out.reborrow())?;
            out.push_sql(") VALUES ");
            self.records.walk_ast(out.reborrow())?;
        }
        self.returning.walk_ast(out.reborrow())?;
        Ok(())
    }
}

#[cfg(feature = "sqlite")]
impl<'a, T, U, Op> ExecuteDsl<SqliteConnection> for InsertStatement<T, &'a [U], Op>
where
    &'a U: Insertable<T>,
    InsertStatement<T, <&'a U as Insertable<T>>::Values, Op>: QueryFragment<Sqlite>,
    T: Copy,
    Op: Copy,
{
    fn execute(query: Self, conn: &SqliteConnection) -> QueryResult<usize> {
        use connection::Connection;
        conn.transaction(|| {
            let mut result = 0;
            for record in query.records {
                result += InsertStatement::new(
                    query.target,
                    record.values(),
                    query.operator,
                    query.returning,
                ).execute(conn)?;
            }
            Ok(result)
        })
    }
}

impl<T, U, Op, Ret> QueryId for InsertStatement<T, U, Op, Ret> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<T, U, Op> AsQuery for InsertStatement<T, U, Op, NoReturningClause>
where
    T: Table,
    InsertStatement<T, U, Op, ReturningClause<T::AllColumns>>: Query,
{
    type SqlType = <Self::Query as Query>::SqlType;
    type Query = InsertStatement<T, U, Op, ReturningClause<T::AllColumns>>;

    fn as_query(self) -> Self::Query {
        self.returning(T::all_columns())
    }
}

impl<T, U, Op, Ret> Query for InsertStatement<T, U, Op, ReturningClause<Ret>>
where
    Ret: Expression + SelectableExpression<T> + NonAggregate,
{
    type SqlType = Ret::SqlType;
}

impl<T, U, Op, Ret, Conn> RunQueryDsl<Conn> for InsertStatement<T, U, Op, Ret> {}

impl<T, U, Op> InsertStatement<T, U, Op> {
    /// Specify what expression is returned after execution of the `insert`.
    /// # Examples
    ///
    /// ### Inserting records:
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("../doctest_setup.rs");
    /// #
    /// # #[cfg(feature = "postgres")]
    /// # fn main() {
    /// #     use schema::users::dsl::*;
    /// #     let connection = establish_connection();
    /// let inserted_names = diesel::insert_into(users)
    ///     .values(&vec![name.eq("Timmy"), name.eq("Jimmy")])
    ///     .returning(name)
    ///     .get_results(&connection);
    /// assert_eq!(Ok(vec!["Timmy".to_string(), "Jimmy".to_string()]), inserted_names);
    /// # }
    /// # #[cfg(not(feature = "postgres"))]
    /// # fn main() {}
    /// ```
    pub fn returning<E>(self, returns: E) -> InsertStatement<T, U, Op, ReturningClause<E>>
    where
        InsertStatement<T, U, Op, ReturningClause<E>>: Query,
    {
        InsertStatement::new(
            self.target,
            self.records,
            self.operator,
            ReturningClause(returns),
        )
    }
}

#[derive(Debug, Copy, Clone, QueryId)]
#[doc(hidden)]
pub struct Insert;

impl<DB: Backend> QueryFragment<DB> for Insert {
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql("INSERT");
        Ok(())
    }
}

#[derive(Debug, Copy, Clone, QueryId)]
#[doc(hidden)]
pub struct InsertOrIgnore;

#[cfg(feature = "sqlite")]
impl QueryFragment<Sqlite> for InsertOrIgnore {
    fn walk_ast(&self, mut out: AstPass<Sqlite>) -> QueryResult<()> {
        out.push_sql("INSERT OR IGNORE");
        Ok(())
    }
}

#[cfg(feature = "mysql")]
impl QueryFragment<Mysql> for InsertOrIgnore {
    fn walk_ast(&self, mut out: AstPass<Mysql>) -> QueryResult<()> {
        out.push_sql("INSERT IGNORE");
        Ok(())
    }
}

#[derive(Debug, Copy, Clone)]
#[doc(hidden)]
pub struct Replace;

#[cfg(feature = "sqlite")]
impl QueryFragment<Sqlite> for Replace {
    fn walk_ast(&self, mut out: AstPass<Sqlite>) -> QueryResult<()> {
        out.push_sql("REPLACE");
        Ok(())
    }
}

#[cfg(feature = "mysql")]
impl QueryFragment<Mysql> for Replace {
    fn walk_ast(&self, mut out: AstPass<Mysql>) -> QueryResult<()> {
        out.push_sql("REPLACE");
        Ok(())
    }
}

/// Marker trait to indicate that no additional operations have been added
/// to a record for insert.
///
/// This is used to prevent things like
/// `.on_conflict_do_nothing().on_conflict_do_nothing()`
/// from compiling.
pub trait UndecoratedInsertRecord<Table> {}

impl<'a, T, Tab> UndecoratedInsertRecord<Tab> for &'a T
where
    T: ?Sized + UndecoratedInsertRecord<Tab>,
{
}

impl<T, U> UndecoratedInsertRecord<T::Table> for ColumnInsertValue<T, U>
where
    T: Column,
{
}

impl<T, Table> UndecoratedInsertRecord<Table> for [T]
where
    T: UndecoratedInsertRecord<Table>,
{
}

impl<T, Table> UndecoratedInsertRecord<Table> for Vec<T>
where
    [T]: UndecoratedInsertRecord<Table>,
{
}

impl<Lhs, Rhs> UndecoratedInsertRecord<Lhs::Table> for Eq<Lhs, Rhs>
where
    Lhs: Column,
{
}

impl<Lhs, Rhs, Tab> UndecoratedInsertRecord<Tab> for Option<Eq<Lhs, Rhs>>
where
    Eq<Lhs, Rhs>: UndecoratedInsertRecord<Tab>,
{
}

#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct DefaultValues;

impl<DB: Backend> CanInsertInSingleQuery<DB> for DefaultValues {
    fn rows_to_insert(&self) -> usize {
        1
    }
}

impl<'a, Tab> Insertable<Tab> for &'a DefaultValues {
    type Values = DefaultValues;

    fn values(self) -> Self::Values {
        *self
    }
}

impl<Tab, DB> InsertValues<Tab, DB> for DefaultValues
where
    Tab: Table,
    DB: Backend + Any,
{
    fn column_names(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }

    #[cfg(not(feature = "mysql"))]
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }

    #[cfg(feature = "mysql")]
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        // The syntax for this on MySQL is
        // INSERT INTO table () VALUES ()
        //
        // This is hacky, but it's the easiest way to get this done without a
        // deeper restructuring of this code (which is in progress, but ugly at some mid-points...)
        if TypeId::of::<DB>() == TypeId::of::<::mysql::Mysql>() {
            out.push_sql("()");
        }
        Ok(())
    }

    #[cfg(not(feature = "mysql"))]
    fn is_noop(&self) -> bool {
        true
    }

    #[cfg(feature = "mysql")]
    fn is_noop(&self) -> bool {
        // The syntax for this on MySQL is
        // INSERT INTO table () VALUES ()
        //
        // This is hacky, but it's the easiest way to get this done without a
        // deeper restructuring of this code.
        TypeId::of::<DB>() != TypeId::of::<::mysql::Mysql>()
    }
}
<|endoftext|>


<commit_before>use std::any::*;

use backend::Backend;
use expression::{Expression, NonAggregate, SelectableExpression};
use expression::operators::Eq;
use insertable::*;
#[cfg(feature = "mysql")]
use mysql::Mysql;
use query_builder::*;
#[cfg(feature = "sqlite")]
use query_dsl::methods::ExecuteDsl;
use query_dsl::RunQueryDsl;
use query_source::{Column, Table};
use result::QueryResult;
#[cfg(feature = "sqlite")]
use sqlite::{Sqlite, SqliteConnection};
use super::returning_clause::*;

/// The structure returned by [`insert_into`].
///
/// The provided methods [`values`] and [`default_values`] will insert
/// data into the targeted table.
///
/// [`insert_into`]: ../fn.insert_into.html
/// [`values`]: #method.values
/// [`default_values`]: #method.default_values
#[derive(Debug, Clone, Copy)]
pub struct IncompleteInsertStatement<T, Op> {
    target: T,
    operator: Op,
}

impl<T, Op> IncompleteInsertStatement<T, Op> {
    pub(crate) fn new(target: T, operator: Op) -> Self {
        IncompleteInsertStatement { target, operator }
    }

    /// Inserts `DEFAULT VALUES` into the targeted table.
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("../doctest_setup.rs");
    /// #
    /// # table! {
    /// #     users (name) {
    /// #         name -> Text,
    /// #         hair_color -> Text,
    /// #     }
    /// # }
    /// #
    /// # fn main() {
    /// #     run_test();
    /// # }
    /// #
    /// # fn run_test() -> QueryResult<()> {
    /// #     use diesel::insert_into;
    /// #     use users::dsl::*;
    /// #     let connection = connection_no_data();
    /// connection.execute("CREATE TABLE users (
    ///     name VARCHAR(255) NOT NULL DEFAULT 'Sean',
    ///     hair_color VARCHAR(255) NOT NULL DEFAULT 'Green'
    /// )")?;
    ///
    /// insert_into(users)
    ///     .default_values()
    ///     .execute(&connection)
    ///     .unwrap();
    /// let inserted_user = users.first(&connection)?;
    /// let expected_data = (String::from("Sean"), String::from("Green"));
    ///
    /// assert_eq!(expected_data, inserted_user);
    /// #     Ok(())
    /// # }
    /// ```
    pub fn default_values(self) -> InsertStatement<T, DefaultValues, Op> {
        static STATIC_DEFAULT_VALUES: &DefaultValues = &DefaultValues;
        self.values(STATIC_DEFAULT_VALUES)
    }

    /// Inserts the given values into the table passed to `insert_into`.
    ///
    /// See the documentation of [`insert_into`] for
    /// usage examples.
    ///
    /// This method can sometimes produce extremely opaque error messages due to
    /// limitations of the Rust language. If you receive an error about
    /// "overflow evaluating requirement" as a result of calling this method,
    /// you may need an `&` in front of the argument to this method.
    ///
    /// [`insert_into`]: ../fn.insert_into.html
    pub fn values<U>(self, records: U) -> InsertStatement<T, U::Values, Op>
    where
        U: Insertable<T>,
    {
        InsertStatement::new(
            self.target,
            records.values(),
            self.operator,
            NoReturningClause,
        )
    }
}

#[derive(Debug, Copy, Clone)]
/// A fully constructed insert statement.
///
/// The parameters of this struct represent:
///
/// - `T`: The table we are inserting into
/// - `U`: The data being inserted
/// - `Op`: The operation being performed. The specific types used to represent
///   this are private, but correspond to SQL such as `INSERT` or `REPLACE`.
///   You can safely rely on the default type representing `INSERT`
/// - `Ret`: The `RETURNING` clause of the query. The specific types used to
///   represent this are private. You can safely rely on the default type
///   representing a query without a `RETURNING` clause.
pub struct InsertStatement<T, U, Op = Insert, Ret = NoReturningClause> {
    operator: Op,
    target: T,
    records: U,
    returning: Ret,
}

impl<T, U, Op, Ret> InsertStatement<T, U, Op, Ret> {
    fn new(target: T, records: U, operator: Op, returning: Ret) -> Self {
        InsertStatement {
            operator: operator,
            target: target,
            records: records,
            returning: returning,
        }
    }

    #[cfg(feature = "postgres")]
    pub(crate) fn replace_values<F, V>(self, f: F) -> InsertStatement<T, V, Op, Ret>
    where
        F: FnOnce(U) -> V,
    {
        InsertStatement::new(self.target, f(self.records), self.operator, self.returning)
    }
}

impl<T, U, Op, Ret, DB> QueryFragment<DB> for InsertStatement<T, U, Op, Ret>
where
    DB: Backend,
    T: Table,
    T::FromClause: QueryFragment<DB>,
    U: InsertValues<T, DB> + CanInsertInSingleQuery<DB>,
    Op: QueryFragment<DB>,
    Ret: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();

        if self.records.rows_to_insert() == 0 {
            out.push_sql("SELECT 1 FROM ");
            self.target.from_clause().walk_ast(out.reborrow())?;
            out.push_sql(" WHERE 1=0");
            return Ok(());
        }

        self.operator.walk_ast(out.reborrow())?;
        out.push_sql(" INTO ");
        self.target.from_clause().walk_ast(out.reborrow())?;
        if self.records.is_noop() {
            out.push_sql(" DEFAULT VALUES");
        } else {
            out.push_sql(" (");
            if let Some(builder) = out.reborrow().query_builder() {
                self.records.column_names(builder)?;
            }
            out.push_sql(") VALUES ");
            if self.records.requires_parenthesis() {
                out.push_sql("(");
            }
            self.records.walk_ast(out.reborrow())?;
            if self.records.requires_parenthesis() {
                out.push_sql(")");
            }
        }
        self.returning.walk_ast(out.reborrow())?;
        Ok(())
    }
}

#[cfg(feature = "sqlite")]
impl<'a, T, U, Op> ExecuteDsl<SqliteConnection> for InsertStatement<T, &'a [U], Op>
where
    &'a U: Insertable<T>,
    InsertStatement<T, <&'a U as Insertable<T>>::Values, Op>: QueryFragment<Sqlite>,
    T: Copy,
    Op: Copy,
{
    fn execute(query: Self, conn: &SqliteConnection) -> QueryResult<usize> {
        use connection::Connection;
        conn.transaction(|| {
            let mut result = 0;
            for record in query.records {
                result += InsertStatement::new(
                    query.target,
                    record.values(),
                    query.operator,
                    query.returning,
                ).execute(conn)?;
            }
            Ok(result)
        })
    }
}

impl<T, U, Op, Ret> QueryId for InsertStatement<T, U, Op, Ret> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<T, U, Op> AsQuery for InsertStatement<T, U, Op, NoReturningClause>
where
    T: Table,
    InsertStatement<T, U, Op, ReturningClause<T::AllColumns>>: Query,
{
    type SqlType = <Self::Query as Query>::SqlType;
    type Query = InsertStatement<T, U, Op, ReturningClause<T::AllColumns>>;

    fn as_query(self) -> Self::Query {
        self.returning(T::all_columns())
    }
}

impl<T, U, Op, Ret> Query for InsertStatement<T, U, Op, ReturningClause<Ret>>
where
    Ret: Expression + SelectableExpression<T> + NonAggregate,
{
    type SqlType = Ret::SqlType;
}

impl<T, U, Op, Ret, Conn> RunQueryDsl<Conn> for InsertStatement<T, U, Op, Ret> {}

impl<T, U, Op> InsertStatement<T, U, Op> {
    /// Specify what expression is returned after execution of the `insert`.
    /// # Examples
    ///
    /// ### Inserting records:
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("../doctest_setup.rs");
    /// #
    /// # #[cfg(feature = "postgres")]
    /// # fn main() {
    /// #     use schema::users::dsl::*;
    /// #     let connection = establish_connection();
    /// let inserted_names = diesel::insert_into(users)
    ///     .values(&vec![name.eq("Timmy"), name.eq("Jimmy")])
    ///     .returning(name)
    ///     .get_results(&connection);
    /// assert_eq!(Ok(vec!["Timmy".to_string(), "Jimmy".to_string()]), inserted_names);
    /// # }
    /// # #[cfg(not(feature = "postgres"))]
    /// # fn main() {}
    /// ```
    pub fn returning<E>(self, returns: E) -> InsertStatement<T, U, Op, ReturningClause<E>>
    where
        InsertStatement<T, U, Op, ReturningClause<E>>: Query,
    {
        InsertStatement::new(
            self.target,
            self.records,
            self.operator,
            ReturningClause(returns),
        )
    }
}

#[derive(Debug, Copy, Clone, QueryId)]
#[doc(hidden)]
pub struct Insert;

impl<DB: Backend> QueryFragment<DB> for Insert {
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql("INSERT");
        Ok(())
    }
}

#[derive(Debug, Copy, Clone, QueryId)]
#[doc(hidden)]
pub struct InsertOrIgnore;

#[cfg(feature = "sqlite")]
impl QueryFragment<Sqlite> for InsertOrIgnore {
    fn walk_ast(&self, mut out: AstPass<Sqlite>) -> QueryResult<()> {
        out.push_sql("INSERT OR IGNORE");
        Ok(())
    }
}

#[cfg(feature = "mysql")]
impl QueryFragment<Mysql> for InsertOrIgnore {
    fn walk_ast(&self, mut out: AstPass<Mysql>) -> QueryResult<()> {
        out.push_sql("INSERT IGNORE");
        Ok(())
    }
}

impl_query_id!(InsertOrIgnore);

#[derive(Debug, Copy, Clone)]
#[doc(hidden)]
pub struct Replace;

#[cfg(feature = "sqlite")]
impl QueryFragment<Sqlite> for Replace {
    fn walk_ast(&self, mut out: AstPass<Sqlite>) -> QueryResult<()> {
        out.push_sql("REPLACE");
        Ok(())
    }
}

#[cfg(feature = "mysql")]
impl QueryFragment<Mysql> for Replace {
    fn walk_ast(&self, mut out: AstPass<Mysql>) -> QueryResult<()> {
        out.push_sql("REPLACE");
        Ok(())
    }
}

/// Marker trait to indicate that no additional operations have been added
/// to a record for insert.
///
/// This is used to prevent things like
/// `.on_conflict_do_nothing().on_conflict_do_nothing()`
/// from compiling.
pub trait UndecoratedInsertRecord<Table> {}

impl<'a, T, Tab> UndecoratedInsertRecord<Tab> for &'a T
where
    T: ?Sized + UndecoratedInsertRecord<Tab>,
{
}

impl<T, U> UndecoratedInsertRecord<T::Table> for ColumnInsertValue<T, U>
where
    T: Column,
{
}

impl<T, Table> UndecoratedInsertRecord<Table> for [T]
where
    T: UndecoratedInsertRecord<Table>,
{
}

impl<T, Table> UndecoratedInsertRecord<Table> for Vec<T>
where
    [T]: UndecoratedInsertRecord<Table>,
{
}

impl<Lhs, Rhs> UndecoratedInsertRecord<Lhs::Table> for Eq<Lhs, Rhs>
where
    Lhs: Column,
{
}

impl<Lhs, Rhs, Tab> UndecoratedInsertRecord<Tab> for Option<Eq<Lhs, Rhs>>
where
    Eq<Lhs, Rhs>: UndecoratedInsertRecord<Tab>,
{
}

#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct DefaultValues;

impl<DB: Backend> CanInsertInSingleQuery<DB> for DefaultValues {
    fn rows_to_insert(&self) -> usize {
        1
    }
}

impl<'a, Tab> Insertable<Tab> for &'a DefaultValues {
    type Values = DefaultValues;

    fn values(self) -> Self::Values {
        *self
    }
}

impl<Tab, DB> InsertValues<Tab, DB> for DefaultValues
where
    Tab: Table,
    DB: Backend + Any,
{
    fn column_names(&self, _: &mut DB::QueryBuilder) -> QueryResult<()> {
        Ok(())
    }

    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }

    #[cfg(not(feature = "mysql"))]
    fn is_noop(&self) -> bool {
        true
    }

    #[cfg(feature = "mysql")]
    fn is_noop(&self) -> bool {
        // The syntax for this on MySQL is
        // INSERT INTO table () VALUES ()
        //
        // This is hacky, but it's the easiest way to get this done without a
        // deeper restructuring of this code.
        TypeId::of::<DB>() != TypeId::of::<::mysql::Mysql>()
    }
}
<commit_msg>Fix failing build<commit_after>use std::any::*;

use backend::Backend;
use expression::{Expression, NonAggregate, SelectableExpression};
use expression::operators::Eq;
use insertable::*;
#[cfg(feature = "mysql")]
use mysql::Mysql;
use query_builder::*;
#[cfg(feature = "sqlite")]
use query_dsl::methods::ExecuteDsl;
use query_dsl::RunQueryDsl;
use query_source::{Column, Table};
use result::QueryResult;
#[cfg(feature = "sqlite")]
use sqlite::{Sqlite, SqliteConnection};
use super::returning_clause::*;

/// The structure returned by [`insert_into`].
///
/// The provided methods [`values`] and [`default_values`] will insert
/// data into the targeted table.
///
/// [`insert_into`]: ../fn.insert_into.html
/// [`values`]: #method.values
/// [`default_values`]: #method.default_values
#[derive(Debug, Clone, Copy)]
pub struct IncompleteInsertStatement<T, Op> {
    target: T,
    operator: Op,
}

impl<T, Op> IncompleteInsertStatement<T, Op> {
    pub(crate) fn new(target: T, operator: Op) -> Self {
        IncompleteInsertStatement { target, operator }
    }

    /// Inserts `DEFAULT VALUES` into the targeted table.
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("../doctest_setup.rs");
    /// #
    /// # table! {
    /// #     users (name) {
    /// #         name -> Text,
    /// #         hair_color -> Text,
    /// #     }
    /// # }
    /// #
    /// # fn main() {
    /// #     run_test();
    /// # }
    /// #
    /// # fn run_test() -> QueryResult<()> {
    /// #     use diesel::insert_into;
    /// #     use users::dsl::*;
    /// #     let connection = connection_no_data();
    /// connection.execute("CREATE TABLE users (
    ///     name VARCHAR(255) NOT NULL DEFAULT 'Sean',
    ///     hair_color VARCHAR(255) NOT NULL DEFAULT 'Green'
    /// )")?;
    ///
    /// insert_into(users)
    ///     .default_values()
    ///     .execute(&connection)
    ///     .unwrap();
    /// let inserted_user = users.first(&connection)?;
    /// let expected_data = (String::from("Sean"), String::from("Green"));
    ///
    /// assert_eq!(expected_data, inserted_user);
    /// #     Ok(())
    /// # }
    /// ```
    pub fn default_values(self) -> InsertStatement<T, DefaultValues, Op> {
        static STATIC_DEFAULT_VALUES: &DefaultValues = &DefaultValues;
        self.values(STATIC_DEFAULT_VALUES)
    }

    /// Inserts the given values into the table passed to `insert_into`.
    ///
    /// See the documentation of [`insert_into`] for
    /// usage examples.
    ///
    /// This method can sometimes produce extremely opaque error messages due to
    /// limitations of the Rust language. If you receive an error about
    /// "overflow evaluating requirement" as a result of calling this method,
    /// you may need an `&` in front of the argument to this method.
    ///
    /// [`insert_into`]: ../fn.insert_into.html
    pub fn values<U>(self, records: U) -> InsertStatement<T, U::Values, Op>
    where
        U: Insertable<T>,
    {
        InsertStatement::new(
            self.target,
            records.values(),
            self.operator,
            NoReturningClause,
        )
    }
}

#[derive(Debug, Copy, Clone)]
/// A fully constructed insert statement.
///
/// The parameters of this struct represent:
///
/// - `T`: The table we are inserting into
/// - `U`: The data being inserted
/// - `Op`: The operation being performed. The specific types used to represent
///   this are private, but correspond to SQL such as `INSERT` or `REPLACE`.
///   You can safely rely on the default type representing `INSERT`
/// - `Ret`: The `RETURNING` clause of the query. The specific types used to
///   represent this are private. You can safely rely on the default type
///   representing a query without a `RETURNING` clause.
pub struct InsertStatement<T, U, Op = Insert, Ret = NoReturningClause> {
    operator: Op,
    target: T,
    records: U,
    returning: Ret,
}

impl<T, U, Op, Ret> InsertStatement<T, U, Op, Ret> {
    fn new(target: T, records: U, operator: Op, returning: Ret) -> Self {
        InsertStatement {
            operator: operator,
            target: target,
            records: records,
            returning: returning,
        }
    }

    #[cfg(feature = "postgres")]
    pub(crate) fn replace_values<F, V>(self, f: F) -> InsertStatement<T, V, Op, Ret>
    where
        F: FnOnce(U) -> V,
    {
        InsertStatement::new(self.target, f(self.records), self.operator, self.returning)
    }
}

impl<T, U, Op, Ret, DB> QueryFragment<DB> for InsertStatement<T, U, Op, Ret>
where
    DB: Backend,
    T: Table,
    T::FromClause: QueryFragment<DB>,
    U: InsertValues<T, DB> + CanInsertInSingleQuery<DB>,
    Op: QueryFragment<DB>,
    Ret: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();

        if self.records.rows_to_insert() == 0 {
            out.push_sql("SELECT 1 FROM ");
            self.target.from_clause().walk_ast(out.reborrow())?;
            out.push_sql(" WHERE 1=0");
            return Ok(());
        }

        self.operator.walk_ast(out.reborrow())?;
        out.push_sql(" INTO ");
        self.target.from_clause().walk_ast(out.reborrow())?;
        if self.records.is_noop() {
            out.push_sql(" DEFAULT VALUES");
        } else {
            out.push_sql(" (");
            if let Some(builder) = out.reborrow().query_builder() {
                self.records.column_names(builder)?;
            }
            out.push_sql(") VALUES ");
            if self.records.requires_parenthesis() {
                out.push_sql("(");
            }
            self.records.walk_ast(out.reborrow())?;
            if self.records.requires_parenthesis() {
                out.push_sql(")");
            }
        }
        self.returning.walk_ast(out.reborrow())?;
        Ok(())
    }
}

#[cfg(feature = "sqlite")]
impl<'a, T, U, Op> ExecuteDsl<SqliteConnection> for InsertStatement<T, &'a [U], Op>
where
    &'a U: Insertable<T>,
    InsertStatement<T, <&'a U as Insertable<T>>::Values, Op>: QueryFragment<Sqlite>,
    T: Copy,
    Op: Copy,
{
    fn execute(query: Self, conn: &SqliteConnection) -> QueryResult<usize> {
        use connection::Connection;
        conn.transaction(|| {
            let mut result = 0;
            for record in query.records {
                result += InsertStatement::new(
                    query.target,
                    record.values(),
                    query.operator,
                    query.returning,
                ).execute(conn)?;
            }
            Ok(result)
        })
    }
}

impl<T, U, Op, Ret> QueryId for InsertStatement<T, U, Op, Ret> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<T, U, Op> AsQuery for InsertStatement<T, U, Op, NoReturningClause>
where
    T: Table,
    InsertStatement<T, U, Op, ReturningClause<T::AllColumns>>: Query,
{
    type SqlType = <Self::Query as Query>::SqlType;
    type Query = InsertStatement<T, U, Op, ReturningClause<T::AllColumns>>;

    fn as_query(self) -> Self::Query {
        self.returning(T::all_columns())
    }
}

impl<T, U, Op, Ret> Query for InsertStatement<T, U, Op, ReturningClause<Ret>>
where
    Ret: Expression + SelectableExpression<T> + NonAggregate,
{
    type SqlType = Ret::SqlType;
}

impl<T, U, Op, Ret, Conn> RunQueryDsl<Conn> for InsertStatement<T, U, Op, Ret> {}

impl<T, U, Op> InsertStatement<T, U, Op> {
    /// Specify what expression is returned after execution of the `insert`.
    /// # Examples
    ///
    /// ### Inserting records:
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("../doctest_setup.rs");
    /// #
    /// # #[cfg(feature = "postgres")]
    /// # fn main() {
    /// #     use schema::users::dsl::*;
    /// #     let connection = establish_connection();
    /// let inserted_names = diesel::insert_into(users)
    ///     .values(&vec![name.eq("Timmy"), name.eq("Jimmy")])
    ///     .returning(name)
    ///     .get_results(&connection);
    /// assert_eq!(Ok(vec!["Timmy".to_string(), "Jimmy".to_string()]), inserted_names);
    /// # }
    /// # #[cfg(not(feature = "postgres"))]
    /// # fn main() {}
    /// ```
    pub fn returning<E>(self, returns: E) -> InsertStatement<T, U, Op, ReturningClause<E>>
    where
        InsertStatement<T, U, Op, ReturningClause<E>>: Query,
    {
        InsertStatement::new(
            self.target,
            self.records,
            self.operator,
            ReturningClause(returns),
        )
    }
}

#[derive(Debug, Copy, Clone, QueryId)]
#[doc(hidden)]
pub struct Insert;

impl<DB: Backend> QueryFragment<DB> for Insert {
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql("INSERT");
        Ok(())
    }
}

#[derive(Debug, Copy, Clone, QueryId)]
#[doc(hidden)]
pub struct InsertOrIgnore;

#[cfg(feature = "sqlite")]
impl QueryFragment<Sqlite> for InsertOrIgnore {
    fn walk_ast(&self, mut out: AstPass<Sqlite>) -> QueryResult<()> {
        out.push_sql("INSERT OR IGNORE");
        Ok(())
    }
}

#[cfg(feature = "mysql")]
impl QueryFragment<Mysql> for InsertOrIgnore {
    fn walk_ast(&self, mut out: AstPass<Mysql>) -> QueryResult<()> {
        out.push_sql("INSERT IGNORE");
        Ok(())
    }
}

#[derive(Debug, Copy, Clone)]
#[doc(hidden)]
pub struct Replace;

#[cfg(feature = "sqlite")]
impl QueryFragment<Sqlite> for Replace {
    fn walk_ast(&self, mut out: AstPass<Sqlite>) -> QueryResult<()> {
        out.push_sql("REPLACE");
        Ok(())
    }
}

#[cfg(feature = "mysql")]
impl QueryFragment<Mysql> for Replace {
    fn walk_ast(&self, mut out: AstPass<Mysql>) -> QueryResult<()> {
        out.push_sql("REPLACE");
        Ok(())
    }
}

/// Marker trait to indicate that no additional operations have been added
/// to a record for insert.
///
/// This is used to prevent things like
/// `.on_conflict_do_nothing().on_conflict_do_nothing()`
/// from compiling.
pub trait UndecoratedInsertRecord<Table> {}

impl<'a, T, Tab> UndecoratedInsertRecord<Tab> for &'a T
where
    T: ?Sized + UndecoratedInsertRecord<Tab>,
{
}

impl<T, U> UndecoratedInsertRecord<T::Table> for ColumnInsertValue<T, U>
where
    T: Column,
{
}

impl<T, Table> UndecoratedInsertRecord<Table> for [T]
where
    T: UndecoratedInsertRecord<Table>,
{
}

impl<T, Table> UndecoratedInsertRecord<Table> for Vec<T>
where
    [T]: UndecoratedInsertRecord<Table>,
{
}

impl<Lhs, Rhs> UndecoratedInsertRecord<Lhs::Table> for Eq<Lhs, Rhs>
where
    Lhs: Column,
{
}

impl<Lhs, Rhs, Tab> UndecoratedInsertRecord<Tab> for Option<Eq<Lhs, Rhs>>
where
    Eq<Lhs, Rhs>: UndecoratedInsertRecord<Tab>,
{
}

#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct DefaultValues;

impl<DB: Backend> CanInsertInSingleQuery<DB> for DefaultValues {
    fn rows_to_insert(&self) -> usize {
        1
    }
}

impl<'a, Tab> Insertable<Tab> for &'a DefaultValues {
    type Values = DefaultValues;

    fn values(self) -> Self::Values {
        *self
    }
}

impl<Tab, DB> InsertValues<Tab, DB> for DefaultValues
where
    Tab: Table,
    DB: Backend + Any,
{
    fn column_names(&self, _: &mut DB::QueryBuilder) -> QueryResult<()> {
        Ok(())
    }

    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }

    #[cfg(not(feature = "mysql"))]
    fn is_noop(&self) -> bool {
        true
    }

    #[cfg(feature = "mysql")]
    fn is_noop(&self) -> bool {
        // The syntax for this on MySQL is
        // INSERT INTO table () VALUES ()
        //
        // This is hacky, but it's the easiest way to get this done without a
        // deeper restructuring of this code.
        TypeId::of::<DB>() != TypeId::of::<::mysql::Mysql>()
    }
}
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// 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
//
//     https://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.
//

//! Module containing all of macro definitions for `async-coap-uri`.

pub use super::{impl_uri_buf_traits, impl_uri_traits};
pub use super::{rel_ref, uri, uri_ref};
pub use super::{rel_ref_format, uri_format, uri_ref_format};

// Internal macros.
#[doc(hidden)]
pub use super::{_impl_uri_buf_traits_base, _impl_uri_traits, _impl_uri_traits_base};

#[doc(hidden)]
#[macro_export]
macro_rules! _uri_const {
    ( $S:expr, $C:ty ) => {{
        const __CONST_S: &'static str = $S;
        // We do this weird casting thing here to make sure that we
        // don't end up using unstable features, while still allowing
        // these macros to be used to assign constants.
        unsafe {
            union Slices<'a> {
                str: &'a str,
                uri: &'a $C,
            }
            Slices { str: __CONST_S }.uri
        }
    }};
}

/// Creates a `&'static UriRef` from a string literal.
///
/// Accepts only string constants and literals. The given string *MUST* be well-formed.
///
/// Examples:
///
/// ```
/// # use async_coap_uri::prelude::*;
/// let x = uri_ref!("a/b/c?q=foobar#frag");
/// assert_eq!(x.scheme(),None);
/// assert_eq!(x.raw_authority(),None);
/// assert_eq!(x.raw_path(),"a/b/c");
/// assert_eq!(x.raw_query(),Some("q=foobar"));
/// assert_eq!(x.raw_fragment(),Some("frag"));
/// ```
///
/// ```
/// # use async_coap_uri::prelude::*;
/// let x = uri_ref!("http://example.com");
/// assert_eq!(x.scheme(),Some("http"));
/// assert_eq!(x.raw_authority(),Some("example.com"));
/// assert_eq!(x.raw_path(),"");
/// assert_eq!(x.raw_query(),None);
/// assert_eq!(x.raw_fragment(),None);
/// ```
///
/// Checks for correctness are performed at compile time:
///
/// ```compile_fail
/// # use async_coap_uri::prelude::*;
/// // This will not compile.
/// let x = uri_ref!("%00 invalid %ff");
/// ```
///
#[macro_export]
macro_rules! uri_ref {
    ( unsafe $S:expr ) => {{
        // We don't do any correctness checks when $S is preceded by `unsafe`.
        $crate::_uri_const!($S, $crate::UriRef)
    }};
    ( $S:expr ) => {{
        assert_uri_ref_literal!($S);
        $crate::_uri_const!($S, $crate::UriRef)
    }};
    ( ) => {
        $crate::uri_ref!("")
    };
}

/// Creates a `&'static RelRef` from a string literal.
///
/// Accepts only string constants and literals. The given string *MUST* be well-formed.
///
/// Example:
///
/// ```
/// # use async_coap_uri::prelude::*;
/// let x = rel_ref!("a/b/c?q=foobar#frag");
/// assert_eq!(x.raw_path(),"a/b/c");
/// assert_eq!(x.raw_query(),Some("q=foobar"));
/// assert_eq!(x.raw_fragment(),Some("frag"));
/// ```
///
/// Checks for correctness are performed at compile time:
///
/// ```compile_fail
/// # use async_coap_uri::prelude::*;
/// // This will not compile.
/// let x = rel_ref!("%00 invalid %ff");
/// ```
///
/// Degenerate cases (strings that could be confused with URIs if parsed as URI-Refs)
/// will also not compile:
///
/// ```compile_fail
/// # use async_coap_uri::prelude::*;
/// // This will not compile because `//a/b/c` is
/// // a degenerate relative reference.
/// let x = rel_ref!("//a/b/c");
/// ```
///
/// ```compile_fail
/// # use async_coap_uri::prelude::*;
/// // This will not compile because `g:a:b:c` is
/// // a degenerate relative reference.
/// let x = rel_ref!("g:a:b:c");
/// ```
///
/// Both of those cases can be made to compile by adjusting them to no longer be degenerate:
///
/// ```
/// # use async_coap_uri::prelude::*;
/// let b = rel_ref!("/.//a/b/c"); // Prepending "/."
/// let a = rel_ref!("./g:a:b:c"); // Prepending "./"
/// let a = rel_ref!("g%3Aa:b:c"); // Convert first colon to "%3A"
/// ```
///
/// At runtime, `UriRef::from_str("g:a:b:c")` is allowed since in some circumstances it cannot
/// be avoided, but there is usually no good reason to have a degenerate `RelRef` literal.
/// In the rare case where such a thing is warranted (unit tests, for example), you can disable
/// compile-time verification by prepending the keyword `unsafe` to the string:
///
/// ```
/// # use async_coap_uri::prelude::*;
/// // Both of these will compile because the `unsafe` keyword
/// // disables the compile-time validity checks:
/// assert!(rel_ref!(unsafe "//a/b/c").is_degenerate());
/// assert!(rel_ref!(unsafe "g:a:b:c").is_degenerate());
/// ```
#[macro_export]
macro_rules! rel_ref {
    ( unsafe $S:expr ) => {{
        // We don't do any correctness checks when $S is preceded by `unsafe`.
        $crate::_uri_const!($S, $crate::RelRef)
    }};
    ( $S:expr ) => {{
        assert_rel_ref_literal!($S);
        $crate::_uri_const!($S, $crate::RelRef)
    }};
    ( ) => {
        $crate::rel_ref!("")
    };
}

/// Creates a `&'static Uri` from a string literal.
///
/// Accepts only string constants and literals. The given string *MUST* be well-formed.
///
/// Example:
///
/// ```
/// # use async_coap_uri::prelude::*;
/// let x = uri!("http://example.com");
/// assert_eq!(x.scheme(),Some("http"));
/// assert_eq!(x.raw_authority(),Some("example.com"));
/// ```
///
/// Checks for correctness are performed at compile time:
///
/// ```compile_fail
/// # use async_coap_uri::prelude::*;
/// // This will not compile.
/// let x = uri!("%00 invalid %ff");
/// ```
///
/// Passing something that is a valid URI-Reference but not a valid URI (i.e.: Missing scheme)
/// will also not compile:
///
/// ```compile_fail
/// # use async_coap_uri::prelude::*;
/// // This will not compile because "a/b/c" isn't a valid URI.
/// let x = uri!("a/b/c");
/// ```
///
#[macro_export]
macro_rules! uri {
    ( unsafe $S:expr ) => {{
        // We don't do any correctness checks when $S is preceded by `unsafe`.
        $crate::_uri_const!($S, $crate::Uri)
    }};
    ( $S:expr ) => {{
        assert_uri_literal!($S);
        $crate::_uri_const!($S, $crate::Uri)
    }};
    ( ) => {
        $crate::uri!("")
    };
}

/// Creates a `Option<UriRefBuf>` from the given string format and arguments.
///
/// The resulting string is checked at runtime to ensure it is well-formed.
#[cfg(feature = "std")]
#[macro_export]
macro_rules! uri_ref_format {
    ($($arg:tt)*) => ($crate::UriRefBuf::from_string(format!($($arg)*)))
}

/// Creates a `Option<UriBuf>` from the given string format and arguments.
///
/// The resulting string is checked at runtime to ensure it is well-formed.
#[cfg(feature = "std")]
#[macro_export]
macro_rules! uri_format {
    ($($arg:tt)*) => ($crate::UriBuf::from_string(format!($($arg)*)))
}

/// Creates a `Option<RelRefBuf>` from the given string format and arguments.
///
/// The resulting string is checked at runtime to ensure it is well-formed.
#[cfg(feature = "std")]
#[macro_export]
macro_rules! rel_ref_format {
    ($($arg:tt)*) => ($crate::RelRefBuf::from_string(format!($($arg)*)))
}

#[doc(hidden)]
#[macro_export]
macro_rules! _impl_uri_traits {
    ( $C:ty ) => {
        impl<T: AsRef<str> + ?Sized> core::cmp::PartialEq<T> for $C {
            fn eq(&self, other: &T) -> bool {
                core::cmp::PartialEq::eq(self.as_str(), other.as_ref())
            }
        }

        impl<T: AsRef<str> + ?Sized> core::cmp::PartialOrd<T> for $C {
            fn partial_cmp(&self, other: &T) -> Option<::std::cmp::Ordering> {
                core::cmp::PartialOrd::partial_cmp(self.as_str(), other.as_ref())
            }
        }

        impl core::cmp::Ord for $C {
            fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
                core::cmp::Ord::cmp(self.as_str(), other.as_str())
            }
        }

        impl std::fmt::Debug for $C {
            fn fmt(
                &self,
                f: &mut std::fmt::Formatter<'_>,
            ) -> std::result::Result<(), std::fmt::Error> {
                f.write_str(concat!(stringify!($C), "<"))?;
                std::fmt::Display::fmt(self.as_str(), f)?;
                f.write_str(">")
            }
        }
        impl AsRef<str> for $C {
            fn as_ref(&self) -> &str {
                self.as_str()
            }
        }
        impl AsRef<$C> for $C {
            fn as_ref(&self) -> &$C {
                &self
            }
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! _impl_uri_traits_base {
    ( $C:ty ) => {
        _impl_uri_traits!($C);

        impl core::convert::From<&$C> for std::string::String {
            fn from(x: &$C) -> Self {
                String::from(&x.0)
            }
        }

        impl core::convert::From<&$C> for $crate::UriRefBuf {
            fn from(x: &$C) -> Self {
                unsafe { $crate::UriRefBuf::from_string_unchecked(String::from(&x.0)) }
            }
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! impl_uri_traits {
    ( $C:ty ) => {
        _impl_uri_traits_base!($C);

        impl $crate::AnyUriRef for $C {
            fn components(&self) -> UriRawComponents<'_> {
                self.0.components()
            }

            fn is_empty(&self) -> bool {
                self.0.is_empty()
            }

            fn uri_type(&self) -> $crate::UriType {
                self.0.uri_type()
            }

            fn to_uri_ref_buf(&self) -> $crate::UriRefBuf {
                self.0.to_uri_ref_buf()
            }

            unsafe fn write_to_unsafe<W: core::fmt::Write + ?Sized>(
                &self,
                write: &mut W,
            ) -> Result<(), core::fmt::Error> {
                self.0.write_to_unsafe(write)
            }
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! _impl_uri_buf_traits_base {
    ( $C:ty , $B:ty ) => {
        _impl_uri_traits!($C);

        impl core::convert::From<$C> for std::string::String {
            fn from(x: $C) -> Self {
                String::from(x.0)
            }
        }

        impl core::convert::From<&$C> for $C {
            fn from(x: &$C) -> Self {
                x.clone()
            }
        }

        impl std::borrow::ToOwned for $B {
            type Owned = $C;

            fn to_owned(&self) -> Self::Owned {
                unsafe { <$C>::from_string_unchecked(self.to_string()) }
            }
        }

        impl core::borrow::Borrow<$B> for $C {
            fn borrow(&self) -> &$B {
                unsafe { <$B>::from_str_unchecked(self.as_str()) }
            }
        }

        impl $crate::AnyUriRef for $C {
            fn components(&self) -> UriRawComponents<'_> {
                use core::borrow::Borrow;
                let b: &$B = self.borrow();
                b.components()
            }

            fn is_empty(&self) -> bool {
                use core::borrow::Borrow;
                let b: &$B = self.borrow();
                b.is_empty()
            }

            fn uri_type(&self) -> $crate::UriType {
                use core::borrow::Borrow;
                let b: &$B = self.borrow();
                b.uri_type()
            }

            fn to_uri_ref_buf(&self) -> $crate::UriRefBuf {
                use core::borrow::Borrow;
                let b: &$B = self.borrow();
                b.to_uri_ref_buf()
            }

            unsafe fn write_to_unsafe<W: core::fmt::Write + ?Sized>(
                &self,
                write: &mut W,
            ) -> Result<(), core::fmt::Error> {
                use core::borrow::Borrow;
                let b: &$B = self.borrow();
                b.write_to_unsafe(write)
            }
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! impl_uri_buf_traits {
    ( $C:ty , $B:ty) => {
        _impl_uri_buf_traits_base!($C, $B);

        impl AsRef<std::string::String> for $C {
            fn as_ref(&self) -> &std::string::String {
                AsRef::<std::string::String>::as_ref(&self.0)
            }
        }

        impl AsRef<$crate::UriRefBuf> for $C {
            fn as_ref(&self) -> &$crate::UriRefBuf {
                AsRef::<$crate::UriRefBuf>::as_ref(&self.0)
            }
        }

        impl core::convert::From<$C> for $crate::UriRefBuf {
            fn from(x: $C) -> Self {
                x.0.into()
            }
        }
    };
}
<commit_msg>async-coap-uri: Fix macro hygiene<commit_after>// Copyright 2019 Google LLC
//
// 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
//
//     https://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.
//

//! Module containing all of macro definitions for `async-coap-uri`.

pub use super::{impl_uri_buf_traits, impl_uri_traits};
pub use super::{rel_ref, uri, uri_ref};
pub use super::{rel_ref_format, uri_format, uri_ref_format};

// Internal macros.
#[doc(hidden)]
pub use super::{_impl_uri_buf_traits_base, _impl_uri_traits, _impl_uri_traits_base};

#[doc(hidden)]
#[macro_export]
macro_rules! _uri_const {
    ( $S:expr, $C:ty ) => {{
        const __CONST_S: &'static str = $S;
        // We do this weird casting thing here to make sure that we
        // don't end up using unstable features, while still allowing
        // these macros to be used to assign constants.
        unsafe {
            union Slices<'a> {
                str: &'a str,
                uri: &'a $C,
            }
            Slices { str: __CONST_S }.uri
        }
    }};
}

/// Creates a `&'static UriRef` from a string literal.
///
/// Accepts only string constants and literals. The given string *MUST* be well-formed.
///
/// Examples:
///
/// ```
/// # use async_coap_uri::prelude::*;
/// let x = uri_ref!("a/b/c?q=foobar#frag");
/// assert_eq!(x.scheme(),None);
/// assert_eq!(x.raw_authority(),None);
/// assert_eq!(x.raw_path(),"a/b/c");
/// assert_eq!(x.raw_query(),Some("q=foobar"));
/// assert_eq!(x.raw_fragment(),Some("frag"));
/// ```
///
/// ```
/// # use async_coap_uri::prelude::*;
/// let x = uri_ref!("http://example.com");
/// assert_eq!(x.scheme(),Some("http"));
/// assert_eq!(x.raw_authority(),Some("example.com"));
/// assert_eq!(x.raw_path(),"");
/// assert_eq!(x.raw_query(),None);
/// assert_eq!(x.raw_fragment(),None);
/// ```
///
/// Checks for correctness are performed at compile time:
///
/// ```compile_fail
/// # use async_coap_uri::prelude::*;
/// // This will not compile.
/// let x = uri_ref!("%00 invalid %ff");
/// ```
///
#[macro_export]
macro_rules! uri_ref {
    ( unsafe $S:expr ) => {{
        // We don't do any correctness checks when $S is preceded by `unsafe`.
        $crate::_uri_const!($S, $crate::UriRef)
    }};
    ( $S:expr ) => {{
        assert_uri_ref_literal!($S);
        $crate::_uri_const!($S, $crate::UriRef)
    }};
    ( ) => {
        $crate::uri_ref!("")
    };
}

/// Creates a `&'static RelRef` from a string literal.
///
/// Accepts only string constants and literals. The given string *MUST* be well-formed.
///
/// Example:
///
/// ```
/// # use async_coap_uri::prelude::*;
/// let x = rel_ref!("a/b/c?q=foobar#frag");
/// assert_eq!(x.raw_path(),"a/b/c");
/// assert_eq!(x.raw_query(),Some("q=foobar"));
/// assert_eq!(x.raw_fragment(),Some("frag"));
/// ```
///
/// Checks for correctness are performed at compile time:
///
/// ```compile_fail
/// # use async_coap_uri::prelude::*;
/// // This will not compile.
/// let x = rel_ref!("%00 invalid %ff");
/// ```
///
/// Degenerate cases (strings that could be confused with URIs if parsed as URI-Refs)
/// will also not compile:
///
/// ```compile_fail
/// # use async_coap_uri::prelude::*;
/// // This will not compile because `//a/b/c` is
/// // a degenerate relative reference.
/// let x = rel_ref!("//a/b/c");
/// ```
///
/// ```compile_fail
/// # use async_coap_uri::prelude::*;
/// // This will not compile because `g:a:b:c` is
/// // a degenerate relative reference.
/// let x = rel_ref!("g:a:b:c");
/// ```
///
/// Both of those cases can be made to compile by adjusting them to no longer be degenerate:
///
/// ```
/// # use async_coap_uri::prelude::*;
/// let b = rel_ref!("/.//a/b/c"); // Prepending "/."
/// let a = rel_ref!("./g:a:b:c"); // Prepending "./"
/// let a = rel_ref!("g%3Aa:b:c"); // Convert first colon to "%3A"
/// ```
///
/// At runtime, `UriRef::from_str("g:a:b:c")` is allowed since in some circumstances it cannot
/// be avoided, but there is usually no good reason to have a degenerate `RelRef` literal.
/// In the rare case where such a thing is warranted (unit tests, for example), you can disable
/// compile-time verification by prepending the keyword `unsafe` to the string:
///
/// ```
/// # use async_coap_uri::prelude::*;
/// // Both of these will compile because the `unsafe` keyword
/// // disables the compile-time validity checks:
/// assert!(rel_ref!(unsafe "//a/b/c").is_degenerate());
/// assert!(rel_ref!(unsafe "g:a:b:c").is_degenerate());
/// ```
#[macro_export]
macro_rules! rel_ref {
    ( unsafe $S:expr ) => {{
        // We don't do any correctness checks when $S is preceded by `unsafe`.
        $crate::_uri_const!($S, $crate::RelRef)
    }};
    ( $S:expr ) => {{
        assert_rel_ref_literal!($S);
        $crate::_uri_const!($S, $crate::RelRef)
    }};
    ( ) => {
        $crate::rel_ref!("")
    };
}

/// Creates a `&'static Uri` from a string literal.
///
/// Accepts only string constants and literals. The given string *MUST* be well-formed.
///
/// Example:
///
/// ```
/// # use async_coap_uri::prelude::*;
/// let x = uri!("http://example.com");
/// assert_eq!(x.scheme(),Some("http"));
/// assert_eq!(x.raw_authority(),Some("example.com"));
/// ```
///
/// Checks for correctness are performed at compile time:
///
/// ```compile_fail
/// # use async_coap_uri::prelude::*;
/// // This will not compile.
/// let x = uri!("%00 invalid %ff");
/// ```
///
/// Passing something that is a valid URI-Reference but not a valid URI (i.e.: Missing scheme)
/// will also not compile:
///
/// ```compile_fail
/// # use async_coap_uri::prelude::*;
/// // This will not compile because "a/b/c" isn't a valid URI.
/// let x = uri!("a/b/c");
/// ```
///
#[macro_export]
macro_rules! uri {
    ( unsafe $S:expr ) => {{
        // We don't do any correctness checks when $S is preceded by `unsafe`.
        $crate::_uri_const!($S, $crate::Uri)
    }};
    ( $S:expr ) => {{
        assert_uri_literal!($S);
        $crate::_uri_const!($S, $crate::Uri)
    }};
    ( ) => {
        $crate::uri!("")
    };
}

/// Creates a `Option<UriRefBuf>` from the given string format and arguments.
///
/// The resulting string is checked at runtime to ensure it is well-formed.
#[cfg(feature = "std")]
#[macro_export]
macro_rules! uri_ref_format {
    ($($arg:tt)*) => ($crate::UriRefBuf::from_string(::std::format!($($arg)*)))
}

/// Creates a `Option<UriBuf>` from the given string format and arguments.
///
/// The resulting string is checked at runtime to ensure it is well-formed.
#[cfg(feature = "std")]
#[macro_export]
macro_rules! uri_format {
    ($($arg:tt)*) => ($crate::UriBuf::from_string(::std::format!($($arg)*)))
}

/// Creates a `Option<RelRefBuf>` from the given string format and arguments.
///
/// The resulting string is checked at runtime to ensure it is well-formed.
#[cfg(feature = "std")]
#[macro_export]
macro_rules! rel_ref_format {
    ($($arg:tt)*) => ($crate::RelRefBuf::from_string(::std::format!($($arg)*)))
}

#[doc(hidden)]
#[macro_export]
macro_rules! _impl_uri_traits {
    ( $C:ty ) => {
        impl<T: ::core::convert::AsRef<str> + ?::core::marker::Sized> ::core::cmp::PartialEq<T>
            for $C
        {
            fn eq(&self, other: &T) -> bool {
                ::core::cmp::PartialEq::eq(self.as_str(), other.as_ref())
            }
        }

        impl<T: ::core::convert::AsRef<str> + ?::core::marker::Sized> ::core::cmp::PartialOrd<T>
            for $C
        {
            fn partial_cmp(&self, other: &T) -> ::core::option::Option<::core::cmp::Ordering> {
                ::core::cmp::PartialOrd::partial_cmp(self.as_str(), other.as_ref())
            }
        }

        impl ::core::cmp::Ord for $C {
            fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
                ::core::cmp::Ord::cmp(self.as_str(), other.as_str())
            }
        }

        impl ::core::fmt::Debug for $C {
            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
                f.write_str(concat!(stringify!($C), "<"))?;
                ::core::fmt::Display::fmt(self.as_str(), f)?;
                f.write_str(">")
            }
        }
        impl ::core::convert::AsRef<str> for $C {
            fn as_ref(&self) -> &str {
                self.as_str()
            }
        }
        impl ::core::convert::AsRef<$C> for $C {
            fn as_ref(&self) -> &$C {
                &self
            }
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! _impl_uri_traits_base {
    ( $C:ty ) => {
        _impl_uri_traits!($C);

        impl ::core::convert::From<&$C> for ::std::string::String {
            fn from(x: &$C) -> Self {
                ::std::string::String::from(&x.0)
            }
        }

        impl ::core::convert::From<&$C> for $crate::UriRefBuf {
            fn from(x: &$C) -> Self {
                unsafe {
                    $crate::UriRefBuf::from_string_unchecked(::std::string::String::from(&x.0))
                }
            }
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! impl_uri_traits {
    ( $C:ty ) => {
        _impl_uri_traits_base!($C);

        impl $crate::AnyUriRef for $C {
            fn components(&self) -> $crate::UriRawComponents<'_> {
                self.0.components()
            }

            fn is_empty(&self) -> bool {
                self.0.is_empty()
            }

            fn uri_type(&self) -> $crate::UriType {
                self.0.uri_type()
            }

            fn to_uri_ref_buf(&self) -> $crate::UriRefBuf {
                self.0.to_uri_ref_buf()
            }

            unsafe fn write_to_unsafe<W: ::core::fmt::Write + ?::core::marker::Sized>(
                &self,
                write: &mut W,
            ) -> ::core::fmt::Result {
                self.0.write_to_unsafe(write)
            }
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! _impl_uri_buf_traits_base {
    ( $C:ty , $B:ty ) => {
        _impl_uri_traits!($C);

        impl ::core::convert::From<$C> for ::std::string::String {
            fn from(x: $C) -> Self {
                ::std::string::String::from(x.0)
            }
        }

        impl ::core::convert::From<&$C> for $C {
            fn from(x: &$C) -> Self {
                <$C as ::core::clone::Clone>::clone(x)
            }
        }

        impl ::std::borrow::ToOwned for $B {
            type Owned = $C;

            fn to_owned(&self) -> Self::Owned {
                unsafe {
                    <$C>::from_string_unchecked(<Self as ::std::string::ToString>::to_string(self))
                }
            }
        }

        impl ::core::borrow::Borrow<$B> for $C {
            fn borrow(&self) -> &$B {
                unsafe { <$B>::from_str_unchecked(self.as_str()) }
            }
        }

        impl $crate::AnyUriRef for $C {
            fn components(&self) -> $crate::UriRawComponents<'_> {
                let b: &$B = <Self as ::core::borrow::Borrow<$B>>::borrow(self);
                b.components()
            }

            fn is_empty(&self) -> bool {
                let b: &$B = <Self as ::core::borrow::Borrow<$B>>::borrow(self);
                b.is_empty()
            }

            fn uri_type(&self) -> $crate::UriType {
                let b: &$B = <Self as ::core::borrow::Borrow<$B>>::borrow(self);
                b.uri_type()
            }

            fn to_uri_ref_buf(&self) -> $crate::UriRefBuf {
                let b: &$B = <Self as ::core::borrow::Borrow<$B>>::borrow(self);
                b.to_uri_ref_buf()
            }

            unsafe fn write_to_unsafe<W: ::core::fmt::Write + ?::core::marker::Sized>(
                &self,
                write: &mut W,
            ) -> ::core::fmt::Result {
                let b: &$B = <Self as ::core::borrow::Borrow<$B>>::borrow(self);
                b.write_to_unsafe(write)
            }
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! impl_uri_buf_traits {
    ( $C:ty , $B:ty) => {
        _impl_uri_buf_traits_base!($C, $B);

        impl ::core::convert::AsRef<::std::string::String> for $C {
            fn as_ref(&self) -> &std::string::String {
                ::core::convert::AsRef::<::std::string::String>::as_ref(&self.0)
            }
        }

        impl ::core::convert::AsRef<$crate::UriRefBuf> for $C {
            fn as_ref(&self) -> &$crate::UriRefBuf {
                ::core::convert::AsRef::<$crate::UriRefBuf>::as_ref(&self.0)
            }
        }

        impl ::core::convert::From<$C> for $crate::UriRefBuf {
            fn from(x: $C) -> Self {
                ::core::convert::Into::<Self>::into(x.0)
            }
        }
    };
}
<|endoftext|>