<commit_before>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::mem;
use std::ptr;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::MutexGuard;

use device::Device;

use OomError;
use SynchronizedVulkanObject;
use VulkanObject;
use VulkanPointers;
use check_errors;
use vk;

/// Pool from which descriptor sets are allocated from.
///
/// A pool has a maximum number of descriptor sets and a maximum number of descriptors (one value
/// per descriptor type) it can allocate.
pub struct DescriptorPool {
    pool: Mutex<vk::DescriptorPool>,
    device: Arc<Device>,
}

impl DescriptorPool {
    /// Initializes a new pool.
    // FIXME: capacity of the pool
    pub fn new(device: &Arc<Device>) -> Result<Arc<DescriptorPool>, OomError> {
        let vk = device.pointers();

        // FIXME: arbitrary
        let pool_sizes = vec![
            vk::DescriptorPoolSize {
                ty: vk::DESCRIPTOR_TYPE_UNIFORM_BUFFER,
                descriptorCount: 10,
            },
            vk::DescriptorPoolSize {
                ty: vk::DESCRIPTOR_TYPE_STORAGE_BUFFER,
                descriptorCount: 10,
            },
            vk::DescriptorPoolSize {
                ty: vk::DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
                descriptorCount: 10,
            },
            vk::DescriptorPoolSize {
                ty: vk::DESCRIPTOR_TYPE_SAMPLED_IMAGE,
                descriptorCount: 10,
            },
            vk::DescriptorPoolSize {
                ty: vk::DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
                descriptorCount: 10,
            },
        ];

        let pool = unsafe {
            let infos = vk::DescriptorPoolCreateInfo {
                sType: vk::STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
                pNext: ptr::null(),
                flags: vk::DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,   // TODO:
                maxSets: 100,       // TODO: let user choose
                poolSizeCount: pool_sizes.len() as u32,
                pPoolSizes: pool_sizes.as_ptr(),
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreateDescriptorPool(device.internal_object(), &infos,
                                                      ptr::null(), &mut output)));
            output
        };

        Ok(Arc::new(DescriptorPool {
            pool: Mutex::new(pool),
            device: device.clone(),
        }))
    }

    /// Returns the device this pool was created from.
    #[inline]
    pub fn device(&self) -> &Arc<Device> {
        &self.device
    }
}

unsafe impl SynchronizedVulkanObject for DescriptorPool {
    type Object = vk::DescriptorPool;

    #[inline]
    fn internal_object_guard(&self) -> MutexGuard<vk::DescriptorPool> {
        self.pool.lock().unwrap()
    }
}

impl Drop for DescriptorPool {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.device.pointers();
            let pool = self.pool.lock().unwrap();
            vk.DestroyDescriptorPool(self.device.internal_object(), *pool, ptr::null());
        }
    }
}

#[cfg(test)]
mod tests {
    use descriptor::DescriptorPool;

    #[test]
    fn create() {
        let (device, _) = gfx_dev_and_queue!();
        let _ = DescriptorPool::new(&device).unwrap();
    }

    #[test]
    fn device() {
        let (device, _) = gfx_dev_and_queue!();
        let pool = DescriptorPool::new(&device).unwrap();
        assert_eq!(&**pool.device() as *const _, &*device as *const _);
    }
}
<commit_msg>Fix tests<commit_after>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::mem;
use std::ptr;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::MutexGuard;

use device::Device;

use OomError;
use SynchronizedVulkanObject;
use VulkanObject;
use VulkanPointers;
use check_errors;
use vk;

/// Pool from which descriptor sets are allocated from.
///
/// A pool has a maximum number of descriptor sets and a maximum number of descriptors (one value
/// per descriptor type) it can allocate.
pub struct DescriptorPool {
    pool: Mutex<vk::DescriptorPool>,
    device: Arc<Device>,
}

impl DescriptorPool {
    /// Initializes a new pool.
    // FIXME: capacity of the pool
    pub fn new(device: &Arc<Device>) -> Result<Arc<DescriptorPool>, OomError> {
        let vk = device.pointers();

        // FIXME: arbitrary
        let pool_sizes = vec![
            vk::DescriptorPoolSize {
                ty: vk::DESCRIPTOR_TYPE_UNIFORM_BUFFER,
                descriptorCount: 10,
            },
            vk::DescriptorPoolSize {
                ty: vk::DESCRIPTOR_TYPE_STORAGE_BUFFER,
                descriptorCount: 10,
            },
            vk::DescriptorPoolSize {
                ty: vk::DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
                descriptorCount: 10,
            },
            vk::DescriptorPoolSize {
                ty: vk::DESCRIPTOR_TYPE_SAMPLED_IMAGE,
                descriptorCount: 10,
            },
            vk::DescriptorPoolSize {
                ty: vk::DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
                descriptorCount: 10,
            },
        ];

        let pool = unsafe {
            let infos = vk::DescriptorPoolCreateInfo {
                sType: vk::STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
                pNext: ptr::null(),
                flags: vk::DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,   // TODO:
                maxSets: 100,       // TODO: let user choose
                poolSizeCount: pool_sizes.len() as u32,
                pPoolSizes: pool_sizes.as_ptr(),
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreateDescriptorPool(device.internal_object(), &infos,
                                                      ptr::null(), &mut output)));
            output
        };

        Ok(Arc::new(DescriptorPool {
            pool: Mutex::new(pool),
            device: device.clone(),
        }))
    }

    /// Returns the device this pool was created from.
    #[inline]
    pub fn device(&self) -> &Arc<Device> {
        &self.device
    }
}

unsafe impl SynchronizedVulkanObject for DescriptorPool {
    type Object = vk::DescriptorPool;

    #[inline]
    fn internal_object_guard(&self) -> MutexGuard<vk::DescriptorPool> {
        self.pool.lock().unwrap()
    }
}

impl Drop for DescriptorPool {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.device.pointers();
            let pool = self.pool.lock().unwrap();
            vk.DestroyDescriptorPool(self.device.internal_object(), *pool, ptr::null());
        }
    }
}

#[cfg(test)]
mod tests {
    use descriptor::descriptor_set::DescriptorPool;

    #[test]
    fn create() {
        let (device, _) = gfx_dev_and_queue!();
        let _ = DescriptorPool::new(&device).unwrap();
    }

    #[test]
    fn device() {
        let (device, _) = gfx_dev_and_queue!();
        let pool = DescriptorPool::new(&device).unwrap();
        assert_eq!(&**pool.device() as *const _, &*device as *const _);
    }
}
<|endoftext|>


<commit_before>//! This modules implements a function to resolve a path `foo::bar::baz` to a
//! def, which is used within the name resolution.
//!
//! When name resolution is finished, the result of resolving a path is either
//! `Some(def)` or `None`. However, when we are in process of resolving imports
//! or macros, there's a third possibility:
//!
//!   I can't resolve this path right now, but I might be resolve this path
//!   later, when more macros are expanded.
//!
//! `ReachedFixedPoint` signals about this.

use base_db::Edition;
use hir_expand::name;
use hir_expand::name::Name;
use test_utils::mark;

use crate::{
    db::DefDatabase,
    item_scope::BUILTIN_SCOPE,
    nameres::{BuiltinShadowMode, DefMap},
    path::{ModPath, PathKind},
    per_ns::PerNs,
    visibility::{RawVisibility, Visibility},
    AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum ResolveMode {
    Import,
    Other,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum ReachedFixedPoint {
    Yes,
    No,
}

#[derive(Debug, Clone)]
pub(super) struct ResolvePathResult {
    pub(super) resolved_def: PerNs,
    pub(super) segment_index: Option<usize>,
    pub(super) reached_fixedpoint: ReachedFixedPoint,
    pub(super) krate: Option<CrateId>,
}

impl ResolvePathResult {
    fn empty(reached_fixedpoint: ReachedFixedPoint) -> ResolvePathResult {
        ResolvePathResult::with(PerNs::none(), reached_fixedpoint, None, None)
    }

    fn with(
        resolved_def: PerNs,
        reached_fixedpoint: ReachedFixedPoint,
        segment_index: Option<usize>,
        krate: Option<CrateId>,
    ) -> ResolvePathResult {
        ResolvePathResult { resolved_def, reached_fixedpoint, segment_index, krate }
    }
}

impl DefMap {
    pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs {
        if name == &name!(self) {
            mark::hit!(extern_crate_self_as);
            return PerNs::types(self.module_id(self.root).into(), Visibility::Public);
        }
        self.extern_prelude
            .get(name)
            .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public))
    }

    pub(crate) fn resolve_visibility(
        &self,
        db: &dyn DefDatabase,
        original_module: LocalModuleId,
        visibility: &RawVisibility,
    ) -> Option<Visibility> {
        match visibility {
            RawVisibility::Module(path) => {
                let (result, remaining) =
                    self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module);
                if remaining.is_some() {
                    return None;
                }
                let types = result.take_types()?;
                match types {
                    ModuleDefId::ModuleId(m) => Some(Visibility::Module(m)),
                    _ => {
                        // error: visibility needs to refer to module
                        None
                    }
                }
            }
            RawVisibility::Public => Some(Visibility::Public),
        }
    }

    // Returns Yes if we are sure that additions to `ItemMap` wouldn't change
    // the result.
    pub(super) fn resolve_path_fp_with_macro(
        &self,
        db: &dyn DefDatabase,
        mode: ResolveMode,
        original_module: LocalModuleId,
        path: &ModPath,
        shadow: BuiltinShadowMode,
    ) -> ResolvePathResult {
        let mut result = ResolvePathResult::empty(ReachedFixedPoint::No);
        result.segment_index = Some(usize::max_value());

        let mut current_map = self;
        loop {
            let new = current_map.resolve_path_fp_with_macro_single(
                db,
                mode,
                original_module,
                path,
                shadow,
            );

            // Merge `new` into `result`.
            result.resolved_def = result.resolved_def.or(new.resolved_def);
            if result.reached_fixedpoint == ReachedFixedPoint::No {
                result.reached_fixedpoint = new.reached_fixedpoint;
            }
            // FIXME: this doesn't seem right; what if the different namespace resolutions come from different crates?
            result.krate = result.krate.or(new.krate);
            result.segment_index = result.segment_index.min(new.segment_index);

            match &current_map.block {
                Some(block) => current_map = &block.parent,
                None => return result,
            }
        }
    }

    pub(super) fn resolve_path_fp_with_macro_single(
        &self,
        db: &dyn DefDatabase,
        mode: ResolveMode,
        original_module: LocalModuleId,
        path: &ModPath,
        shadow: BuiltinShadowMode,
    ) -> ResolvePathResult {
        let mut segments = path.segments.iter().enumerate();
        let mut curr_per_ns: PerNs = match path.kind {
            PathKind::DollarCrate(krate) => {
                if krate == self.krate {
                    mark::hit!(macro_dollar_crate_self);
                    PerNs::types(self.module_id(self.root).into(), Visibility::Public)
                } else {
                    let def_map = db.crate_def_map(krate);
                    let module = def_map.module_id(def_map.root);
                    mark::hit!(macro_dollar_crate_other);
                    PerNs::types(module.into(), Visibility::Public)
                }
            }
            PathKind::Crate => PerNs::types(self.module_id(self.root).into(), Visibility::Public),
            // plain import or absolute path in 2015: crate-relative with
            // fallback to extern prelude (with the simplification in
            // rust-lang/rust#57745)
            // FIXME there must be a nicer way to write this condition
            PathKind::Plain | PathKind::Abs
                if self.edition == Edition::Edition2015
                    && (path.kind == PathKind::Abs || mode == ResolveMode::Import) =>
            {
                let (_, segment) = match segments.next() {
                    Some((idx, segment)) => (idx, segment),
                    None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
                };
                log::debug!("resolving {:?} in crate root (+ extern prelude)", segment);
                self.resolve_name_in_crate_root_or_extern_prelude(&segment)
            }
            PathKind::Plain => {
                let (_, segment) = match segments.next() {
                    Some((idx, segment)) => (idx, segment),
                    None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
                };
                // The first segment may be a builtin type. If the path has more
                // than one segment, we first try resolving it as a module
                // anyway.
                // FIXME: If the next segment doesn't resolve in the module and
                // BuiltinShadowMode wasn't Module, then we need to try
                // resolving it as a builtin.
                let prefer_module =
                    if path.segments.len() == 1 { shadow } else { BuiltinShadowMode::Module };

                log::debug!("resolving {:?} in module", segment);
                self.resolve_name_in_module(db, original_module, &segment, prefer_module)
            }
            PathKind::Super(lvl) => {
                let mut module = original_module;
                for i in 0..lvl {
                    match self.modules[module].parent {
                        Some(it) => module = it,
                        None => match &self.block {
                            Some(block) => {
                                // Look up remaining path in parent `DefMap`
                                let new_path = ModPath {
                                    kind: PathKind::Super(lvl - i),
                                    segments: path.segments.clone(),
                                };
                                log::debug!("`super` path: {} -> {} in parent map", path, new_path);
                                return block.parent.resolve_path_fp_with_macro(
                                    db,
                                    mode,
                                    block.parent_module,
                                    &new_path,
                                    shadow,
                                );
                            }
                            None => {
                                log::debug!("super path in root module");
                                return ResolvePathResult::empty(ReachedFixedPoint::Yes);
                            }
                        },
                    }
                }

                PerNs::types(self.module_id(module).into(), Visibility::Public)
            }
            PathKind::Abs => {
                // 2018-style absolute path -- only extern prelude
                let segment = match segments.next() {
                    Some((_, segment)) => segment,
                    None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
                };
                if let Some(def) = self.extern_prelude.get(&segment) {
                    log::debug!("absolute path {:?} resolved to crate {:?}", path, def);
                    PerNs::types(*def, Visibility::Public)
                } else {
                    return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
                }
            }
        };

        for (i, segment) in segments {
            let (curr, vis) = match curr_per_ns.take_types_vis() {
                Some(r) => r,
                None => {
                    // we still have path segments left, but the path so far
                    // didn't resolve in the types namespace => no resolution
                    // (don't break here because `curr_per_ns` might contain
                    // something in the value namespace, and it would be wrong
                    // to return that)
                    return ResolvePathResult::empty(ReachedFixedPoint::No);
                }
            };
            // resolve segment in curr

            curr_per_ns = match curr {
                ModuleDefId::ModuleId(module) => {
                    if module.krate != self.krate {
                        let path = ModPath {
                            segments: path.segments[i..].to_vec(),
                            kind: PathKind::Super(0),
                        };
                        log::debug!("resolving {:?} in other crate", path);
                        let defp_map = module.def_map(db);
                        let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow);
                        return ResolvePathResult::with(
                            def,
                            ReachedFixedPoint::Yes,
                            s.map(|s| s + i),
                            Some(module.krate),
                        );
                    }

                    // Since it is a qualified path here, it should not contains legacy macros
                    self[module.local_id].scope.get(&segment)
                }
                ModuleDefId::AdtId(AdtId::EnumId(e)) => {
                    // enum variant
                    mark::hit!(can_import_enum_variant);
                    let enum_data = db.enum_data(e);
                    match enum_data.variant(&segment) {
                        Some(local_id) => {
                            let variant = EnumVariantId { parent: e, local_id };
                            match &*enum_data.variants[local_id].variant_data {
                                crate::adt::VariantData::Record(_) => {
                                    PerNs::types(variant.into(), Visibility::Public)
                                }
                                crate::adt::VariantData::Tuple(_)
                                | crate::adt::VariantData::Unit => {
                                    PerNs::both(variant.into(), variant.into(), Visibility::Public)
                                }
                            }
                        }
                        None => {
                            return ResolvePathResult::with(
                                PerNs::types(e.into(), vis),
                                ReachedFixedPoint::Yes,
                                Some(i),
                                Some(self.krate),
                            );
                        }
                    }
                }
                s => {
                    // could be an inherent method call in UFCS form
                    // (`Struct::method`), or some other kind of associated item
                    log::debug!(
                        "path segment {:?} resolved to non-module {:?}, but is not last",
                        segment,
                        curr,
                    );

                    return ResolvePathResult::with(
                        PerNs::types(s, vis),
                        ReachedFixedPoint::Yes,
                        Some(i),
                        Some(self.krate),
                    );
                }
            };
        }

        ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None, Some(self.krate))
    }

    fn resolve_name_in_module(
        &self,
        db: &dyn DefDatabase,
        module: LocalModuleId,
        name: &Name,
        shadow: BuiltinShadowMode,
    ) -> PerNs {
        // Resolve in:
        //  - legacy scope of macro
        //  - current module / scope
        //  - extern prelude
        //  - std prelude
        let from_legacy_macro = self[module]
            .scope
            .get_legacy_macro(name)
            .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public));
        let from_scope = self[module].scope.get(name);
        let from_builtin = BUILTIN_SCOPE.get(name).copied().unwrap_or_else(PerNs::none);
        let from_scope_or_builtin = match shadow {
            BuiltinShadowMode::Module => from_scope.or(from_builtin),
            BuiltinShadowMode::Other => {
                if let Some(ModuleDefId::ModuleId(_)) = from_scope.take_types() {
                    from_builtin.or(from_scope)
                } else {
                    from_scope.or(from_builtin)
                }
            }
        };
        let from_extern_prelude = self
            .extern_prelude
            .get(name)
            .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public));
        let from_prelude = self.resolve_in_prelude(db, name);

        from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude)
    }

    fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> PerNs {
        let from_crate_root = self[self.root].scope.get(name);
        let from_extern_prelude = self.resolve_name_in_extern_prelude(name);

        from_crate_root.or(from_extern_prelude)
    }

    fn resolve_in_prelude(&self, db: &dyn DefDatabase, name: &Name) -> PerNs {
        if let Some(prelude) = self.prelude {
            let keep;
            let def_map = if prelude.krate == self.krate {
                self
            } else {
                // Extend lifetime
                keep = prelude.def_map(db);
                &keep
            };
            def_map[prelude.local_id].scope.get(name)
        } else {
            PerNs::none()
        }
    }
}
<commit_msg>Update `original_module` when ascending `DefMap`s<commit_after>//! This modules implements a function to resolve a path `foo::bar::baz` to a
//! def, which is used within the name resolution.
//!
//! When name resolution is finished, the result of resolving a path is either
//! `Some(def)` or `None`. However, when we are in process of resolving imports
//! or macros, there's a third possibility:
//!
//!   I can't resolve this path right now, but I might be resolve this path
//!   later, when more macros are expanded.
//!
//! `ReachedFixedPoint` signals about this.

use base_db::Edition;
use hir_expand::name;
use hir_expand::name::Name;
use test_utils::mark;

use crate::{
    db::DefDatabase,
    item_scope::BUILTIN_SCOPE,
    nameres::{BuiltinShadowMode, DefMap},
    path::{ModPath, PathKind},
    per_ns::PerNs,
    visibility::{RawVisibility, Visibility},
    AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum ResolveMode {
    Import,
    Other,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum ReachedFixedPoint {
    Yes,
    No,
}

#[derive(Debug, Clone)]
pub(super) struct ResolvePathResult {
    pub(super) resolved_def: PerNs,
    pub(super) segment_index: Option<usize>,
    pub(super) reached_fixedpoint: ReachedFixedPoint,
    pub(super) krate: Option<CrateId>,
}

impl ResolvePathResult {
    fn empty(reached_fixedpoint: ReachedFixedPoint) -> ResolvePathResult {
        ResolvePathResult::with(PerNs::none(), reached_fixedpoint, None, None)
    }

    fn with(
        resolved_def: PerNs,
        reached_fixedpoint: ReachedFixedPoint,
        segment_index: Option<usize>,
        krate: Option<CrateId>,
    ) -> ResolvePathResult {
        ResolvePathResult { resolved_def, reached_fixedpoint, segment_index, krate }
    }
}

impl DefMap {
    pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs {
        if name == &name!(self) {
            mark::hit!(extern_crate_self_as);
            return PerNs::types(self.module_id(self.root).into(), Visibility::Public);
        }
        self.extern_prelude
            .get(name)
            .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public))
    }

    pub(crate) fn resolve_visibility(
        &self,
        db: &dyn DefDatabase,
        original_module: LocalModuleId,
        visibility: &RawVisibility,
    ) -> Option<Visibility> {
        match visibility {
            RawVisibility::Module(path) => {
                let (result, remaining) =
                    self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module);
                if remaining.is_some() {
                    return None;
                }
                let types = result.take_types()?;
                match types {
                    ModuleDefId::ModuleId(m) => Some(Visibility::Module(m)),
                    _ => {
                        // error: visibility needs to refer to module
                        None
                    }
                }
            }
            RawVisibility::Public => Some(Visibility::Public),
        }
    }

    // Returns Yes if we are sure that additions to `ItemMap` wouldn't change
    // the result.
    pub(super) fn resolve_path_fp_with_macro(
        &self,
        db: &dyn DefDatabase,
        mode: ResolveMode,
        mut original_module: LocalModuleId,
        path: &ModPath,
        shadow: BuiltinShadowMode,
    ) -> ResolvePathResult {
        let mut result = ResolvePathResult::empty(ReachedFixedPoint::No);
        result.segment_index = Some(usize::max_value());

        let mut current_map = self;
        loop {
            let new = current_map.resolve_path_fp_with_macro_single(
                db,
                mode,
                original_module,
                path,
                shadow,
            );

            // Merge `new` into `result`.
            result.resolved_def = result.resolved_def.or(new.resolved_def);
            if result.reached_fixedpoint == ReachedFixedPoint::No {
                result.reached_fixedpoint = new.reached_fixedpoint;
            }
            // FIXME: this doesn't seem right; what if the different namespace resolutions come from different crates?
            result.krate = result.krate.or(new.krate);
            result.segment_index = result.segment_index.min(new.segment_index);

            match &current_map.block {
                Some(block) => {
                    current_map = &block.parent;
                    original_module = block.parent_module;
                }
                None => return result,
            }
        }
    }

    pub(super) fn resolve_path_fp_with_macro_single(
        &self,
        db: &dyn DefDatabase,
        mode: ResolveMode,
        original_module: LocalModuleId,
        path: &ModPath,
        shadow: BuiltinShadowMode,
    ) -> ResolvePathResult {
        let mut segments = path.segments.iter().enumerate();
        let mut curr_per_ns: PerNs = match path.kind {
            PathKind::DollarCrate(krate) => {
                if krate == self.krate {
                    mark::hit!(macro_dollar_crate_self);
                    PerNs::types(self.module_id(self.root).into(), Visibility::Public)
                } else {
                    let def_map = db.crate_def_map(krate);
                    let module = def_map.module_id(def_map.root);
                    mark::hit!(macro_dollar_crate_other);
                    PerNs::types(module.into(), Visibility::Public)
                }
            }
            PathKind::Crate => PerNs::types(self.module_id(self.root).into(), Visibility::Public),
            // plain import or absolute path in 2015: crate-relative with
            // fallback to extern prelude (with the simplification in
            // rust-lang/rust#57745)
            // FIXME there must be a nicer way to write this condition
            PathKind::Plain | PathKind::Abs
                if self.edition == Edition::Edition2015
                    && (path.kind == PathKind::Abs || mode == ResolveMode::Import) =>
            {
                let (_, segment) = match segments.next() {
                    Some((idx, segment)) => (idx, segment),
                    None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
                };
                log::debug!("resolving {:?} in crate root (+ extern prelude)", segment);
                self.resolve_name_in_crate_root_or_extern_prelude(&segment)
            }
            PathKind::Plain => {
                let (_, segment) = match segments.next() {
                    Some((idx, segment)) => (idx, segment),
                    None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
                };
                // The first segment may be a builtin type. If the path has more
                // than one segment, we first try resolving it as a module
                // anyway.
                // FIXME: If the next segment doesn't resolve in the module and
                // BuiltinShadowMode wasn't Module, then we need to try
                // resolving it as a builtin.
                let prefer_module =
                    if path.segments.len() == 1 { shadow } else { BuiltinShadowMode::Module };

                log::debug!("resolving {:?} in module", segment);
                self.resolve_name_in_module(db, original_module, &segment, prefer_module)
            }
            PathKind::Super(lvl) => {
                let mut module = original_module;
                for i in 0..lvl {
                    match self.modules[module].parent {
                        Some(it) => module = it,
                        None => match &self.block {
                            Some(block) => {
                                // Look up remaining path in parent `DefMap`
                                let new_path = ModPath {
                                    kind: PathKind::Super(lvl - i),
                                    segments: path.segments.clone(),
                                };
                                log::debug!("`super` path: {} -> {} in parent map", path, new_path);
                                return block.parent.resolve_path_fp_with_macro(
                                    db,
                                    mode,
                                    block.parent_module,
                                    &new_path,
                                    shadow,
                                );
                            }
                            None => {
                                log::debug!("super path in root module");
                                return ResolvePathResult::empty(ReachedFixedPoint::Yes);
                            }
                        },
                    }
                }

                PerNs::types(self.module_id(module).into(), Visibility::Public)
            }
            PathKind::Abs => {
                // 2018-style absolute path -- only extern prelude
                let segment = match segments.next() {
                    Some((_, segment)) => segment,
                    None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
                };
                if let Some(def) = self.extern_prelude.get(&segment) {
                    log::debug!("absolute path {:?} resolved to crate {:?}", path, def);
                    PerNs::types(*def, Visibility::Public)
                } else {
                    return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
                }
            }
        };

        for (i, segment) in segments {
            let (curr, vis) = match curr_per_ns.take_types_vis() {
                Some(r) => r,
                None => {
                    // we still have path segments left, but the path so far
                    // didn't resolve in the types namespace => no resolution
                    // (don't break here because `curr_per_ns` might contain
                    // something in the value namespace, and it would be wrong
                    // to return that)
                    return ResolvePathResult::empty(ReachedFixedPoint::No);
                }
            };
            // resolve segment in curr

            curr_per_ns = match curr {
                ModuleDefId::ModuleId(module) => {
                    if module.krate != self.krate {
                        let path = ModPath {
                            segments: path.segments[i..].to_vec(),
                            kind: PathKind::Super(0),
                        };
                        log::debug!("resolving {:?} in other crate", path);
                        let defp_map = module.def_map(db);
                        let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow);
                        return ResolvePathResult::with(
                            def,
                            ReachedFixedPoint::Yes,
                            s.map(|s| s + i),
                            Some(module.krate),
                        );
                    }

                    // Since it is a qualified path here, it should not contains legacy macros
                    self[module.local_id].scope.get(&segment)
                }
                ModuleDefId::AdtId(AdtId::EnumId(e)) => {
                    // enum variant
                    mark::hit!(can_import_enum_variant);
                    let enum_data = db.enum_data(e);
                    match enum_data.variant(&segment) {
                        Some(local_id) => {
                            let variant = EnumVariantId { parent: e, local_id };
                            match &*enum_data.variants[local_id].variant_data {
                                crate::adt::VariantData::Record(_) => {
                                    PerNs::types(variant.into(), Visibility::Public)
                                }
                                crate::adt::VariantData::Tuple(_)
                                | crate::adt::VariantData::Unit => {
                                    PerNs::both(variant.into(), variant.into(), Visibility::Public)
                                }
                            }
                        }
                        None => {
                            return ResolvePathResult::with(
                                PerNs::types(e.into(), vis),
                                ReachedFixedPoint::Yes,
                                Some(i),
                                Some(self.krate),
                            );
                        }
                    }
                }
                s => {
                    // could be an inherent method call in UFCS form
                    // (`Struct::method`), or some other kind of associated item
                    log::debug!(
                        "path segment {:?} resolved to non-module {:?}, but is not last",
                        segment,
                        curr,
                    );

                    return ResolvePathResult::with(
                        PerNs::types(s, vis),
                        ReachedFixedPoint::Yes,
                        Some(i),
                        Some(self.krate),
                    );
                }
            };
        }

        ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None, Some(self.krate))
    }

    fn resolve_name_in_module(
        &self,
        db: &dyn DefDatabase,
        module: LocalModuleId,
        name: &Name,
        shadow: BuiltinShadowMode,
    ) -> PerNs {
        // Resolve in:
        //  - legacy scope of macro
        //  - current module / scope
        //  - extern prelude
        //  - std prelude
        let from_legacy_macro = self[module]
            .scope
            .get_legacy_macro(name)
            .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public));
        let from_scope = self[module].scope.get(name);
        let from_builtin = BUILTIN_SCOPE.get(name).copied().unwrap_or_else(PerNs::none);
        let from_scope_or_builtin = match shadow {
            BuiltinShadowMode::Module => from_scope.or(from_builtin),
            BuiltinShadowMode::Other => {
                if let Some(ModuleDefId::ModuleId(_)) = from_scope.take_types() {
                    from_builtin.or(from_scope)
                } else {
                    from_scope.or(from_builtin)
                }
            }
        };
        let from_extern_prelude = self
            .extern_prelude
            .get(name)
            .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public));
        let from_prelude = self.resolve_in_prelude(db, name);

        from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude)
    }

    fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> PerNs {
        let from_crate_root = self[self.root].scope.get(name);
        let from_extern_prelude = self.resolve_name_in_extern_prelude(name);

        from_crate_root.or(from_extern_prelude)
    }

    fn resolve_in_prelude(&self, db: &dyn DefDatabase, name: &Name) -> PerNs {
        if let Some(prelude) = self.prelude {
            let keep;
            let def_map = if prelude.krate == self.krate {
                self
            } else {
                // Extend lifetime
                keep = prelude.def_map(db);
                &keep
            };
            def_map[prelude.local_id].scope.get(name)
        } else {
            PerNs::none()
        }
    }
}
<|endoftext|>


<commit_before>use std::sync::mpsc::Sender;

use event::{Action, Key, Modifiers, MouseButton, WindowEvent};
use gl;
use glutin::{
    self, dpi::LogicalSize, ContextBuilder, EventsLoop, GlContext, GlRequest, GlWindow,
    WindowBuilder,
};
use window::AbstractCanvas;

/// A canvas based on glutin and OpenGL.
pub struct GLCanvas {
    window: GlWindow,
    events: EventsLoop,
    key_states: [Action; Key::Unknown as usize + 1],
    button_states: [Action; MouseButton::Button8 as usize + 1],
    out_events: Sender<WindowEvent>,
    // listeners: Vec<EventListenerHandle>,
}

impl AbstractCanvas for GLCanvas {
    fn open(
        title: &str,
        hide: bool,
        width: u32,
        height: u32,
        out_events: Sender<WindowEvent>,
    ) -> Self {
        let events = EventsLoop::new();
        let window = WindowBuilder::new()
            .with_title(title)
            .with_dimensions(LogicalSize::new(width as f64, height as f64))
            .with_visibility(!hide);
        let context = ContextBuilder::new()
            .with_vsync(true)
            .with_gl(GlRequest::GlThenGles {
                opengl_version: (3, 2),
                opengles_version: (2, 0),
            });
        let window = GlWindow::new(window, context, &events).unwrap();
        let _ = unsafe { window.make_current().unwrap() };
        verify!(gl::load_with(
            |name| window.context().get_proc_address(name) as *const _
        ));

        unsafe {
            // Setup a single VAO.
            let mut vao = 0;
            gl::GenVertexArrays(1, &mut vao);
            gl::BindVertexArray(vao);
        }

        GLCanvas {
            window,
            events,
            key_states: [Action::Release; Key::Unknown as usize + 1],
            button_states: [Action::Release; MouseButton::Button8 as usize + 1],
            out_events,
        }
    }

    fn render_loop(mut callback: impl FnMut(f64) -> bool + 'static) {
        loop {
            if !callback(0.0) {
                break;
            } // XXX: timestamp
        }
    }

    fn poll_events(&mut self) {
        let out_events = &mut self.out_events;
        let window = &mut self.window;
        let button_states = &mut self.button_states;
        let key_states = &mut self.key_states;

        self.events.poll_events(|event| match event {
            glutin::Event::WindowEvent { event, .. } => match event {
                glutin::WindowEvent::CloseRequested => {
                    let _ = out_events.send(WindowEvent::Close);
                }
                glutin::WindowEvent::Resized(logical_size) => {
                    let dpi_factor = window.get_hidpi_factor();
                    let physical_size = logical_size.to_physical(dpi_factor);
                    window.resize(physical_size);
                    let fb_size: (u32, u32) = physical_size.into();
                    let _ = out_events.send(WindowEvent::FramebufferSize(fb_size.0, fb_size.1));
                }
                glutin::WindowEvent::CursorMoved {
                    position,
                    modifiers,
                    ..
                } => {
                    let modifiers = translate_modifiers(modifiers);
                    let _ =
                        out_events.send(WindowEvent::CursorPos(position.x, position.y, modifiers));
                }
                glutin::WindowEvent::MouseInput {
                    state,
                    button,
                    modifiers,
                    ..
                } => {
                    let action = translate_action(state);
                    let button = translate_mouse_button(button);
                    let modifiers = translate_modifiers(modifiers);
                    button_states[button as usize] = action;
                    let _ = out_events.send(WindowEvent::MouseButton(button, action, modifiers));
                }
                glutin::WindowEvent::MouseWheel {
                    delta, modifiers, ..
                } => {
                    let (x, y) = match delta {
                        glutin::MouseScrollDelta::LineDelta(dx, dy) => (dx as f64, dy as f64),
                        glutin::MouseScrollDelta::PixelDelta(delta) => delta.into(),
                    };
                    let modifiers = translate_modifiers(modifiers);
                    let _ = out_events.send(WindowEvent::Scroll(x, y, modifiers));
                }
                glutin::WindowEvent::KeyboardInput { input, .. } => {
                    let action = translate_action(input.state);
                    let key = translate_key(input.virtual_keycode);
                    let modifiers = translate_modifiers(input.modifiers);
                    key_states[key as usize] = action;
                    let _ = out_events.send(WindowEvent::Key(key, action, modifiers));
                }
                _ => {}
            },
            _ => {}
        })
    }

    fn swap_buffers(&mut self) {
        let _ = self.window.swap_buffers();
    }

    fn size(&self) -> (u32, u32) {
        let hidpi = self.window.get_hidpi_factor();
        let logical_size = self
            .window
            .get_inner_size()
            .expect("The window was closed.");
        logical_size.to_physical(hidpi).into()
    }

    fn hidpi_factor(&self) -> f64 {
        self.window.get_hidpi_factor() as f64
    }

    fn set_title(&mut self, title: &str) {
        self.window.set_title(title)
    }

    fn hide(&mut self) {
        self.window.hide()
    }

    fn show(&mut self) {
        self.window.show()
    }

    fn get_mouse_button(&self, button: MouseButton) -> Action {
        self.button_states[button as usize]
    }
    fn get_key(&self, key: Key) -> Action {
        self.key_states[key as usize]
    }
}

fn translate_action(action: glutin::ElementState) -> Action {
    match action {
        glutin::ElementState::Pressed => Action::Press,
        glutin::ElementState::Released => Action::Release,
    }
}

fn translate_modifiers(modifiers: glutin::ModifiersState) -> Modifiers {
    let mut res = Modifiers::empty();
    if modifiers.shift {
        res.insert(Modifiers::Shift)
    }
    if modifiers.ctrl {
        res.insert(Modifiers::Control)
    }
    if modifiers.alt {
        res.insert(Modifiers::Alt)
    }
    if modifiers.logo {
        res.insert(Modifiers::Super)
    }

    res
}

fn translate_mouse_button(button: glutin::MouseButton) -> MouseButton {
    match button {
        glutin::MouseButton::Left => MouseButton::Button1,
        glutin::MouseButton::Right => MouseButton::Button2,
        glutin::MouseButton::Middle => MouseButton::Button3,
        glutin::MouseButton::Other(_) => MouseButton::Button4, // XXX: the default is not good.
    }
}

fn translate_key(button: Option<glutin::VirtualKeyCode>) -> Key {
    if let Some(button) = button {
        match button {
            glutin::VirtualKeyCode::Key1 => Key::Key1,
            glutin::VirtualKeyCode::Key2 => Key::Key2,
            glutin::VirtualKeyCode::Key3 => Key::Key3,
            glutin::VirtualKeyCode::Key4 => Key::Key4,
            glutin::VirtualKeyCode::Key5 => Key::Key5,
            glutin::VirtualKeyCode::Key6 => Key::Key6,
            glutin::VirtualKeyCode::Key7 => Key::Key7,
            glutin::VirtualKeyCode::Key8 => Key::Key8,
            glutin::VirtualKeyCode::Key9 => Key::Key9,
            glutin::VirtualKeyCode::Key0 => Key::Key0,
            glutin::VirtualKeyCode::A => Key::A,
            glutin::VirtualKeyCode::B => Key::B,
            glutin::VirtualKeyCode::C => Key::C,
            glutin::VirtualKeyCode::D => Key::V,
            glutin::VirtualKeyCode::E => Key::E,
            glutin::VirtualKeyCode::F => Key::F,
            glutin::VirtualKeyCode::G => Key::G,
            glutin::VirtualKeyCode::H => Key::H,
            glutin::VirtualKeyCode::I => Key::I,
            glutin::VirtualKeyCode::J => Key::J,
            glutin::VirtualKeyCode::K => Key::K,
            glutin::VirtualKeyCode::L => Key::L,
            glutin::VirtualKeyCode::M => Key::M,
            glutin::VirtualKeyCode::N => Key::N,
            glutin::VirtualKeyCode::O => Key::O,
            glutin::VirtualKeyCode::P => Key::P,
            glutin::VirtualKeyCode::Q => Key::Q,
            glutin::VirtualKeyCode::R => Key::R,
            glutin::VirtualKeyCode::S => Key::S,
            glutin::VirtualKeyCode::T => Key::T,
            glutin::VirtualKeyCode::U => Key::U,
            glutin::VirtualKeyCode::V => Key::V,
            glutin::VirtualKeyCode::W => Key::W,
            glutin::VirtualKeyCode::X => Key::X,
            glutin::VirtualKeyCode::Y => Key::Y,
            glutin::VirtualKeyCode::Z => Key::Z,
            glutin::VirtualKeyCode::Escape => Key::Escape,
            glutin::VirtualKeyCode::F1 => Key::F1,
            glutin::VirtualKeyCode::F2 => Key::F2,
            glutin::VirtualKeyCode::F3 => Key::F3,
            glutin::VirtualKeyCode::F4 => Key::F4,
            glutin::VirtualKeyCode::F5 => Key::F5,
            glutin::VirtualKeyCode::F6 => Key::F6,
            glutin::VirtualKeyCode::F7 => Key::F7,
            glutin::VirtualKeyCode::F8 => Key::F8,
            glutin::VirtualKeyCode::F9 => Key::F9,
            glutin::VirtualKeyCode::F10 => Key::F10,
            glutin::VirtualKeyCode::F11 => Key::F11,
            glutin::VirtualKeyCode::F12 => Key::F12,
            glutin::VirtualKeyCode::F13 => Key::F13,
            glutin::VirtualKeyCode::F14 => Key::F14,
            glutin::VirtualKeyCode::F15 => Key::F15,
            glutin::VirtualKeyCode::Snapshot => Key::Snapshot,
            glutin::VirtualKeyCode::Scroll => Key::Scroll,
            glutin::VirtualKeyCode::Pause => Key::Pause,
            glutin::VirtualKeyCode::Insert => Key::Insert,
            glutin::VirtualKeyCode::Home => Key::Home,
            glutin::VirtualKeyCode::Delete => Key::Delete,
            glutin::VirtualKeyCode::End => Key::End,
            glutin::VirtualKeyCode::PageDown => Key::PageDown,
            glutin::VirtualKeyCode::PageUp => Key::PageUp,
            glutin::VirtualKeyCode::Left => Key::Left,
            glutin::VirtualKeyCode::Up => Key::Up,
            glutin::VirtualKeyCode::Right => Key::Right,
            glutin::VirtualKeyCode::Down => Key::Down,
            glutin::VirtualKeyCode::Back => Key::Back,
            glutin::VirtualKeyCode::Return => Key::Return,
            glutin::VirtualKeyCode::Space => Key::Space,
            glutin::VirtualKeyCode::Compose => Key::Compose,
            glutin::VirtualKeyCode::Caret => Key::Caret,
            glutin::VirtualKeyCode::Numlock => Key::Numlock,
            glutin::VirtualKeyCode::Numpad0 => Key::Numpad0,
            glutin::VirtualKeyCode::Numpad1 => Key::Numpad1,
            glutin::VirtualKeyCode::Numpad2 => Key::Numpad2,
            glutin::VirtualKeyCode::Numpad3 => Key::Numpad3,
            glutin::VirtualKeyCode::Numpad4 => Key::Numpad4,
            glutin::VirtualKeyCode::Numpad5 => Key::Numpad5,
            glutin::VirtualKeyCode::Numpad6 => Key::Numpad6,
            glutin::VirtualKeyCode::Numpad7 => Key::Numpad7,
            glutin::VirtualKeyCode::Numpad8 => Key::Numpad8,
            glutin::VirtualKeyCode::Numpad9 => Key::Numpad9,
            glutin::VirtualKeyCode::AbntC1 => Key::AbntC1,
            glutin::VirtualKeyCode::AbntC2 => Key::AbntC2,
            glutin::VirtualKeyCode::Add => Key::Add,
            glutin::VirtualKeyCode::Apostrophe => Key::Apostrophe,
            glutin::VirtualKeyCode::Apps => Key::Apps,
            glutin::VirtualKeyCode::At => Key::At,
            glutin::VirtualKeyCode::Ax => Key::Ax,
            glutin::VirtualKeyCode::Backslash => Key::Backslash,
            glutin::VirtualKeyCode::Calculator => Key::Calculator,
            glutin::VirtualKeyCode::Capital => Key::Capital,
            glutin::VirtualKeyCode::Colon => Key::Colon,
            glutin::VirtualKeyCode::Comma => Key::Comma,
            glutin::VirtualKeyCode::Convert => Key::Convert,
            glutin::VirtualKeyCode::Decimal => Key::Decimal,
            glutin::VirtualKeyCode::Divide => Key::Divide,
            glutin::VirtualKeyCode::Equals => Key::Equals,
            glutin::VirtualKeyCode::Grave => Key::Grave,
            glutin::VirtualKeyCode::Kana => Key::Kana,
            glutin::VirtualKeyCode::Kanji => Key::Kanji,
            glutin::VirtualKeyCode::LAlt => Key::LAlt,
            glutin::VirtualKeyCode::LBracket => Key::LBracket,
            glutin::VirtualKeyCode::LControl => Key::LControl,
            glutin::VirtualKeyCode::LShift => Key::LShift,
            glutin::VirtualKeyCode::LWin => Key::LWin,
            glutin::VirtualKeyCode::Mail => Key::Mail,
            glutin::VirtualKeyCode::MediaSelect => Key::MediaSelect,
            glutin::VirtualKeyCode::MediaStop => Key::MediaStop,
            glutin::VirtualKeyCode::Minus => Key::Minus,
            glutin::VirtualKeyCode::Multiply => Key::Multiply,
            glutin::VirtualKeyCode::Mute => Key::Mute,
            glutin::VirtualKeyCode::MyComputer => Key::MyComputer,
            glutin::VirtualKeyCode::NavigateForward => Key::NavigateForward,
            glutin::VirtualKeyCode::NavigateBackward => Key::NavigateBackward,
            glutin::VirtualKeyCode::NextTrack => Key::NextTrack,
            glutin::VirtualKeyCode::NoConvert => Key::NoConvert,
            glutin::VirtualKeyCode::NumpadComma => Key::NumpadComma,
            glutin::VirtualKeyCode::NumpadEnter => Key::NumpadEnter,
            glutin::VirtualKeyCode::NumpadEquals => Key::NumpadEquals,
            glutin::VirtualKeyCode::OEM102 => Key::OEM102,
            glutin::VirtualKeyCode::Period => Key::Period,
            glutin::VirtualKeyCode::PlayPause => Key::PlayPause,
            glutin::VirtualKeyCode::Power => Key::Power,
            glutin::VirtualKeyCode::PrevTrack => Key::PrevTrack,
            glutin::VirtualKeyCode::RAlt => Key::RAlt,
            glutin::VirtualKeyCode::RBracket => Key::RBracket,
            glutin::VirtualKeyCode::RControl => Key::RControl,
            glutin::VirtualKeyCode::RShift => Key::RShift,
            glutin::VirtualKeyCode::RWin => Key::RWin,
            glutin::VirtualKeyCode::Semicolon => Key::Semicolon,
            glutin::VirtualKeyCode::Slash => Key::Slash,
            glutin::VirtualKeyCode::Sleep => Key::Sleep,
            glutin::VirtualKeyCode::Stop => Key::Stop,
            glutin::VirtualKeyCode::Subtract => Key::Subtract,
            glutin::VirtualKeyCode::Sysrq => Key::Sysrq,
            glutin::VirtualKeyCode::Tab => Key::Tab,
            glutin::VirtualKeyCode::Underline => Key::Underline,
            glutin::VirtualKeyCode::Unlabeled => Key::Unlabeled,
            glutin::VirtualKeyCode::VolumeDown => Key::VolumeDown,
            glutin::VirtualKeyCode::VolumeUp => Key::VolumeUp,
            glutin::VirtualKeyCode::Wake => Key::Wake,
            glutin::VirtualKeyCode::WebBack => Key::WebBack,
            glutin::VirtualKeyCode::WebFavorites => Key::WebFavorites,
            glutin::VirtualKeyCode::WebForward => Key::WebForward,
            glutin::VirtualKeyCode::WebHome => Key::WebHome,
            glutin::VirtualKeyCode::WebRefresh => Key::WebRefresh,
            glutin::VirtualKeyCode::WebSearch => Key::WebSearch,
            glutin::VirtualKeyCode::WebStop => Key::WebStop,
            glutin::VirtualKeyCode::Yen => Key::Yen,
            glutin::VirtualKeyCode::Copy => Key::Copy,
            glutin::VirtualKeyCode::Paste => Key::Paste,
            glutin::VirtualKeyCode::Cut => Key::Cut,
        }
    } else {
        Key::Unknown
    }
}
<commit_msg>Fix mouse event mouse coordinates.<commit_after>use std::sync::mpsc::Sender;

use event::{Action, Key, Modifiers, MouseButton, WindowEvent};
use gl;
use glutin::{
    self, dpi::LogicalSize, ContextBuilder, EventsLoop, GlContext, GlRequest, GlWindow,
    WindowBuilder,
};
use window::AbstractCanvas;

/// A canvas based on glutin and OpenGL.
pub struct GLCanvas {
    window: GlWindow,
    events: EventsLoop,
    key_states: [Action; Key::Unknown as usize + 1],
    button_states: [Action; MouseButton::Button8 as usize + 1],
    out_events: Sender<WindowEvent>,
    // listeners: Vec<EventListenerHandle>,
}

impl AbstractCanvas for GLCanvas {
    fn open(
        title: &str,
        hide: bool,
        width: u32,
        height: u32,
        out_events: Sender<WindowEvent>,
    ) -> Self {
        let events = EventsLoop::new();
        let window = WindowBuilder::new()
            .with_title(title)
            .with_dimensions(LogicalSize::new(width as f64, height as f64))
            .with_visibility(!hide);
        let context = ContextBuilder::new()
            .with_vsync(true)
            .with_gl(GlRequest::GlThenGles {
                opengl_version: (3, 2),
                opengles_version: (2, 0),
            });
        let window = GlWindow::new(window, context, &events).unwrap();
        let _ = unsafe { window.make_current().unwrap() };
        verify!(gl::load_with(
            |name| window.context().get_proc_address(name) as *const _
        ));

        unsafe {
            // Setup a single VAO.
            let mut vao = 0;
            gl::GenVertexArrays(1, &mut vao);
            gl::BindVertexArray(vao);
        }

        GLCanvas {
            window,
            events,
            key_states: [Action::Release; Key::Unknown as usize + 1],
            button_states: [Action::Release; MouseButton::Button8 as usize + 1],
            out_events,
        }
    }

    fn render_loop(mut callback: impl FnMut(f64) -> bool + 'static) {
        loop {
            if !callback(0.0) {
                break;
            } // XXX: timestamp
        }
    }

    fn poll_events(&mut self) {
        let out_events = &mut self.out_events;
        let window = &mut self.window;
        let button_states = &mut self.button_states;
        let key_states = &mut self.key_states;

        self.events.poll_events(|event| match event {
            glutin::Event::WindowEvent { event, .. } => match event {
                glutin::WindowEvent::CloseRequested => {
                    let _ = out_events.send(WindowEvent::Close);
                }
                glutin::WindowEvent::Resized(logical_size) => {
                    let dpi_factor = window.get_hidpi_factor();
                    let physical_size = logical_size.to_physical(dpi_factor);
                    window.resize(physical_size);
                    let fb_size: (u32, u32) = physical_size.into();
                    let _ = out_events.send(WindowEvent::FramebufferSize(fb_size.0, fb_size.1));
                }
                glutin::WindowEvent::CursorMoved {
                    position,
                    modifiers,
                    ..
                } => {
                    let modifiers = translate_modifiers(modifiers);
                    let dpi_factor = window.get_hidpi_factor();
                    let physical_pos = position.to_physical(dpi_factor);
                    let _ =
                        out_events.send(WindowEvent::CursorPos(physical_pos.x, physical_pos.y, modifiers));
                }
                glutin::WindowEvent::MouseInput {
                    state,
                    button,
                    modifiers,
                    ..
                } => {
                    let action = translate_action(state);
                    let button = translate_mouse_button(button);
                    let modifiers = translate_modifiers(modifiers);
                    button_states[button as usize] = action;
                    let _ = out_events.send(WindowEvent::MouseButton(button, action, modifiers));
                }
                glutin::WindowEvent::MouseWheel {
                    delta, modifiers, ..
                } => {
                    let (x, y) = match delta {
                        glutin::MouseScrollDelta::LineDelta(dx, dy) => (dx as f64, dy as f64),
                        glutin::MouseScrollDelta::PixelDelta(delta) => delta.into(),
                    };
                    let modifiers = translate_modifiers(modifiers);
                    let _ = out_events.send(WindowEvent::Scroll(x, y, modifiers));
                }
                glutin::WindowEvent::KeyboardInput { input, .. } => {
                    let action = translate_action(input.state);
                    let key = translate_key(input.virtual_keycode);
                    let modifiers = translate_modifiers(input.modifiers);
                    key_states[key as usize] = action;
                    let _ = out_events.send(WindowEvent::Key(key, action, modifiers));
                }
                _ => {}
            },
            _ => {}
        })
    }

    fn swap_buffers(&mut self) {
        let _ = self.window.swap_buffers();
    }

    fn size(&self) -> (u32, u32) {
        let hidpi = self.window.get_hidpi_factor();
        let logical_size = self
            .window
            .get_inner_size()
            .expect("The window was closed.");
        logical_size.to_physical(hidpi).into()
    }

    fn hidpi_factor(&self) -> f64 {
        self.window.get_hidpi_factor() as f64
    }

    fn set_title(&mut self, title: &str) {
        self.window.set_title(title)
    }

    fn hide(&mut self) {
        self.window.hide()
    }

    fn show(&mut self) {
        self.window.show()
    }

    fn get_mouse_button(&self, button: MouseButton) -> Action {
        self.button_states[button as usize]
    }
    fn get_key(&self, key: Key) -> Action {
        self.key_states[key as usize]
    }
}

fn translate_action(action: glutin::ElementState) -> Action {
    match action {
        glutin::ElementState::Pressed => Action::Press,
        glutin::ElementState::Released => Action::Release,
    }
}

fn translate_modifiers(modifiers: glutin::ModifiersState) -> Modifiers {
    let mut res = Modifiers::empty();
    if modifiers.shift {
        res.insert(Modifiers::Shift)
    }
    if modifiers.ctrl {
        res.insert(Modifiers::Control)
    }
    if modifiers.alt {
        res.insert(Modifiers::Alt)
    }
    if modifiers.logo {
        res.insert(Modifiers::Super)
    }

    res
}

fn translate_mouse_button(button: glutin::MouseButton) -> MouseButton {
    match button {
        glutin::MouseButton::Left => MouseButton::Button1,
        glutin::MouseButton::Right => MouseButton::Button2,
        glutin::MouseButton::Middle => MouseButton::Button3,
        glutin::MouseButton::Other(_) => MouseButton::Button4, // XXX: the default is not good.
    }
}

fn translate_key(button: Option<glutin::VirtualKeyCode>) -> Key {
    if let Some(button) = button {
        match button {
            glutin::VirtualKeyCode::Key1 => Key::Key1,
            glutin::VirtualKeyCode::Key2 => Key::Key2,
            glutin::VirtualKeyCode::Key3 => Key::Key3,
            glutin::VirtualKeyCode::Key4 => Key::Key4,
            glutin::VirtualKeyCode::Key5 => Key::Key5,
            glutin::VirtualKeyCode::Key6 => Key::Key6,
            glutin::VirtualKeyCode::Key7 => Key::Key7,
            glutin::VirtualKeyCode::Key8 => Key::Key8,
            glutin::VirtualKeyCode::Key9 => Key::Key9,
            glutin::VirtualKeyCode::Key0 => Key::Key0,
            glutin::VirtualKeyCode::A => Key::A,
            glutin::VirtualKeyCode::B => Key::B,
            glutin::VirtualKeyCode::C => Key::C,
            glutin::VirtualKeyCode::D => Key::V,
            glutin::VirtualKeyCode::E => Key::E,
            glutin::VirtualKeyCode::F => Key::F,
            glutin::VirtualKeyCode::G => Key::G,
            glutin::VirtualKeyCode::H => Key::H,
            glutin::VirtualKeyCode::I => Key::I,
            glutin::VirtualKeyCode::J => Key::J,
            glutin::VirtualKeyCode::K => Key::K,
            glutin::VirtualKeyCode::L => Key::L,
            glutin::VirtualKeyCode::M => Key::M,
            glutin::VirtualKeyCode::N => Key::N,
            glutin::VirtualKeyCode::O => Key::O,
            glutin::VirtualKeyCode::P => Key::P,
            glutin::VirtualKeyCode::Q => Key::Q,
            glutin::VirtualKeyCode::R => Key::R,
            glutin::VirtualKeyCode::S => Key::S,
            glutin::VirtualKeyCode::T => Key::T,
            glutin::VirtualKeyCode::U => Key::U,
            glutin::VirtualKeyCode::V => Key::V,
            glutin::VirtualKeyCode::W => Key::W,
            glutin::VirtualKeyCode::X => Key::X,
            glutin::VirtualKeyCode::Y => Key::Y,
            glutin::VirtualKeyCode::Z => Key::Z,
            glutin::VirtualKeyCode::Escape => Key::Escape,
            glutin::VirtualKeyCode::F1 => Key::F1,
            glutin::VirtualKeyCode::F2 => Key::F2,
            glutin::VirtualKeyCode::F3 => Key::F3,
            glutin::VirtualKeyCode::F4 => Key::F4,
            glutin::VirtualKeyCode::F5 => Key::F5,
            glutin::VirtualKeyCode::F6 => Key::F6,
            glutin::VirtualKeyCode::F7 => Key::F7,
            glutin::VirtualKeyCode::F8 => Key::F8,
            glutin::VirtualKeyCode::F9 => Key::F9,
            glutin::VirtualKeyCode::F10 => Key::F10,
            glutin::VirtualKeyCode::F11 => Key::F11,
            glutin::VirtualKeyCode::F12 => Key::F12,
            glutin::VirtualKeyCode::F13 => Key::F13,
            glutin::VirtualKeyCode::F14 => Key::F14,
            glutin::VirtualKeyCode::F15 => Key::F15,
            glutin::VirtualKeyCode::Snapshot => Key::Snapshot,
            glutin::VirtualKeyCode::Scroll => Key::Scroll,
            glutin::VirtualKeyCode::Pause => Key::Pause,
            glutin::VirtualKeyCode::Insert => Key::Insert,
            glutin::VirtualKeyCode::Home => Key::Home,
            glutin::VirtualKeyCode::Delete => Key::Delete,
            glutin::VirtualKeyCode::End => Key::End,
            glutin::VirtualKeyCode::PageDown => Key::PageDown,
            glutin::VirtualKeyCode::PageUp => Key::PageUp,
            glutin::VirtualKeyCode::Left => Key::Left,
            glutin::VirtualKeyCode::Up => Key::Up,
            glutin::VirtualKeyCode::Right => Key::Right,
            glutin::VirtualKeyCode::Down => Key::Down,
            glutin::VirtualKeyCode::Back => Key::Back,
            glutin::VirtualKeyCode::Return => Key::Return,
            glutin::VirtualKeyCode::Space => Key::Space,
            glutin::VirtualKeyCode::Compose => Key::Compose,
            glutin::VirtualKeyCode::Caret => Key::Caret,
            glutin::VirtualKeyCode::Numlock => Key::Numlock,
            glutin::VirtualKeyCode::Numpad0 => Key::Numpad0,
            glutin::VirtualKeyCode::Numpad1 => Key::Numpad1,
            glutin::VirtualKeyCode::Numpad2 => Key::Numpad2,
            glutin::VirtualKeyCode::Numpad3 => Key::Numpad3,
            glutin::VirtualKeyCode::Numpad4 => Key::Numpad4,
            glutin::VirtualKeyCode::Numpad5 => Key::Numpad5,
            glutin::VirtualKeyCode::Numpad6 => Key::Numpad6,
            glutin::VirtualKeyCode::Numpad7 => Key::Numpad7,
            glutin::VirtualKeyCode::Numpad8 => Key::Numpad8,
            glutin::VirtualKeyCode::Numpad9 => Key::Numpad9,
            glutin::VirtualKeyCode::AbntC1 => Key::AbntC1,
            glutin::VirtualKeyCode::AbntC2 => Key::AbntC2,
            glutin::VirtualKeyCode::Add => Key::Add,
            glutin::VirtualKeyCode::Apostrophe => Key::Apostrophe,
            glutin::VirtualKeyCode::Apps => Key::Apps,
            glutin::VirtualKeyCode::At => Key::At,
            glutin::VirtualKeyCode::Ax => Key::Ax,
            glutin::VirtualKeyCode::Backslash => Key::Backslash,
            glutin::VirtualKeyCode::Calculator => Key::Calculator,
            glutin::VirtualKeyCode::Capital => Key::Capital,
            glutin::VirtualKeyCode::Colon => Key::Colon,
            glutin::VirtualKeyCode::Comma => Key::Comma,
            glutin::VirtualKeyCode::Convert => Key::Convert,
            glutin::VirtualKeyCode::Decimal => Key::Decimal,
            glutin::VirtualKeyCode::Divide => Key::Divide,
            glutin::VirtualKeyCode::Equals => Key::Equals,
            glutin::VirtualKeyCode::Grave => Key::Grave,
            glutin::VirtualKeyCode::Kana => Key::Kana,
            glutin::VirtualKeyCode::Kanji => Key::Kanji,
            glutin::VirtualKeyCode::LAlt => Key::LAlt,
            glutin::VirtualKeyCode::LBracket => Key::LBracket,
            glutin::VirtualKeyCode::LControl => Key::LControl,
            glutin::VirtualKeyCode::LShift => Key::LShift,
            glutin::VirtualKeyCode::LWin => Key::LWin,
            glutin::VirtualKeyCode::Mail => Key::Mail,
            glutin::VirtualKeyCode::MediaSelect => Key::MediaSelect,
            glutin::VirtualKeyCode::MediaStop => Key::MediaStop,
            glutin::VirtualKeyCode::Minus => Key::Minus,
            glutin::VirtualKeyCode::Multiply => Key::Multiply,
            glutin::VirtualKeyCode::Mute => Key::Mute,
            glutin::VirtualKeyCode::MyComputer => Key::MyComputer,
            glutin::VirtualKeyCode::NavigateForward => Key::NavigateForward,
            glutin::VirtualKeyCode::NavigateBackward => Key::NavigateBackward,
            glutin::VirtualKeyCode::NextTrack => Key::NextTrack,
            glutin::VirtualKeyCode::NoConvert => Key::NoConvert,
            glutin::VirtualKeyCode::NumpadComma => Key::NumpadComma,
            glutin::VirtualKeyCode::NumpadEnter => Key::NumpadEnter,
            glutin::VirtualKeyCode::NumpadEquals => Key::NumpadEquals,
            glutin::VirtualKeyCode::OEM102 => Key::OEM102,
            glutin::VirtualKeyCode::Period => Key::Period,
            glutin::VirtualKeyCode::PlayPause => Key::PlayPause,
            glutin::VirtualKeyCode::Power => Key::Power,
            glutin::VirtualKeyCode::PrevTrack => Key::PrevTrack,
            glutin::VirtualKeyCode::RAlt => Key::RAlt,
            glutin::VirtualKeyCode::RBracket => Key::RBracket,
            glutin::VirtualKeyCode::RControl => Key::RControl,
            glutin::VirtualKeyCode::RShift => Key::RShift,
            glutin::VirtualKeyCode::RWin => Key::RWin,
            glutin::VirtualKeyCode::Semicolon => Key::Semicolon,
            glutin::VirtualKeyCode::Slash => Key::Slash,
            glutin::VirtualKeyCode::Sleep => Key::Sleep,
            glutin::VirtualKeyCode::Stop => Key::Stop,
            glutin::VirtualKeyCode::Subtract => Key::Subtract,
            glutin::VirtualKeyCode::Sysrq => Key::Sysrq,
            glutin::VirtualKeyCode::Tab => Key::Tab,
            glutin::VirtualKeyCode::Underline => Key::Underline,
            glutin::VirtualKeyCode::Unlabeled => Key::Unlabeled,
            glutin::VirtualKeyCode::VolumeDown => Key::VolumeDown,
            glutin::VirtualKeyCode::VolumeUp => Key::VolumeUp,
            glutin::VirtualKeyCode::Wake => Key::Wake,
            glutin::VirtualKeyCode::WebBack => Key::WebBack,
            glutin::VirtualKeyCode::WebFavorites => Key::WebFavorites,
            glutin::VirtualKeyCode::WebForward => Key::WebForward,
            glutin::VirtualKeyCode::WebHome => Key::WebHome,
            glutin::VirtualKeyCode::WebRefresh => Key::WebRefresh,
            glutin::VirtualKeyCode::WebSearch => Key::WebSearch,
            glutin::VirtualKeyCode::WebStop => Key::WebStop,
            glutin::VirtualKeyCode::Yen => Key::Yen,
            glutin::VirtualKeyCode::Copy => Key::Copy,
            glutin::VirtualKeyCode::Paste => Key::Paste,
            glutin::VirtualKeyCode::Cut => Key::Cut,
        }
    } else {
        Key::Unknown
    }
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::io::prelude::*;
use std::process::{Command, Stdio};

static PANGRAM: &'static str =
"the quick brown fox jumped over the lazy dog\n";

fn main() {
    // Spawn the `wc` command
    let process = match Command::new("wc")
                                .stdin(Stdio::piped())
                                .stdout(Stdio::piped())
                                .spawn() {
        Err(why) => panic!("couldn't spawn wc: {}", Error::description(&why)),
        Ok(process) => process,
    };

    {
        // Write a string to the stdin of `wc`.
        // stdin has type `Option<ChildStdin>`, but since we know this instance
        // must have one, we can directly `unwrap` it.
        match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) {
            Err(why) => panic!("couldn't write to wc stdin: {}",
                               Error::description(&why)),
            Ok(_) => println!("sent pangram to wc"),
        }

        // `stdin` gets `drop`ed here, and the pipe is closed
        // This is very important, otherwise `wc` wouldn't start processing the
        // input we just sent
    }

    // The `stdout` field also has type `Option<ChildStdout>` so must be unwrapped.
    let mut s = String::new();
    match process.stdout.unwrap().read_to_string(&mut s) {
        Err(why) => panic!("couldn't read wc stdout: {}",
                           Error::description(&why)),
        Ok(_) => print!("wc responded with:\n{}", s),
    }
}
<commit_msg>Additional markup tweaks.<commit_after>use std::error::Error;
use std::io::prelude::*;
use std::process::{Command, Stdio};

static PANGRAM: &'static str =
"the quick brown fox jumped over the lazy dog\n";

fn main() {
    // Spawn the `wc` command
    let process = match Command::new("wc")
                                .stdin(Stdio::piped())
                                .stdout(Stdio::piped())
                                .spawn() {
        Err(why) => panic!("couldn't spawn wc: {}", Error::description(&why)),
        Ok(process) => process,
    };

    {
        // Write a string to the `stdin` of `wc`.
        //
        // `stdin` has type `Option<ChildStdin>`, but since we know this instance
        // must have one, we can directly `unwrap` it.
        match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) {
            Err(why) => panic!("couldn't write to wc stdin: {}",
                               Error::description(&why)),
            Ok(_) => println!("sent pangram to wc"),
        }

        // `stdin` gets `drop`ed here, and the pipe is closed.
        //
        // This is very important, otherwise `wc` wouldn't start processing the
        // input we just sent.
    }

    // The `stdout` field also has type `Option<ChildStdout>` so must be unwrapped.
    let mut s = String::new();
    match process.stdout.unwrap().read_to_string(&mut s) {
        Err(why) => panic!("couldn't read wc stdout: {}",
                           Error::description(&why)),
        Ok(_) => print!("wc responded with:\n{}", s),
    }
}
<|endoftext|>


<commit_before>use autocxx::prelude::*;
include_cpp! {
    #include "input.h"
    safety!(unsafe_ffi)
    generate!("DoMath")
    generate!("Goat")
}

fn main() {
    println!("Hello, world! - C++ math should say 12={}", ffi::DoMath(4));
    let mut goat = ffi::Goat::make_unique();
    goat.as_mut().unwrap().add_a_horn();
    goat.as_mut().unwrap().add_a_horn();
    assert_eq!(
        goat.describe().as_ref().unwrap().to_string_lossy(),
        "This goat has 2 horns."
    );
}
<commit_msg>Reinstate accidentally removed header.<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use autocxx::prelude::*;
include_cpp! {
    #include "input.h"
    safety!(unsafe_ffi)
    generate!("DoMath")
    generate!("Goat")
}

fn main() {
    println!("Hello, world! - C++ math should say 12={}", ffi::DoMath(4));
    let mut goat = ffi::Goat::make_unique();
    goat.as_mut().unwrap().add_a_horn();
    goat.as_mut().unwrap().add_a_horn();
    assert_eq!(
        goat.describe().as_ref().unwrap().to_string_lossy(),
        "This goat has 2 horns."
    );
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;

use super::Query;
use crate::backend::Backend;
use crate::connection::Connection;
use crate::query_builder::{AstPass, QueryFragment, QueryId};
use crate::query_dsl::RunQueryDsl;
use crate::result::QueryResult;
use crate::serialize::ToSql;
use crate::sql_types::{HasSqlType, Untyped};

#[derive(Debug, Clone)]
#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
/// The return value of `sql_query`.
///
/// Unlike most queries in Diesel, `SqlQuery` loads its data by column name,
/// rather than by index. This means that you cannot deserialize this query into
/// a tuple, and any structs used must implement `QueryableByName`.
///
/// See [`sql_query`](../fn.sql_query.html) for examples.
pub struct SqlQuery<Inner = ()> {
    inner: Inner,
    query: String,
}

impl<Inner> SqlQuery<Inner> {
    pub(crate) fn new(inner: Inner, query: String) -> Self {
        SqlQuery { inner, query }
    }

    /// Bind a value for use with this SQL query. The given query should have
    /// placeholders that vary based on the database type,
    /// like [SQLite Parameter](https://sqlite.org/lang_expr.html#varparam) syntax,
    /// [PostgreSQL PREPARE syntax](https://www.postgresql.org/docs/current/sql-prepare.html),
    /// or [MySQL bind syntax](https://dev.mysql.com/doc/refman/8.0/en/mysql-stmt-bind-param.html).
    ///
    /// # Safety
    ///
    /// This function should be used with care, as Diesel cannot validate that
    /// the value is of the right type nor can it validate that you have passed
    /// the correct number of parameters.
    ///
    /// # Example
    ///
    /// ```
    /// # include!("../doctest_setup.rs");
    /// #
    /// # use schema::users;
    /// #
    /// # #[derive(QueryableByName, Debug, PartialEq)]
    /// # #[table_name="users"]
    /// # struct User {
    /// #     id: i32,
    /// #     name: String,
    /// # }
    /// #
    /// # fn main() {
    /// #     use diesel::sql_query;
    /// #     use diesel::sql_types::{Integer, Text};
    /// #
    /// #     let connection = establish_connection();
    /// #     diesel::insert_into(users::table)
    /// #         .values(users::name.eq("Jim"))
    /// #         .execute(&connection).unwrap();
    /// # #[cfg(feature = "postgres")]
    /// # let users = sql_query("SELECT * FROM users WHERE id > $1 AND name != $2");
    /// # #[cfg(not(feature = "postgres"))]
    /// let users = sql_query("SELECT * FROM users WHERE id > ? AND name <> ?")
    /// # ;
    /// # let users = users
    ///     .bind::<Integer, _>(1)
    ///     .bind::<Text, _>("Tess")
    ///     .get_results(&connection);
    /// let expected_users = vec![
    ///     User { id: 3, name: "Jim".into() },
    /// ];
    /// assert_eq!(Ok(expected_users), users);
    /// # }
    /// ```
    pub fn bind<ST, Value>(self, value: Value) -> UncheckedBind<Self, Value, ST> {
        UncheckedBind::new(self, value)
    }

    /// Internally boxes future calls on `bind` and `sql` so that they don't
    /// change the type.
    ///
    /// This allows doing things you otherwise couldn't do, e.g. `bind`ing in a
    /// loop.
    pub fn into_boxed<'f, DB: Backend>(self) -> BoxedSqlQuery<'f, DB, Self> {
        BoxedSqlQuery::new(self)
    }

    /// Appends a piece of SQL code at the end.
    pub fn sql<T: AsRef<str>>(mut self, sql: T) -> Self {
        self.query += sql.as_ref();
        self
    }
}

impl<DB, Inner> QueryFragment<DB> for SqlQuery<Inner>
where
    DB: Backend,
    Inner: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();
        self.inner.walk_ast(out.reborrow())?;
        out.push_sql(&self.query);
        Ok(())
    }
}

impl<Inner> QueryId for SqlQuery<Inner> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<Inner> Query for SqlQuery<Inner> {
    type SqlType = Untyped;
}

impl<Inner, Conn> RunQueryDsl<Conn> for SqlQuery<Inner> {}

#[derive(Debug, Clone, Copy)]
#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
pub struct UncheckedBind<Query, Value, ST> {
    query: Query,
    value: Value,
    _marker: PhantomData<ST>,
}

impl<Query, Value, ST> UncheckedBind<Query, Value, ST> {
    pub fn new(query: Query, value: Value) -> Self {
        UncheckedBind {
            query,
            value,
            _marker: PhantomData,
        }
    }

    pub fn bind<ST2, Value2>(self, value: Value2) -> UncheckedBind<Self, Value2, ST2> {
        UncheckedBind::new(self, value)
    }

    pub fn into_boxed<'f, DB: Backend>(self) -> BoxedSqlQuery<'f, DB, Self> {
        BoxedSqlQuery::new(self)
    }

    pub fn sql<T: Into<String>>(self, sql: T) -> SqlQuery<Self> {
        SqlQuery::new(self, sql.into())
    }
}

impl<Query, Value, ST> QueryId for UncheckedBind<Query, Value, ST>
where
    Query: QueryId,
    ST: QueryId,
{
    type QueryId = UncheckedBind<Query::QueryId, (), ST::QueryId>;

    const HAS_STATIC_QUERY_ID: bool = Query::HAS_STATIC_QUERY_ID && ST::HAS_STATIC_QUERY_ID;
}

impl<Query, Value, ST, DB> QueryFragment<DB> for UncheckedBind<Query, Value, ST>
where
    DB: Backend + HasSqlType<ST>,
    Query: QueryFragment<DB>,
    Value: ToSql<ST, DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        self.query.walk_ast(out.reborrow())?;
        out.push_bind_param_value_only(&self.value)?;
        Ok(())
    }
}

impl<Q, Value, ST> Query for UncheckedBind<Q, Value, ST> {
    type SqlType = Untyped;
}

impl<Conn, Query, Value, ST> RunQueryDsl<Conn> for UncheckedBind<Query, Value, ST> {}

#[must_use = "Queries are only executed when calling `load`, `get_result`, or similar."]
/// See [`SqlQuery::into_boxed`].
///
/// [`SqlQuery::into_boxed`]: ./struct.SqlQuery.html#method.into_boxed
#[allow(missing_debug_implementations)]
pub struct BoxedSqlQuery<'f, DB: Backend, Query> {
    query: Query,
    sql: String,
    binds: Vec<Box<dyn Fn(AstPass<DB>) -> QueryResult<()> + 'f>>,
}

impl<'f, DB: Backend, Query> BoxedSqlQuery<'f, DB, Query> {
    pub(crate) fn new(query: Query) -> Self {
        BoxedSqlQuery {
            query,
            sql: "".to_string(),
            binds: vec![],
        }
    }

    /// See [`SqlQuery::bind`].
    ///
    /// [`SqlQuery::bind`]: ./struct.SqlQuery.html#method.bind
    pub fn bind<BindSt, Value>(mut self, b: Value) -> Self
    where
        DB: HasSqlType<BindSt>,
        Value: ToSql<BindSt, DB> + 'f,
    {
        self.binds
            .push(Box::new(move |mut out| out.push_bind_param_value_only(&b)));
        self
    }

    /// See [`SqlQuery::sql`].
    ///
    /// [`SqlQuery::sql`]: ./struct.SqlQuery.html#method.sql
    pub fn sql<T: AsRef<str>>(mut self, sql: T) -> Self {
        self.sql += sql.as_ref();
        self
    }
}

impl<DB, Query> QueryFragment<DB> for BoxedSqlQuery<'_, DB, Query>
where
    DB: Backend,
    Query: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();
        self.query.walk_ast(out.reborrow())?;
        out.push_sql(&self.sql);

        for b in &self.binds {
            b(out.reborrow())?;
        }
        Ok(())
    }
}

impl<DB: Backend, Query> QueryId for BoxedSqlQuery<'_, DB, Query> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<DB, Q> Query for BoxedSqlQuery<'_, DB, Q>
where
    DB: Backend,
{
    type SqlType = Untyped;
}

impl<Conn: Connection, Query> RunQueryDsl<Conn> for BoxedSqlQuery<'_, Conn::Backend, Query> {}
<commit_msg>Add documentation for the UncheckedBind struct used by SqlQuery::bind<commit_after>use std::marker::PhantomData;

use super::Query;
use crate::backend::Backend;
use crate::connection::Connection;
use crate::query_builder::{AstPass, QueryFragment, QueryId};
use crate::query_dsl::RunQueryDsl;
use crate::result::QueryResult;
use crate::serialize::ToSql;
use crate::sql_types::{HasSqlType, Untyped};

#[derive(Debug, Clone)]
#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
/// The return value of `sql_query`.
///
/// Unlike most queries in Diesel, `SqlQuery` loads its data by column name,
/// rather than by index. This means that you cannot deserialize this query into
/// a tuple, and any structs used must implement `QueryableByName`.
///
/// See [`sql_query`](../fn.sql_query.html) for examples.
pub struct SqlQuery<Inner = ()> {
    inner: Inner,
    query: String,
}

impl<Inner> SqlQuery<Inner> {
    pub(crate) fn new(inner: Inner, query: String) -> Self {
        SqlQuery { inner, query }
    }

    /// Bind a value for use with this SQL query. The given query should have
    /// placeholders that vary based on the database type,
    /// like [SQLite Parameter](https://sqlite.org/lang_expr.html#varparam) syntax,
    /// [PostgreSQL PREPARE syntax](https://www.postgresql.org/docs/current/sql-prepare.html),
    /// or [MySQL bind syntax](https://dev.mysql.com/doc/refman/8.0/en/mysql-stmt-bind-param.html).
    ///
    /// # Safety
    ///
    /// This function should be used with care, as Diesel cannot validate that
    /// the value is of the right type nor can it validate that you have passed
    /// the correct number of parameters.
    ///
    /// # Example
    ///
    /// ```
    /// # include!("../doctest_setup.rs");
    /// #
    /// # use schema::users;
    /// #
    /// # #[derive(QueryableByName, Debug, PartialEq)]
    /// # #[table_name="users"]
    /// # struct User {
    /// #     id: i32,
    /// #     name: String,
    /// # }
    /// #
    /// # fn main() {
    /// #     use diesel::sql_query;
    /// #     use diesel::sql_types::{Integer, Text};
    /// #
    /// #     let connection = establish_connection();
    /// #     diesel::insert_into(users::table)
    /// #         .values(users::name.eq("Jim"))
    /// #         .execute(&connection).unwrap();
    /// # #[cfg(feature = "postgres")]
    /// # let users = sql_query("SELECT * FROM users WHERE id > $1 AND name != $2");
    /// # #[cfg(not(feature = "postgres"))]
    /// let users = sql_query("SELECT * FROM users WHERE id > ? AND name <> ?")
    /// # ;
    /// # let users = users
    ///     .bind::<Integer, _>(1)
    ///     .bind::<Text, _>("Tess")
    ///     .get_results(&connection);
    /// let expected_users = vec![
    ///     User { id: 3, name: "Jim".into() },
    /// ];
    /// assert_eq!(Ok(expected_users), users);
    /// # }
    /// ```
    pub fn bind<ST, Value>(self, value: Value) -> UncheckedBind<Self, Value, ST> {
        UncheckedBind::new(self, value)
    }

    /// Internally boxes future calls on `bind` and `sql` so that they don't
    /// change the type.
    ///
    /// This allows doing things you otherwise couldn't do, e.g. `bind`ing in a
    /// loop.
    pub fn into_boxed<'f, DB: Backend>(self) -> BoxedSqlQuery<'f, DB, Self> {
        BoxedSqlQuery::new(self)
    }

    /// Appends a piece of SQL code at the end.
    pub fn sql<T: AsRef<str>>(mut self, sql: T) -> Self {
        self.query += sql.as_ref();
        self
    }
}

impl<DB, Inner> QueryFragment<DB> for SqlQuery<Inner>
where
    DB: Backend,
    Inner: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();
        self.inner.walk_ast(out.reborrow())?;
        out.push_sql(&self.query);
        Ok(())
    }
}

impl<Inner> QueryId for SqlQuery<Inner> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<Inner> Query for SqlQuery<Inner> {
    type SqlType = Untyped;
}

impl<Inner, Conn> RunQueryDsl<Conn> for SqlQuery<Inner> {}

#[derive(Debug, Clone, Copy)]
#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
/// Returned by the [`SqlQuery::bind()`] method when binding a value to a fragment of SQL.
///
/// [`SqlQuery::bind()`]: ./struct.SqlQuery.html#method.bind
pub struct UncheckedBind<Query, Value, ST> {
    query: Query,
    value: Value,
    _marker: PhantomData<ST>,
}

impl<Query, Value, ST> UncheckedBind<Query, Value, ST> {
    pub fn new(query: Query, value: Value) -> Self {
        UncheckedBind {
            query,
            value,
            _marker: PhantomData,
        }
    }

    pub fn bind<ST2, Value2>(self, value: Value2) -> UncheckedBind<Self, Value2, ST2> {
        UncheckedBind::new(self, value)
    }

    pub fn into_boxed<'f, DB: Backend>(self) -> BoxedSqlQuery<'f, DB, Self> {
        BoxedSqlQuery::new(self)
    }

    /// Construct a full SQL query using raw SQL.
    ///
    /// This function exists for cases where a query needs to be written that is not
    /// supported by the query builder. Unlike most queries in Diesel, `sql_query`
    /// will deserialize its data by name, not by index. That means that you cannot
    /// deserialize into a tuple, and structs which you deserialize from this
    /// function will need to have `#[derive(QueryableByName)]`.
    ///
    /// This function is intended for use when you want to write the entire query
    /// using raw SQL. If you only need a small bit of raw SQL in your query, use
    /// [`sql`](./dsl/fn.sql.html) instead.
    ///
    /// Query parameters can be bound into the raw query using [`SqlQuery::bind()`].
    ///
    /// # Safety
    ///
    /// The implementation of `QueryableByName` will assume that columns with a
    /// given name will have a certain type. The compiler will be unable to verify
    /// that the given type is correct. If your query returns a column of an
    /// unexpected type, the result may have the wrong value, or return an error.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # include!("../doctest_setup.rs");
    /// #
    /// # use schema::users;
    /// #
    /// # #[derive(QueryableByName, Debug, PartialEq)]
    /// # #[table_name="users"]
    /// # struct User {
    /// #     id: i32,
    /// #     name: String,
    /// # }
    /// #
    /// # fn main() {
    /// #     use diesel::sql_query;
    /// #     use diesel::sql_types::{Integer, Text};
    /// #
    /// #     let connection = establish_connection();
    /// # #[cfg(feature = "postgres")]
    /// # let users = sql_query("SELECT * FROM users WHERE id > $1 AND name != $2");
    /// # #[cfg(not(feature = "postgres"))]
    /// let users = sql_query("SELECT * FROM users WHERE id > ? AND name <> ?")
    /// # ;
    /// # let users = users
    ///     .bind::<Integer, _>(1)
    ///     .bind::<Text, _>("Tess")
    ///     .get_results(&connection);
    /// let expected_users = vec![
    ///     User { id: 3, name: "Jim".into() },
    /// ];
    /// assert_eq!(Ok(expected_users), users);
    /// # }
    /// ```
    /// [`SqlQuery::bind()`]: query_builder/struct.SqlQuery.html#method.bind
    pub fn sql<T: Into<String>>(self, sql: T) -> SqlQuery<Self> {
        SqlQuery::new(self, sql.into())
    }
}

impl<Query, Value, ST> QueryId for UncheckedBind<Query, Value, ST>
where
    Query: QueryId,
    ST: QueryId,
{
    type QueryId = UncheckedBind<Query::QueryId, (), ST::QueryId>;

    const HAS_STATIC_QUERY_ID: bool = Query::HAS_STATIC_QUERY_ID && ST::HAS_STATIC_QUERY_ID;
}

impl<Query, Value, ST, DB> QueryFragment<DB> for UncheckedBind<Query, Value, ST>
where
    DB: Backend + HasSqlType<ST>,
    Query: QueryFragment<DB>,
    Value: ToSql<ST, DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        self.query.walk_ast(out.reborrow())?;
        out.push_bind_param_value_only(&self.value)?;
        Ok(())
    }
}

impl<Q, Value, ST> Query for UncheckedBind<Q, Value, ST> {
    type SqlType = Untyped;
}

impl<Conn, Query, Value, ST> RunQueryDsl<Conn> for UncheckedBind<Query, Value, ST> {}

#[must_use = "Queries are only executed when calling `load`, `get_result`, or similar."]
/// See [`SqlQuery::into_boxed`].
///
/// [`SqlQuery::into_boxed`]: ./struct.SqlQuery.html#method.into_boxed
#[allow(missing_debug_implementations)]
pub struct BoxedSqlQuery<'f, DB: Backend, Query> {
    query: Query,
    sql: String,
    binds: Vec<Box<dyn Fn(AstPass<DB>) -> QueryResult<()> + 'f>>,
}

impl<'f, DB: Backend, Query> BoxedSqlQuery<'f, DB, Query> {
    pub(crate) fn new(query: Query) -> Self {
        BoxedSqlQuery {
            query,
            sql: "".to_string(),
            binds: vec![],
        }
    }

    /// See [`SqlQuery::bind`].
    ///
    /// [`SqlQuery::bind`]: ./struct.SqlQuery.html#method.bind
    pub fn bind<BindSt, Value>(mut self, b: Value) -> Self
    where
        DB: HasSqlType<BindSt>,
        Value: ToSql<BindSt, DB> + 'f,
    {
        self.binds
            .push(Box::new(move |mut out| out.push_bind_param_value_only(&b)));
        self
    }

    /// See [`SqlQuery::sql`].
    ///
    /// [`SqlQuery::sql`]: ./struct.SqlQuery.html#method.sql
    pub fn sql<T: AsRef<str>>(mut self, sql: T) -> Self {
        self.sql += sql.as_ref();
        self
    }
}

impl<DB, Query> QueryFragment<DB> for BoxedSqlQuery<'_, DB, Query>
where
    DB: Backend,
    Query: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();
        self.query.walk_ast(out.reborrow())?;
        out.push_sql(&self.sql);

        for b in &self.binds {
            b(out.reborrow())?;
        }
        Ok(())
    }
}

impl<DB: Backend, Query> QueryId for BoxedSqlQuery<'_, DB, Query> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<DB, Q> Query for BoxedSqlQuery<'_, DB, Q>
where
    DB: Backend,
{
    type SqlType = Untyped;
}

impl<Conn: Connection, Query> RunQueryDsl<Conn> for BoxedSqlQuery<'_, Conn::Backend, Query> {}
<|endoftext|>


<commit_before>use std::io::BufReader;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::env;

fn main() {
    let tab: Vec<_> = env::args().collect();
    let mut file_tab: Vec<_> = Vec::new();
    let mut iterator: usize = 0;
    let mut v: Vec<&str> = Vec::new();
    let mut buffer = String::new();
    let mut buffer2 = String::new();

    println!("{:?}", &tab[1..]);

    assert_ne!(tab.len(), 2);

    for n in &tab {
        let f = File::open(&n).unwrap();
        let f = BufReader::new(f);
        file_tab[iterator] = f;
        iterator += 1;
    }
    file_tab[0].read_to_string(&mut buffer);
    file_tab[1].read_to_string(&mut buffer2);
}
<commit_msg>reduce code size but not compile yet<commit_after>use std::io::BufReader;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::env;

fn main() {
    let tab: Vec<_> = env::args().collect();

    println!("{:?}", &tab[1..]);

    assert_ne!(tab.len(), 2);

    let mut f = File::open(&tab[0]).unwrap();
    let mut f = BufReader::new(f);
    let mut f2 = File::open(&tab[1]).unwrap();
    let mut f2 = BufReader::new(f);
    let mut counter = 0;
    for line in f.lines() {
        if line != f2.lines() {
            counter +=1;
        }
    }
    println!("{} of differences between {:?}", counter, &tab[1..]);
}
<|endoftext|>