<commit_before>//! This module implements import-resolution/macro expansion algorithm.
//!
//! The result of this module is `CrateDefMap`: a data structure which contains:
//!
//!   * a tree of modules for the crate
//!   * for each module, a set of items visible in the module (directly declared
//!     or imported)
//!
//! Note that `CrateDefMap` contains fully macro expanded code.
//!
//! Computing `CrateDefMap` can be partitioned into several logically
//! independent "phases". The phases are mutually recursive though, there's no
//! strict ordering.
//!
//! ## Collecting RawItems
//!
//! This happens in the `raw` module, which parses a single source file into a
//! set of top-level items. Nested imports are desugared to flat imports in this
//! phase. Macro calls are represented as a triple of (Path, Option<Name>,
//! TokenTree).
//!
//! ## Collecting Modules
//!
//! This happens in the `collector` module. In this phase, we recursively walk
//! tree of modules, collect raw items from submodules, populate module scopes
//! with defined items (so, we assign item ids in this phase) and record the set
//! of unresolved imports and macros.
//!
//! While we walk tree of modules, we also record macro_rules definitions and
//! expand calls to macro_rules defined macros.
//!
//! ## Resolving Imports
//!
//! We maintain a list of currently unresolved imports. On every iteration, we
//! try to resolve some imports from this list. If the import is resolved, we
//! record it, by adding an item to current module scope and, if necessary, by
//! recursively populating glob imports.
//!
//! ## Resolving Macros
//!
//! macro_rules from the same crate use a global mutable namespace. We expand
//! them immediately, when we collect modules.
//!
//! Macros from other crates (including proc-macros) can be used with
//! `foo::bar!` syntax. We handle them similarly to imports. There's a list of
//! unexpanded macros. On every iteration, we try to resolve each macro call
//! path and, upon success, we run macro expansion and "collect module" phase on
//! the result

pub(crate) mod raw;
mod collector;
mod mod_resolution;
mod path_resolution;

#[cfg(test)]
mod tests;

use std::sync::Arc;

use hir_expand::{
    ast_id_map::FileAstId, diagnostics::DiagnosticSink, either::Either, name::Name, MacroDefId,
    Source,
};
use once_cell::sync::Lazy;
use ra_arena::Arena;
use ra_db::{CrateId, Edition, FileId};
use ra_prof::profile;
use ra_syntax::ast;
use rustc_hash::{FxHashMap, FxHashSet};

use crate::{
    builtin_type::BuiltinType,
    db::DefDatabase,
    nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
    path::Path,
    per_ns::PerNs,
    AstId, FunctionId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId,
};

/// Contains all top-level defs from a macro-expanded crate
#[derive(Debug, PartialEq, Eq)]
pub struct CrateDefMap {
    krate: CrateId,
    edition: Edition,
    /// The prelude module for this crate. This either comes from an import
    /// marked with the `prelude_import` attribute, or (in the normal case) from
    /// a dependency (`std` or `core`).
    prelude: Option<ModuleId>,
    extern_prelude: FxHashMap<Name, ModuleDefId>,
    root: LocalModuleId,
    modules: Arena<LocalModuleId, ModuleData>,

    /// Some macros are not well-behavior, which leads to infinite loop
    /// e.g. macro_rules! foo { ($ty:ty) => { foo!($ty); } }
    /// We mark it down and skip it in collector
    ///
    /// FIXME:
    /// Right now it only handle a poison macro in a single crate,
    /// such that if other crate try to call that macro,
    /// the whole process will do again until it became poisoned in that crate.
    /// We should handle this macro set globally
    /// However, do we want to put it as a global variable?
    poison_macros: FxHashSet<MacroDefId>,

    diagnostics: Vec<DefDiagnostic>,
}

impl std::ops::Index<LocalModuleId> for CrateDefMap {
    type Output = ModuleData;
    fn index(&self, id: LocalModuleId) -> &ModuleData {
        &self.modules[id]
    }
}

#[derive(Default, Debug, PartialEq, Eq)]
pub struct ModuleData {
    pub parent: Option<LocalModuleId>,
    pub children: FxHashMap<Name, LocalModuleId>,
    pub scope: ModuleScope,

    //  FIXME: these can't be both null, we need a three-state enum here.
    /// None for root
    pub declaration: Option<AstId<ast::Module>>,
    /// None for inline modules.
    ///
    /// Note that non-inline modules, by definition, live inside non-macro file.
    pub definition: Option<FileId>,

    pub impls: Vec<ImplId>,
}

#[derive(Default, Debug, PartialEq, Eq)]
pub(crate) struct Declarations {
    fns: FxHashMap<FileAstId<ast::FnDef>, FunctionId>,
}

#[derive(Debug, Default, PartialEq, Eq)]
pub struct ModuleScope {
    items: FxHashMap<Name, Resolution>,
    /// Macros visable in current module in legacy textual scope
    ///
    /// For macros invoked by an unquatified identifier like `bar!()`, `legacy_macros` will be searched in first.
    /// If it yields no result, then it turns to module scoped `macros`.
    /// It macros with name quatified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped,
    /// and only normal scoped `macros` will be searched in.
    ///
    /// Note that this automatically inherit macros defined textually before the definition of module itself.
    ///
    /// Module scoped macros will be inserted into `items` instead of here.
    // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
    // be all resolved to the last one defined if shadowing happens.
    legacy_macros: FxHashMap<Name, MacroDefId>,
}

static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
    BuiltinType::ALL
        .iter()
        .map(|(name, ty)| {
            (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None })
        })
        .collect()
});

/// Legacy macros can only be accessed through special methods like `get_legacy_macros`.
/// Other methods will only resolve values, types and module scoped macros only.
impl ModuleScope {
    pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a {
        //FIXME: shadowing
        self.items.iter().chain(BUILTIN_SCOPE.iter())
    }

    pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
        self.entries()
            .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
            .flat_map(|per_ns| {
                per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
            })
    }

    /// Iterate over all module scoped macros
    pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
        self.items
            .iter()
            .filter_map(|(name, res)| res.def.get_macros().map(|macro_| (name, macro_)))
    }

    /// Iterate over all legacy textual scoped macros visable at the end of the module
    pub fn legacy_macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
        self.legacy_macros.iter().map(|(name, def)| (name, *def))
    }

    /// Get a name from current module scope, legacy macros are not included
    pub fn get(&self, name: &Name) -> Option<&Resolution> {
        self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name))
    }

    pub fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
        self.items.values().filter_map(|r| match r.def.take_types() {
            Some(ModuleDefId::TraitId(t)) => Some(t),
            _ => None,
        })
    }

    fn get_legacy_macro(&self, name: &Name) -> Option<MacroDefId> {
        self.legacy_macros.get(name).copied()
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Resolution {
    /// None for unresolved
    pub def: PerNs,
    /// ident by which this is imported into local scope.
    pub import: Option<LocalImportId>,
}

impl CrateDefMap {
    pub(crate) fn crate_def_map_query(
        // Note that this doesn't have `+ AstDatabase`!
        // This gurantess that `CrateDefMap` is stable across reparses.
        db: &impl DefDatabase,
        krate: CrateId,
    ) -> Arc<CrateDefMap> {
        let _p = profile("crate_def_map_query");
        let def_map = {
            let crate_graph = db.crate_graph();
            let edition = crate_graph.edition(krate);
            let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default();
            let root = modules.alloc(ModuleData::default());
            CrateDefMap {
                krate,
                edition,
                extern_prelude: FxHashMap::default(),
                prelude: None,
                root,
                modules,
                poison_macros: FxHashSet::default(),
                diagnostics: Vec::new(),
            }
        };
        let def_map = collector::collect_defs(db, def_map);
        Arc::new(def_map)
    }

    pub fn krate(&self) -> CrateId {
        self.krate
    }

    pub fn root(&self) -> LocalModuleId {
        self.root
    }

    pub fn prelude(&self) -> Option<ModuleId> {
        self.prelude
    }

    pub fn extern_prelude(&self) -> &FxHashMap<Name, ModuleDefId> {
        &self.extern_prelude
    }

    pub fn add_diagnostics(
        &self,
        db: &impl DefDatabase,
        module: LocalModuleId,
        sink: &mut DiagnosticSink,
    ) {
        self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink))
    }

    pub fn resolve_path(
        &self,
        db: &impl DefDatabase,
        original_module: LocalModuleId,
        path: &Path,
    ) -> (PerNs, Option<usize>) {
        let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path);
        (res.resolved_def, res.segment_index)
    }

    pub fn modules(&self) -> impl Iterator<Item = LocalModuleId> + '_ {
        self.modules.iter().map(|(id, _data)| id)
    }

    pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator<Item = LocalModuleId> + '_ {
        self.modules
            .iter()
            .filter(move |(_id, data)| data.definition == Some(file_id))
            .map(|(id, _data)| id)
    }
}

impl ModuleData {
    /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
    pub fn definition_source(
        &self,
        db: &impl DefDatabase,
    ) -> Source<Either<ast::SourceFile, ast::Module>> {
        if let Some(file_id) = self.definition {
            let sf = db.parse(file_id).tree();
            return Source::new(file_id.into(), Either::A(sf));
        }
        let decl = self.declaration.unwrap();
        Source::new(decl.file_id(), Either::B(decl.to_node(db)))
    }

    /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
    /// `None` for the crate root.
    pub fn declaration_source(&self, db: &impl DefDatabase) -> Option<Source<ast::Module>> {
        let decl = self.declaration?;
        let value = decl.to_node(db);
        Some(Source { file_id: decl.file_id(), value })
    }
}

mod diagnostics {
    use hir_expand::diagnostics::DiagnosticSink;
    use ra_db::RelativePathBuf;
    use ra_syntax::{ast, AstPtr};

    use crate::{db::DefDatabase, diagnostics::UnresolvedModule, nameres::LocalModuleId, AstId};

    #[derive(Debug, PartialEq, Eq)]
    pub(super) enum DefDiagnostic {
        UnresolvedModule {
            module: LocalModuleId,
            declaration: AstId<ast::Module>,
            candidate: RelativePathBuf,
        },
    }

    impl DefDiagnostic {
        pub(super) fn add_to(
            &self,
            db: &impl DefDatabase,
            target_module: LocalModuleId,
            sink: &mut DiagnosticSink,
        ) {
            match self {
                DefDiagnostic::UnresolvedModule { module, declaration, candidate } => {
                    if *module != target_module {
                        return;
                    }
                    let decl = declaration.to_node(db);
                    sink.push(UnresolvedModule {
                        file: declaration.file_id(),
                        decl: AstPtr::new(&decl),
                        candidate: candidate.clone(),
                    })
                }
            }
        }
    }
}
<commit_msg>Reduce visbility<commit_after>//! This module implements import-resolution/macro expansion algorithm.
//!
//! The result of this module is `CrateDefMap`: a data structure which contains:
//!
//!   * a tree of modules for the crate
//!   * for each module, a set of items visible in the module (directly declared
//!     or imported)
//!
//! Note that `CrateDefMap` contains fully macro expanded code.
//!
//! Computing `CrateDefMap` can be partitioned into several logically
//! independent "phases". The phases are mutually recursive though, there's no
//! strict ordering.
//!
//! ## Collecting RawItems
//!
//! This happens in the `raw` module, which parses a single source file into a
//! set of top-level items. Nested imports are desugared to flat imports in this
//! phase. Macro calls are represented as a triple of (Path, Option<Name>,
//! TokenTree).
//!
//! ## Collecting Modules
//!
//! This happens in the `collector` module. In this phase, we recursively walk
//! tree of modules, collect raw items from submodules, populate module scopes
//! with defined items (so, we assign item ids in this phase) and record the set
//! of unresolved imports and macros.
//!
//! While we walk tree of modules, we also record macro_rules definitions and
//! expand calls to macro_rules defined macros.
//!
//! ## Resolving Imports
//!
//! We maintain a list of currently unresolved imports. On every iteration, we
//! try to resolve some imports from this list. If the import is resolved, we
//! record it, by adding an item to current module scope and, if necessary, by
//! recursively populating glob imports.
//!
//! ## Resolving Macros
//!
//! macro_rules from the same crate use a global mutable namespace. We expand
//! them immediately, when we collect modules.
//!
//! Macros from other crates (including proc-macros) can be used with
//! `foo::bar!` syntax. We handle them similarly to imports. There's a list of
//! unexpanded macros. On every iteration, we try to resolve each macro call
//! path and, upon success, we run macro expansion and "collect module" phase on
//! the result

pub(crate) mod raw;
mod collector;
mod mod_resolution;
mod path_resolution;

#[cfg(test)]
mod tests;

use std::sync::Arc;

use hir_expand::{
    ast_id_map::FileAstId, diagnostics::DiagnosticSink, either::Either, name::Name, MacroDefId,
    Source,
};
use once_cell::sync::Lazy;
use ra_arena::Arena;
use ra_db::{CrateId, Edition, FileId};
use ra_prof::profile;
use ra_syntax::ast;
use rustc_hash::{FxHashMap, FxHashSet};

use crate::{
    builtin_type::BuiltinType,
    db::DefDatabase,
    nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
    path::Path,
    per_ns::PerNs,
    AstId, FunctionId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId,
};

/// Contains all top-level defs from a macro-expanded crate
#[derive(Debug, PartialEq, Eq)]
pub struct CrateDefMap {
    krate: CrateId,
    edition: Edition,
    /// The prelude module for this crate. This either comes from an import
    /// marked with the `prelude_import` attribute, or (in the normal case) from
    /// a dependency (`std` or `core`).
    prelude: Option<ModuleId>,
    extern_prelude: FxHashMap<Name, ModuleDefId>,
    root: LocalModuleId,
    modules: Arena<LocalModuleId, ModuleData>,

    /// Some macros are not well-behavior, which leads to infinite loop
    /// e.g. macro_rules! foo { ($ty:ty) => { foo!($ty); } }
    /// We mark it down and skip it in collector
    ///
    /// FIXME:
    /// Right now it only handle a poison macro in a single crate,
    /// such that if other crate try to call that macro,
    /// the whole process will do again until it became poisoned in that crate.
    /// We should handle this macro set globally
    /// However, do we want to put it as a global variable?
    poison_macros: FxHashSet<MacroDefId>,

    diagnostics: Vec<DefDiagnostic>,
}

impl std::ops::Index<LocalModuleId> for CrateDefMap {
    type Output = ModuleData;
    fn index(&self, id: LocalModuleId) -> &ModuleData {
        &self.modules[id]
    }
}

#[derive(Default, Debug, PartialEq, Eq)]
pub struct ModuleData {
    pub parent: Option<LocalModuleId>,
    pub children: FxHashMap<Name, LocalModuleId>,
    pub scope: ModuleScope,

    //  FIXME: these can't be both null, we need a three-state enum here.
    /// None for root
    pub declaration: Option<AstId<ast::Module>>,
    /// None for inline modules.
    ///
    /// Note that non-inline modules, by definition, live inside non-macro file.
    pub definition: Option<FileId>,

    pub impls: Vec<ImplId>,
}

#[derive(Default, Debug, PartialEq, Eq)]
pub(crate) struct Declarations {
    fns: FxHashMap<FileAstId<ast::FnDef>, FunctionId>,
}

#[derive(Debug, Default, PartialEq, Eq)]
pub struct ModuleScope {
    items: FxHashMap<Name, Resolution>,
    /// Macros visable in current module in legacy textual scope
    ///
    /// For macros invoked by an unquatified identifier like `bar!()`, `legacy_macros` will be searched in first.
    /// If it yields no result, then it turns to module scoped `macros`.
    /// It macros with name quatified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped,
    /// and only normal scoped `macros` will be searched in.
    ///
    /// Note that this automatically inherit macros defined textually before the definition of module itself.
    ///
    /// Module scoped macros will be inserted into `items` instead of here.
    // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
    // be all resolved to the last one defined if shadowing happens.
    legacy_macros: FxHashMap<Name, MacroDefId>,
}

static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
    BuiltinType::ALL
        .iter()
        .map(|(name, ty)| {
            (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None })
        })
        .collect()
});

/// Legacy macros can only be accessed through special methods like `get_legacy_macros`.
/// Other methods will only resolve values, types and module scoped macros only.
impl ModuleScope {
    pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a {
        //FIXME: shadowing
        self.items.iter().chain(BUILTIN_SCOPE.iter())
    }

    pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
        self.entries()
            .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
            .flat_map(|per_ns| {
                per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
            })
    }

    /// Iterate over all module scoped macros
    pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
        self.items
            .iter()
            .filter_map(|(name, res)| res.def.get_macros().map(|macro_| (name, macro_)))
    }

    /// Iterate over all legacy textual scoped macros visable at the end of the module
    pub fn legacy_macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
        self.legacy_macros.iter().map(|(name, def)| (name, *def))
    }

    /// Get a name from current module scope, legacy macros are not included
    pub fn get(&self, name: &Name) -> Option<&Resolution> {
        self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name))
    }

    pub fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
        self.items.values().filter_map(|r| match r.def.take_types() {
            Some(ModuleDefId::TraitId(t)) => Some(t),
            _ => None,
        })
    }

    fn get_legacy_macro(&self, name: &Name) -> Option<MacroDefId> {
        self.legacy_macros.get(name).copied()
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Resolution {
    /// None for unresolved
    pub def: PerNs,
    /// ident by which this is imported into local scope.
    pub import: Option<LocalImportId>,
}

impl CrateDefMap {
    pub(crate) fn crate_def_map_query(
        // Note that this doesn't have `+ AstDatabase`!
        // This gurantess that `CrateDefMap` is stable across reparses.
        db: &impl DefDatabase,
        krate: CrateId,
    ) -> Arc<CrateDefMap> {
        let _p = profile("crate_def_map_query");
        let def_map = {
            let crate_graph = db.crate_graph();
            let edition = crate_graph.edition(krate);
            let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default();
            let root = modules.alloc(ModuleData::default());
            CrateDefMap {
                krate,
                edition,
                extern_prelude: FxHashMap::default(),
                prelude: None,
                root,
                modules,
                poison_macros: FxHashSet::default(),
                diagnostics: Vec::new(),
            }
        };
        let def_map = collector::collect_defs(db, def_map);
        Arc::new(def_map)
    }

    pub fn krate(&self) -> CrateId {
        self.krate
    }

    pub fn root(&self) -> LocalModuleId {
        self.root
    }

    pub fn prelude(&self) -> Option<ModuleId> {
        self.prelude
    }

    pub fn extern_prelude(&self) -> &FxHashMap<Name, ModuleDefId> {
        &self.extern_prelude
    }

    pub fn add_diagnostics(
        &self,
        db: &impl DefDatabase,
        module: LocalModuleId,
        sink: &mut DiagnosticSink,
    ) {
        self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink))
    }

    pub fn modules(&self) -> impl Iterator<Item = LocalModuleId> + '_ {
        self.modules.iter().map(|(id, _data)| id)
    }

    pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator<Item = LocalModuleId> + '_ {
        self.modules
            .iter()
            .filter(move |(_id, data)| data.definition == Some(file_id))
            .map(|(id, _data)| id)
    }

    pub(crate) fn resolve_path(
        &self,
        db: &impl DefDatabase,
        original_module: LocalModuleId,
        path: &Path,
    ) -> (PerNs, Option<usize>) {
        let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path);
        (res.resolved_def, res.segment_index)
    }
}

impl ModuleData {
    /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
    pub fn definition_source(
        &self,
        db: &impl DefDatabase,
    ) -> Source<Either<ast::SourceFile, ast::Module>> {
        if let Some(file_id) = self.definition {
            let sf = db.parse(file_id).tree();
            return Source::new(file_id.into(), Either::A(sf));
        }
        let decl = self.declaration.unwrap();
        Source::new(decl.file_id(), Either::B(decl.to_node(db)))
    }

    /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
    /// `None` for the crate root.
    pub fn declaration_source(&self, db: &impl DefDatabase) -> Option<Source<ast::Module>> {
        let decl = self.declaration?;
        let value = decl.to_node(db);
        Some(Source { file_id: decl.file_id(), value })
    }
}

mod diagnostics {
    use hir_expand::diagnostics::DiagnosticSink;
    use ra_db::RelativePathBuf;
    use ra_syntax::{ast, AstPtr};

    use crate::{db::DefDatabase, diagnostics::UnresolvedModule, nameres::LocalModuleId, AstId};

    #[derive(Debug, PartialEq, Eq)]
    pub(super) enum DefDiagnostic {
        UnresolvedModule {
            module: LocalModuleId,
            declaration: AstId<ast::Module>,
            candidate: RelativePathBuf,
        },
    }

    impl DefDiagnostic {
        pub(super) fn add_to(
            &self,
            db: &impl DefDatabase,
            target_module: LocalModuleId,
            sink: &mut DiagnosticSink,
        ) {
            match self {
                DefDiagnostic::UnresolvedModule { module, declaration, candidate } => {
                    if *module != target_module {
                        return;
                    }
                    let decl = declaration.to_node(db);
                    sink.push(UnresolvedModule {
                        file: declaration.file_id(),
                        decl: AstPtr::new(&decl),
                        candidate: candidate.clone(),
                    })
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use languageserver_types::{
    CodeActionProviderCapability, CompletionOptions, DocumentOnTypeFormattingOptions,
    ExecuteCommandOptions, FoldingRangeProviderCapability, RenameOptions, RenameProviderCapability,
    ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
    TextDocumentSyncOptions,
};

pub fn server_capabilities() -> ServerCapabilities {
    ServerCapabilities {
        text_document_sync: Some(TextDocumentSyncCapability::Options(
            TextDocumentSyncOptions {
                open_close: Some(true),
                change: Some(TextDocumentSyncKind::Full),
                will_save: None,
                will_save_wait_until: None,
                save: None,
            },
        )),
        hover_provider: Some(true),
        completion_provider: Some(CompletionOptions {
            resolve_provider: None,
            trigger_characters: Some(vec![":".to_string(), ".".to_string()]),
        }),
        signature_help_provider: Some(SignatureHelpOptions {
            trigger_characters: Some(vec!["(".to_string(), ",".to_string(), ")".to_string()]),
        }),
        definition_provider: Some(true),
        type_definition_provider: None,
        implementation_provider: None,
        references_provider: Some(true),
        document_highlight_provider: Some(true),
        document_symbol_provider: Some(true),
        workspace_symbol_provider: Some(true),
        code_action_provider: Some(CodeActionProviderCapability::Simple(true)),
        code_lens_provider: None,
        document_formatting_provider: Some(true),
        document_range_formatting_provider: None,
        document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
            first_trigger_character: "=".to_string(),
            more_trigger_character: None,
        }),
        folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
        rename_provider: Some(RenameProviderCapability::Options(RenameOptions {
            prepare_provider: Some(true),
        })),
        color_provider: None,
        execute_command_provider: Some(ExecuteCommandOptions {
            commands: vec!["apply_code_action".to_string()],
        }),
        workspace: None,
    }
}
<commit_msg>add "." as a trigger char on type formatting<commit_after>use languageserver_types::{
    CodeActionProviderCapability, CompletionOptions, DocumentOnTypeFormattingOptions,
    ExecuteCommandOptions, FoldingRangeProviderCapability, RenameOptions, RenameProviderCapability,
    ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
    TextDocumentSyncOptions,
};

pub fn server_capabilities() -> ServerCapabilities {
    ServerCapabilities {
        text_document_sync: Some(TextDocumentSyncCapability::Options(
            TextDocumentSyncOptions {
                open_close: Some(true),
                change: Some(TextDocumentSyncKind::Full),
                will_save: None,
                will_save_wait_until: None,
                save: None,
            },
        )),
        hover_provider: Some(true),
        completion_provider: Some(CompletionOptions {
            resolve_provider: None,
            trigger_characters: Some(vec![":".to_string(), ".".to_string()]),
        }),
        signature_help_provider: Some(SignatureHelpOptions {
            trigger_characters: Some(vec!["(".to_string(), ",".to_string(), ")".to_string()]),
        }),
        definition_provider: Some(true),
        type_definition_provider: None,
        implementation_provider: None,
        references_provider: Some(true),
        document_highlight_provider: Some(true),
        document_symbol_provider: Some(true),
        workspace_symbol_provider: Some(true),
        code_action_provider: Some(CodeActionProviderCapability::Simple(true)),
        code_lens_provider: None,
        document_formatting_provider: Some(true),
        document_range_formatting_provider: None,
        document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
            first_trigger_character: "=".to_string(),
            more_trigger_character: Some(vec![".".to_string()]),
        }),
        folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
        rename_provider: Some(RenameProviderCapability::Options(RenameOptions {
            prepare_provider: Some(true),
        })),
        color_provider: None,
        execute_command_provider: Some(ExecuteCommandOptions {
            commands: vec!["apply_code_action".to_string()],
        }),
        workspace: None,
    }
}
<|endoftext|>


<commit_before>extern crate libc;

use libc::{c_char, c_int, c_short, c_void};

pub type chtype = u64; // chtypes 64 bits by default
pub type attr_t = chtype;
pub type PDCursesBool = u8;

#[repr(C)]
#[derive(Clone, Copy)]
pub struct WINDOW {
    // definition of a window
    pub _cury: i32, // current pseudo-cursor
    pub _curx: i32,
    pub _maxy: i32, // max window coordinates
    pub _maxx: i32,
    pub _begy: i32, // origin on screen
    pub _begx: i32,
    pub _flags: i32, // window properties
    pub _attrs: chtype, // standard attributes and colors
    pub bkgd: chtype, // background, normally blank
    pub _clear: PDCursesBool, // causes clear at next refresh
    pub _leaveit: PDCursesBool, // leaves cursor where it is
    pub _scroll: PDCursesBool, // allows window scrolling
    pub _nodelay: PDCursesBool, // input character wait flag
    pub _immed: PDCursesBool, // immediate update flag
    pub _sync: PDCursesBool, // synchronise window ancestors
    pub _use_keypad: PDCursesBool, // flags keypad key mode active
    pub _y: *mut *mut chtype, // pointer to line pointer array
    pub _firstch: *mut i32, // first changed character in line
    pub _lastch: *mut i32, // last changed character in line
    pub _tmarg: i32, // top of scrolling region
    pub _bmarg: i32, // bottom of scrolling region
    pub _delayms: i32, // milliseconds of delay for getch()
    pub _parx: i32, // coords relative to parent (0,0)
    pub _pary: i32,
    pub _parent: *mut WINDOW, // subwin's pointer to parent win
}

#[link(name="pdcurses",kind="static")]
extern "C" {
    // ----------------------------------------------------------------------
    //
    //  PDCurses Function Declarations
    //
    //

    // Standard

    pub fn addch(_: chtype) -> c_int;
    pub fn addchnstr(_: *const chtype, _: c_int) -> c_int;
    pub fn addchstr(_: *const chtype) -> c_int;
    pub fn addnstr(_: *const c_char, _: c_int) -> c_int;
    pub fn addstr(_: *const c_char) -> c_int;
    pub fn attroff(_: chtype) -> c_int;
    pub fn attron(_: chtype) -> c_int;
    pub fn attrset(_: chtype) -> c_int;
    pub fn attr_get(_: *mut attr_t, _: *mut c_short, _: *mut c_void) -> c_int;
    pub fn attr_off(_: attr_t, _: *mut c_void) -> c_int;
    pub fn attr_on(_: attr_t, _: *mut c_void) -> c_int;
    pub fn attr_set(_: attr_t, _: c_short, _: *mut c_void) -> c_int;

    pub fn baudrate() -> c_int;
    pub fn beep() -> c_int;
    pub fn bkgd(_: chtype) -> c_int;
    pub fn bkgdset(_: chtype);
    pub fn border(_: chtype,
                  _: chtype,
                  _: chtype,
                  _: chtype,
                  _: chtype,
                  _: chtype,
                  _: chtype,
                  _: chtype)
                  -> c_int;
    pub fn pdc_box(_: *mut WINDOW, _: chtype, _: chtype) -> c_int;

    pub fn cbreak() -> c_int;
    pub fn echo() -> c_int;
    pub fn endwin() -> c_int;
    pub fn getch() -> c_int;
    pub fn initscr() -> *mut WINDOW;
    pub fn nocbreak() -> c_int;
    pub fn nodelay(_: *mut WINDOW, _: bool) -> c_int;
    pub fn printw(_: *const c_char) -> c_int;
    pub fn refresh() -> c_int;
    pub fn wgetch(_: *mut WINDOW) -> c_int;
}
<commit_msg>Added function bindings for the functions that start with 'c'<commit_after>extern crate libc;

use libc::{c_char, c_int, c_short, c_void};

pub type chtype = u64; // chtypes 64 bits by default
pub type attr_t = chtype;
pub type pdc_bool = u8;

#[repr(C)]
#[derive(Clone, Copy)]
pub struct WINDOW {
    // definition of a window
    pub _cury: i32, // current pseudo-cursor
    pub _curx: i32,
    pub _maxy: i32, // max window coordinates
    pub _maxx: i32,
    pub _begy: i32, // origin on screen
    pub _begx: i32,
    pub _flags: i32, // window properties
    pub _attrs: chtype, // standard attributes and colors
    pub bkgd: chtype, // background, normally blank
    pub _clear: pdc_bool, // causes clear at next refresh
    pub _leaveit: pdc_bool, // leaves cursor where it is
    pub _scroll: pdc_bool, // allows window scrolling
    pub _nodelay: pdc_bool, // input character wait flag
    pub _immed: pdc_bool, // immediate update flag
    pub _sync: pdc_bool, // synchronise window ancestors
    pub _use_keypad: pdc_bool, // flags keypad key mode active
    pub _y: *mut *mut chtype, // pointer to line pointer array
    pub _firstch: *mut i32, // first changed character in line
    pub _lastch: *mut i32, // last changed character in line
    pub _tmarg: i32, // top of scrolling region
    pub _bmarg: i32, // bottom of scrolling region
    pub _delayms: i32, // milliseconds of delay for getch()
    pub _parx: i32, // coords relative to parent (0,0)
    pub _pary: i32,
    pub _parent: *mut WINDOW, // subwin's pointer to parent win
}

#[link(name="pdcurses",kind="static")]
extern "C" {
    // ----------------------------------------------------------------------
    //
    //  PDCurses Function Declarations
    //
    //

    // Standard

    pub fn addch(_: chtype) -> c_int;
    pub fn addchnstr(_: *const chtype, _: c_int) -> c_int;
    pub fn addchstr(_: *const chtype) -> c_int;
    pub fn addnstr(_: *const c_char, _: c_int) -> c_int;
    pub fn addstr(_: *const c_char) -> c_int;
    pub fn attroff(_: chtype) -> c_int;
    pub fn attron(_: chtype) -> c_int;
    pub fn attrset(_: chtype) -> c_int;
    pub fn attr_get(_: *mut attr_t, _: *mut c_short, _: *mut c_void) -> c_int;
    pub fn attr_off(_: attr_t, _: *mut c_void) -> c_int;
    pub fn attr_on(_: attr_t, _: *mut c_void) -> c_int;
    pub fn attr_set(_: attr_t, _: c_short, _: *mut c_void) -> c_int;

    pub fn baudrate() -> c_int;
    pub fn beep() -> c_int;
    pub fn bkgd(_: chtype) -> c_int;
    pub fn bkgdset(_: chtype);
    pub fn border(_: chtype,
                  _: chtype,
                  _: chtype,
                  _: chtype,
                  _: chtype,
                  _: chtype,
                  _: chtype,
                  _: chtype)
                  -> c_int;
    pub fn pdc_box(_: *mut WINDOW, _: chtype, _: chtype) -> c_int;

    pub fn can_change_color() -> pdc_bool;
    pub fn cbreak() -> c_int;
    pub fn chgat(_: c_int, _: attr_t, _: c_short, _: *const c_void) -> c_int;
    pub fn clearok(_: *mut WINDOW, _: pdc_bool) -> c_int;
    pub fn clear() -> c_int;
    pub fn clrtobot() -> c_int;
    pub fn clrtoeol() -> c_int;
    pub fn color_content(_: c_short, _: *mut c_short, _: *mut c_short, _: *mut c_short) -> c_int;
    pub fn color_set(_: short, _: *mut c_void) -> c_int;
    pub fn copywin(_: *const WINDOW,
                   _: *mut WINDOW,
                   _: c_int,
                   _: c_int,
                   _: c_int,
                   _: c_int,
                   _: c_int,
                   _: c_int,
                   _: c_int)
                   -> c_int;
    pub fn curs_set(_: c_int) -> c_int;

    pub fn echo() -> c_int;
    pub fn endwin() -> c_int;
    pub fn getch() -> c_int;
    pub fn initscr() -> *mut WINDOW;
    pub fn nocbreak() -> c_int;
    pub fn nodelay(_: *mut WINDOW, _: bool) -> c_int;
    pub fn printw(_: *const c_char) -> c_int;
    pub fn refresh() -> c_int;
    pub fn wgetch(_: *mut WINDOW) -> c_int;
}
<|endoftext|>


<commit_before>#![allow(unused_imports,dead_code)]

#[macro_use]
extern crate lazy_static;

mod color;
mod style;

use color::*;

use std::convert::From;
use std::ops::Deref;
use std::string::String;
use std::fmt;

/// Colored mean both color or styled
#[derive(Debug,PartialEq, Eq)]
pub struct ColoredString {
    input: String,
    fgcolor: Option<Color>,
    bgcolor: Option<Color>,
    style: style::Style
}

pub trait Colorize {
    // Font Colors
    fn black(self) -> ColoredString;
    fn red(self) -> ColoredString;
    fn green(self) -> ColoredString;
    fn yellow(self) -> ColoredString;
    fn blue(self) -> ColoredString;
    fn magenta(self) -> ColoredString;
    fn purple(self) -> ColoredString;
    fn cyan(self) -> ColoredString;
    fn white(self) -> ColoredString;
    // Background Colors
    fn on_black(self) -> ColoredString;
    fn on_red(self) -> ColoredString;
    fn on_green(self) -> ColoredString;
    fn on_yellow(self) -> ColoredString;
    fn on_blue(self) -> ColoredString;
    fn on_magenta(self) -> ColoredString;
    fn on_purple(self) -> ColoredString;
    fn on_cyan(self) -> ColoredString;
    fn on_white(self) -> ColoredString;
    // Styles
    fn clear(self) -> ColoredString;
    fn normal(self) -> ColoredString;
    fn bold(self) -> ColoredString;
    fn dimmed(self) -> ColoredString;
    fn italic(self) -> ColoredString;
    fn underline(self) -> ColoredString;
    fn blink(self) -> ColoredString;
    fn reverse(self) -> ColoredString;
    fn hidden(self) -> ColoredString;
}

impl ColoredString {
    pub fn is_plain(&self) -> bool {
        (self.bgcolor.is_none() && self.fgcolor.is_none()
            && self.style == style::CLEAR)
    }

    fn has_colors(&self) -> bool {
        use std::env::var_os;
        use std::ffi::OsString;
        fn is_good(var: Option<OsString>) -> bool {
            var.is_none() || var != Some("0".into())
        }
        lazy_static! {
            static ref COLOR_STATE : bool = (
                (var_os("CLICOLOR_FORCE").or(Some("0".into())) != Some("0".into())) || is_good(var_os("CLICOLOR"))
            );
        }
        *COLOR_STATE
    }
}

impl Default for ColoredString {
    fn default() -> Self {
        ColoredString {
            input: String::default(),
            fgcolor: None,
            bgcolor: None,
            style: style::CLEAR
        }
    }
}

impl Deref for ColoredString {
    type Target = str;
    fn deref(&self) -> &str {
        &self.input
    }
}

impl<'a> From<&'a str> for ColoredString {
    fn from(s: &'a str) -> Self {
        ColoredString {
            input: String::from(s), .. ColoredString::default()
        }
    }
}

macro_rules! def_color {
    ($side:ident: $name: ident => $color: path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                $side: Some($color), .. self
            }
        }
    };
}

macro_rules! def_style {
    ($name: ident, $value: path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                style: style::Style::from_both(self.style, $value),
                .. self
            }
        }
    };
}

impl Colorize for ColoredString {
    def_color!(fgcolor: black => Color::Black);
    fn red(self) -> ColoredString {
        ColoredString {
            fgcolor: Some(Color::Red), .. self
        }
    }
    def_color!(fgcolor: green => Color::Green);
    def_color!(fgcolor: yellow => Color::Yellow);
    def_color!(fgcolor: blue => Color::Blue);
    def_color!(fgcolor: magenta => Color::Magenta);
    def_color!(fgcolor: purple => Color::Magenta);
    def_color!(fgcolor: cyan => Color::Cyan);
    def_color!(fgcolor: white => Color::White);

    def_color!(bgcolor: on_black => Color::Black);
    fn on_red(self) -> ColoredString {
        ColoredString {
            bgcolor: Some(Color::Red), .. self
        }
    }
    def_color!(bgcolor: on_green => Color::Green);
    def_color!(bgcolor: on_yellow => Color::Yellow);
    def_color!(bgcolor: on_blue => Color::Blue);
    def_color!(bgcolor: on_magenta => Color::Magenta);
    def_color!(bgcolor: on_purple => Color::Magenta);
    def_color!(bgcolor: on_cyan => Color::Cyan);
    def_color!(bgcolor: on_white => Color::White);

    fn clear(self) -> ColoredString {
        ColoredString {
            input: self.input,
            .. ColoredString::default()
        }
    }
    fn normal(self) -> ColoredString { self.clear() }
    def_style!(bold, style::Styles::Bold);
    def_style!(dimmed, style::Styles::Dimmed);
    def_style!(italic, style::Styles::Italic);
    def_style!(underline, style::Styles::Underline);
    def_style!(blink, style::Styles::Blink);
    def_style!(reverse, style::Styles::Reversed);
    def_style!(hidden, style::Styles::Hidden);
}

macro_rules! def_str_color {
    ($side:ident: $name: ident => $color: path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                input: String::from(self),
                $side: Some($color),
                .. ColoredString::default()
            }
        }
    }
}

macro_rules! def_str_style {
    ($name:ident, $style:path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                input: String::from(self),
                style: style::Style::new($style),
                .. ColoredString::default()
            }
        }
    }
}

impl<'a> Colorize for &'a str {
    def_str_color!(fgcolor: black => Color::Black);
    fn red(self) -> ColoredString {
        ColoredString {
            input: String::from(self),
            fgcolor: Some(Color::Red),
            .. ColoredString::default()
        }
    }
    def_str_color!(fgcolor: green => Color::Green);
    def_str_color!(fgcolor: yellow => Color::Yellow);
    def_str_color!(fgcolor: blue => Color::Blue);
    def_str_color!(fgcolor: magenta => Color::Magenta);
    def_str_color!(fgcolor: purple => Color::Magenta);
    def_str_color!(fgcolor: cyan => Color::Cyan);
    def_str_color!(fgcolor: white => Color::White);

    def_str_color!(bgcolor: on_black => Color::Black);
    fn on_red(self) -> ColoredString {
        ColoredString {
            input: String::from(self),
            bgcolor: Some(Color::Red),
            .. ColoredString::default()
        }
    }
    def_str_color!(bgcolor: on_green => Color::Green);
    def_str_color!(bgcolor: on_yellow => Color::Yellow);
    def_str_color!(bgcolor: on_blue => Color::Blue);
    def_str_color!(bgcolor: on_magenta => Color::Magenta);
    def_str_color!(bgcolor: on_purple => Color::Magenta);
    def_str_color!(bgcolor: on_cyan => Color::Cyan);
    def_str_color!(bgcolor: on_white => Color::White);

    fn clear(self) -> ColoredString {
        ColoredString {
            input: String::from(self),
            style: style::CLEAR,
            .. ColoredString::default()
        }
    }
    fn normal(self) -> ColoredString { self.clear() }
    def_str_style!(bold, style::Styles::Bold);
    def_str_style!(dimmed, style::Styles::Dimmed);
    def_str_style!(italic, style::Styles::Italic);
    def_str_style!(underline, style::Styles::Underline);
    def_str_style!(blink, style::Styles::Blink);
    def_str_style!(reverse, style::Styles::Reversed);
    def_str_style!(hidden, style::Styles::Hidden);
}

impl fmt::Display for ColoredString {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

        println!("has color: {}", self.has_colors());

        if !self.has_colors() || self.is_plain() {
            try!(f.write_str(&self.input));
            return Ok(())
        }

        try!(f.write_str("\x1B["));
        let mut has_wrote = false;

        if self.style != style::CLEAR {
            try!(f.write_str(&self.style.to_str()));
            has_wrote = true;
        }

        if let Some(ref color) = self.bgcolor {
            if has_wrote { try!(f.write_str(";")) }
            try!(f.write_str(color.to_bg_str()));
            has_wrote = true;
        }

        if let Some(ref color) = self.fgcolor {
            if has_wrote { try!(f.write_str(";")) }
            try!(f.write_str(color.to_fg_str()));
        }

        try!(f.write_str("m")   );
        try!(f.write_str(&self.input));
        try!(f.write_str("\x1B[0m"));
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let toto = "toto";
        println!("{}", toto.red());
        println!("{}", String::from(toto).red());
        println!("{}", toto.blue());

        println!("blue style ****");
        println!("{}", toto.bold());
        println!("{}", "yeah ! Red bold !".red().bold());
        println!("{}", "yeah ! Yellow bold !".bold().yellow());
        println!("{}", toto.bold().blue());
        println!("{}", toto.blue().bold());
        println!("{}", toto.blue().bold().underline());
        println!("{}", toto.blue().italic());
        println!("******");
        println!("test clearing");
        println!("{}", "red cleared".red().clear());
        println!("{}", "bold cyan cleared".bold().cyan().clear());
        println!("******");
        println!("Bg tests");
        println!("{}", toto.green().on_blue());
        println!("{}", toto.on_magenta().yellow());
        println!("{}", toto.purple().on_yellow());
        println!("{}", toto.magenta().on_white());
        println!("{}", toto.cyan().on_green());
        println!("{}", toto.black().on_white());
        println!("******");
        println!("{}", toto.green());
        println!("{}", toto.yellow());
        println!("{}", toto.purple());
        println!("{}", toto.magenta());
        println!("{}", toto.cyan());
        println!("{}", toto.white());
        println!("{}", toto.white().red().blue().green());
        // uncomment to see term output
        //assert!(false)
    }
}
<commit_msg>remove debug print<commit_after>#![allow(unused_imports,dead_code)]

#[macro_use]
extern crate lazy_static;

mod color;
mod style;

use color::*;

use std::convert::From;
use std::ops::Deref;
use std::string::String;
use std::fmt;

/// Colored mean both color or styled
#[derive(Debug,PartialEq, Eq)]
pub struct ColoredString {
    input: String,
    fgcolor: Option<Color>,
    bgcolor: Option<Color>,
    style: style::Style
}

pub trait Colorize {
    // Font Colors
    fn black(self) -> ColoredString;
    fn red(self) -> ColoredString;
    fn green(self) -> ColoredString;
    fn yellow(self) -> ColoredString;
    fn blue(self) -> ColoredString;
    fn magenta(self) -> ColoredString;
    fn purple(self) -> ColoredString;
    fn cyan(self) -> ColoredString;
    fn white(self) -> ColoredString;
    // Background Colors
    fn on_black(self) -> ColoredString;
    fn on_red(self) -> ColoredString;
    fn on_green(self) -> ColoredString;
    fn on_yellow(self) -> ColoredString;
    fn on_blue(self) -> ColoredString;
    fn on_magenta(self) -> ColoredString;
    fn on_purple(self) -> ColoredString;
    fn on_cyan(self) -> ColoredString;
    fn on_white(self) -> ColoredString;
    // Styles
    fn clear(self) -> ColoredString;
    fn normal(self) -> ColoredString;
    fn bold(self) -> ColoredString;
    fn dimmed(self) -> ColoredString;
    fn italic(self) -> ColoredString;
    fn underline(self) -> ColoredString;
    fn blink(self) -> ColoredString;
    fn reverse(self) -> ColoredString;
    fn hidden(self) -> ColoredString;
}

impl ColoredString {
    pub fn is_plain(&self) -> bool {
        (self.bgcolor.is_none() && self.fgcolor.is_none()
            && self.style == style::CLEAR)
    }

    fn has_colors(&self) -> bool {
        use std::env::var_os;
        use std::ffi::OsString;
        fn is_good(var: Option<OsString>) -> bool {
            var.is_none() || var != Some("0".into())
        }
        lazy_static! {
            static ref COLOR_STATE : bool = (
                (var_os("CLICOLOR_FORCE").or(Some("0".into())) != Some("0".into())) || is_good(var_os("CLICOLOR"))
            );
        }
        *COLOR_STATE
    }
}

impl Default for ColoredString {
    fn default() -> Self {
        ColoredString {
            input: String::default(),
            fgcolor: None,
            bgcolor: None,
            style: style::CLEAR
        }
    }
}

impl Deref for ColoredString {
    type Target = str;
    fn deref(&self) -> &str {
        &self.input
    }
}

impl<'a> From<&'a str> for ColoredString {
    fn from(s: &'a str) -> Self {
        ColoredString {
            input: String::from(s), .. ColoredString::default()
        }
    }
}

macro_rules! def_color {
    ($side:ident: $name: ident => $color: path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                $side: Some($color), .. self
            }
        }
    };
}

macro_rules! def_style {
    ($name: ident, $value: path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                style: style::Style::from_both(self.style, $value),
                .. self
            }
        }
    };
}

impl Colorize for ColoredString {
    def_color!(fgcolor: black => Color::Black);
    fn red(self) -> ColoredString {
        ColoredString {
            fgcolor: Some(Color::Red), .. self
        }
    }
    def_color!(fgcolor: green => Color::Green);
    def_color!(fgcolor: yellow => Color::Yellow);
    def_color!(fgcolor: blue => Color::Blue);
    def_color!(fgcolor: magenta => Color::Magenta);
    def_color!(fgcolor: purple => Color::Magenta);
    def_color!(fgcolor: cyan => Color::Cyan);
    def_color!(fgcolor: white => Color::White);

    def_color!(bgcolor: on_black => Color::Black);
    fn on_red(self) -> ColoredString {
        ColoredString {
            bgcolor: Some(Color::Red), .. self
        }
    }
    def_color!(bgcolor: on_green => Color::Green);
    def_color!(bgcolor: on_yellow => Color::Yellow);
    def_color!(bgcolor: on_blue => Color::Blue);
    def_color!(bgcolor: on_magenta => Color::Magenta);
    def_color!(bgcolor: on_purple => Color::Magenta);
    def_color!(bgcolor: on_cyan => Color::Cyan);
    def_color!(bgcolor: on_white => Color::White);

    fn clear(self) -> ColoredString {
        ColoredString {
            input: self.input,
            .. ColoredString::default()
        }
    }
    fn normal(self) -> ColoredString { self.clear() }
    def_style!(bold, style::Styles::Bold);
    def_style!(dimmed, style::Styles::Dimmed);
    def_style!(italic, style::Styles::Italic);
    def_style!(underline, style::Styles::Underline);
    def_style!(blink, style::Styles::Blink);
    def_style!(reverse, style::Styles::Reversed);
    def_style!(hidden, style::Styles::Hidden);
}

macro_rules! def_str_color {
    ($side:ident: $name: ident => $color: path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                input: String::from(self),
                $side: Some($color),
                .. ColoredString::default()
            }
        }
    }
}

macro_rules! def_str_style {
    ($name:ident, $style:path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                input: String::from(self),
                style: style::Style::new($style),
                .. ColoredString::default()
            }
        }
    }
}

impl<'a> Colorize for &'a str {
    def_str_color!(fgcolor: black => Color::Black);
    fn red(self) -> ColoredString {
        ColoredString {
            input: String::from(self),
            fgcolor: Some(Color::Red),
            .. ColoredString::default()
        }
    }
    def_str_color!(fgcolor: green => Color::Green);
    def_str_color!(fgcolor: yellow => Color::Yellow);
    def_str_color!(fgcolor: blue => Color::Blue);
    def_str_color!(fgcolor: magenta => Color::Magenta);
    def_str_color!(fgcolor: purple => Color::Magenta);
    def_str_color!(fgcolor: cyan => Color::Cyan);
    def_str_color!(fgcolor: white => Color::White);

    def_str_color!(bgcolor: on_black => Color::Black);
    fn on_red(self) -> ColoredString {
        ColoredString {
            input: String::from(self),
            bgcolor: Some(Color::Red),
            .. ColoredString::default()
        }
    }
    def_str_color!(bgcolor: on_green => Color::Green);
    def_str_color!(bgcolor: on_yellow => Color::Yellow);
    def_str_color!(bgcolor: on_blue => Color::Blue);
    def_str_color!(bgcolor: on_magenta => Color::Magenta);
    def_str_color!(bgcolor: on_purple => Color::Magenta);
    def_str_color!(bgcolor: on_cyan => Color::Cyan);
    def_str_color!(bgcolor: on_white => Color::White);

    fn clear(self) -> ColoredString {
        ColoredString {
            input: String::from(self),
            style: style::CLEAR,
            .. ColoredString::default()
        }
    }
    fn normal(self) -> ColoredString { self.clear() }
    def_str_style!(bold, style::Styles::Bold);
    def_str_style!(dimmed, style::Styles::Dimmed);
    def_str_style!(italic, style::Styles::Italic);
    def_str_style!(underline, style::Styles::Underline);
    def_str_style!(blink, style::Styles::Blink);
    def_str_style!(reverse, style::Styles::Reversed);
    def_str_style!(hidden, style::Styles::Hidden);
}

impl fmt::Display for ColoredString {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

        if !self.has_colors() || self.is_plain() {
            try!(f.write_str(&self.input));
            return Ok(())
        }

        try!(f.write_str("\x1B["));
        let mut has_wrote = false;

        if self.style != style::CLEAR {
            try!(f.write_str(&self.style.to_str()));
            has_wrote = true;
        }

        if let Some(ref color) = self.bgcolor {
            if has_wrote { try!(f.write_str(";")) }
            try!(f.write_str(color.to_bg_str()));
            has_wrote = true;
        }

        if let Some(ref color) = self.fgcolor {
            if has_wrote { try!(f.write_str(";")) }
            try!(f.write_str(color.to_fg_str()));
        }

        try!(f.write_str("m")   );
        try!(f.write_str(&self.input));
        try!(f.write_str("\x1B[0m"));
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let toto = "toto";
        println!("{}", toto.red());
        println!("{}", String::from(toto).red());
        println!("{}", toto.blue());

        println!("blue style ****");
        println!("{}", toto.bold());
        println!("{}", "yeah ! Red bold !".red().bold());
        println!("{}", "yeah ! Yellow bold !".bold().yellow());
        println!("{}", toto.bold().blue());
        println!("{}", toto.blue().bold());
        println!("{}", toto.blue().bold().underline());
        println!("{}", toto.blue().italic());
        println!("******");
        println!("test clearing");
        println!("{}", "red cleared".red().clear());
        println!("{}", "bold cyan cleared".bold().cyan().clear());
        println!("******");
        println!("Bg tests");
        println!("{}", toto.green().on_blue());
        println!("{}", toto.on_magenta().yellow());
        println!("{}", toto.purple().on_yellow());
        println!("{}", toto.magenta().on_white());
        println!("{}", toto.cyan().on_green());
        println!("{}", toto.black().on_white());
        println!("******");
        println!("{}", toto.green());
        println!("{}", toto.yellow());
        println!("{}", toto.purple());
        println!("{}", toto.magenta());
        println!("{}", toto.cyan());
        println!("{}", toto.white());
        println!("{}", toto.white().red().blue().green());
        // uncomment to see term output
        //assert!(false)
    }
}
<|endoftext|>


<commit_before>
extern crate chrono;
extern crate ansi_term;
extern crate time;

pub mod logger;
pub mod test_case;
<commit_msg>deleted unneeded linefeed<commit_after>extern crate chrono;
extern crate ansi_term;
extern crate time;

pub mod logger;
pub mod test_case;
<|endoftext|>


<commit_before>//! Functionality for working with SIMD registers and instructions.
//!
//! [Source](https://github.com/huonw/simd), [crates.io](https://crates.io/crates/simd)

#![feature(trace_macros)]

extern crate simdty;
extern crate llvmint;

use std::mem;

pub use convert::bitcast::Bitcast;
pub use convert::semantic::Convert;

mod convert;

mod generated;

/// A SIMD vector, storing precisely `count()` elements of (primitive)
/// type `Item` sequentially in memory.
///
/// This trait is `unsafe` because it is used inside `unsafe` code
/// relying on the correctness of `Item` and `count()`.
pub unsafe trait Vector: Sized + Copy {
    /// The type that this vector contains.
    type Item;

    /// Return the number of items in `self`.
    #[inline(always)]
    fn count(_: Option<Self>) -> usize {
        let vsize = mem::size_of::<Self>();
        let esize = mem::size_of::<Self::Item>();
        assert!(vsize % esize == 0);

        vsize / esize
    }
}

pub unsafe trait HalfVector: Vector {
    type Half /*: Vector<Item = Self::Item>*/;

    fn split(self) -> (Self::Half, Self::Half);

    #[inline]
    fn lower(self) -> Self::Half { self.split().0 }
    #[inline]
    fn upper(self) -> Self::Half { self.split().1 }
}
pub unsafe trait DoubleVector: Vector {
    type Double /*: Vector<Item = Self::Item>*/;

    fn merge(self, other: Self) -> Self::Double;
}
<commit_msg>Document {Half,Double}Vector.<commit_after>//! Functionality for working with SIMD registers and instructions.
//!
//! [Source](https://github.com/huonw/simd), [crates.io](https://crates.io/crates/simd)

#![feature(trace_macros)]

extern crate simdty;
extern crate llvmint;

use std::mem;

pub use convert::bitcast::Bitcast;
pub use convert::semantic::Convert;

mod convert;

mod generated;

/// A SIMD vector, storing precisely `count()` elements of (primitive)
/// type `Item` sequentially in memory.
///
/// This trait is `unsafe` because it is used inside `unsafe` code
/// relying on the correctness of `Item` and `count()`.
pub unsafe trait Vector: Sized + Copy {
    /// The type that this vector contains.
    type Item;

    /// Return the number of items in `self`.
    #[inline(always)]
    fn count(_: Option<Self>) -> usize {
        let vsize = mem::size_of::<Self>();
        let esize = mem::size_of::<Self::Item>();
        assert!(vsize % esize == 0);

        vsize / esize
    }
}

/// SIMD vectors which can be separated into two SIMD vectors of half
/// the size with the same elements.
pub unsafe trait HalfVector: Vector {
    type Half /*: Vector<Item = Self::Item>*/;

    /// Retrieve the upper and lower halves of the `self` vector.
    fn split(self) -> (Self::Half, Self::Half);

    /// Retrieve the lower half of the `self` vector.
    #[inline]
    fn lower(self) -> Self::Half { self.split().0 }
    /// Retrieve the upper half of the `self` vector.
    #[inline]
    fn upper(self) -> Self::Half { self.split().1 }
}
/// SIMD vectors which can be merged with another of the same type to
/// create one of double the length with the same elements.
pub unsafe trait DoubleVector: Vector {
    type Double /*: Vector<Item = Self::Item>*/;

    /// Concatenate the elements of `self` and `other` into a single
    /// SIMD vector.
    fn merge(self, other: Self) -> Self::Double;
}
<|endoftext|>


<commit_before>extern crate "route-recognizer" as router;
extern crate conduit;

use std::collections::hash_map::{HashMap, Entry};
use std::error::Error;
use std::fmt;

use router::{Router, Match};
use conduit::{Method, Handler, Request, Response};

pub struct RouteBuilder {
    routers: HashMap<Method, Router<Box<Handler + Send + Sync>>>
}

pub struct RouterError(String);

impl RouteBuilder {
    pub fn new() -> RouteBuilder {
        RouteBuilder { routers: HashMap::new() }
    }

    pub fn recognize<'a>(&'a self, method: &Method, path: &str)
                         -> Result<Match<&'a Box<Handler + Send + Sync>>,
                                   RouterError>
    {
        match self.routers.get(method) {
            Some(router) => router.recognize(path),
            None => Err(format!("No router found for {:?}", method)),
        }.map_err(RouterError)
    }

    pub fn map<'a, H: Handler>(&'a mut self, method: Method, pattern: &str,
                               handler: H) -> &'a mut RouteBuilder {
        {
            let router = match self.routers.entry(method) {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(Router::new()),
            };
            router.add(pattern, Box::new(handler));
        }
        self
    }

    pub fn get<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                               -> &'a mut RouteBuilder {
        self.map(Method::Get, pattern, handler)
    }

    pub fn post<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                                -> &'a mut RouteBuilder {
        self.map(Method::Post, pattern, handler)
    }

    pub fn put<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                               -> &'a mut RouteBuilder {
        self.map(Method::Put, pattern, handler)
    }

    pub fn delete<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                                  -> &'a mut RouteBuilder {
        self.map(Method::Delete, pattern, handler)
    }

    pub fn head<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                                -> &'a mut RouteBuilder {
        self.map(Method::Head, pattern, handler)
    }
}

impl conduit::Handler for RouteBuilder {
    fn call(&self, request: &mut Request) -> Result<Response, Box<Error+Send>> {
        let m = {
            let method = request.method();
            let path = request.path();

            match self.recognize(&method, path) {
                Ok(m) => m,
                Err(e) => return Err(Box::new(e) as Box<Error+Send>)
            }
        };

        {
            let extensions = request.mut_extensions();
            extensions.insert(m.params.clone());
        }

        (*m.handler).call(request)
    }
}

impl Error for RouterError {
    fn description(&self) -> &str { self.0.as_slice() }
}

impl fmt::Display for RouterError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

pub trait RequestParams<'a> {
    fn params(self) -> &'a router::Params;
}

pub fn params<'a>(req: &'a Request) -> &'a router::Params {
    req.extensions().find::<router::Params>()
        .expect("Missing params")
}

impl<'a> RequestParams<'a> for &'a (Request + 'a) {
    fn params(self) -> &'a router::Params {
        params(self)
    }
}

#[cfg(test)]
mod tests {
    extern crate semver;
    use std::collections::HashMap;
    use std::error::Error;
    use std::old_io::MemReader;
    use std::old_io::net::ip::IpAddr;

    use {RouteBuilder, RequestParams};

    use conduit;
    use conduit::{Handler, Method, Scheme, Host, Headers, Extensions, TypeMap};

    struct RequestSentinel {
        method: Method,
        path: String,
        extensions: conduit::Extensions
    }

    impl RequestSentinel {
        fn new(method: Method, path: &'static str) -> RequestSentinel {
            RequestSentinel {
                path: path.to_string(),
                extensions: TypeMap::new(),
                method: method
            }
        }
    }

    impl conduit::Request for RequestSentinel {
        fn http_version(&self) -> semver::Version { unimplemented!() }
        fn conduit_version(&self) -> semver::Version { unimplemented!() }
        fn method(&self) -> Method { self.method }
        fn scheme(&self) -> Scheme { unimplemented!() }
        fn host<'a>(&'a self) -> Host<'a> { unimplemented!() }
        fn virtual_root<'a>(&'a self) -> Option<&'a str> { unimplemented!() }
        fn path<'a>(&'a self) -> &'a str {
            self.path.as_slice()
        }
        fn query_string<'a>(&'a self) -> Option<&'a str> { unimplemented!() }
        fn remote_ip(&self) -> IpAddr { unimplemented!() }
        fn content_length(&self) -> Option<u64> { unimplemented!() }
        fn headers<'a>(&'a self) -> &'a Headers { unimplemented!() }
        fn body<'a>(&'a mut self) -> &'a mut Reader { unimplemented!() }
        fn extensions<'a>(&'a self) -> &'a Extensions {
            &self.extensions
        }
        fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions {
            &mut self.extensions
        }
    }

    #[test]
    fn basic_get() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::Get, "/posts/1");
        let mut res = router.call(&mut req).ok().expect("No response");

        assert_eq!(res.status, (200, "OK"));
        assert_eq!(res.body.read_to_string().unwrap(), "1, Get".to_string());
    }

    #[test]
    fn basic_post() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::Post, "/posts/10");
        let mut res = router.call(&mut req).ok().expect("No response");

        assert_eq!(res.status, (200, "OK"));
        assert_eq!(res.body.read_to_string().unwrap(), "10, Post".to_string());
    }

    #[test]
    fn nonexistent_route() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::Post, "/nonexistent");
        router.call(&mut req).err().expect("No response");
    }

    fn test_router() -> RouteBuilder {
        let mut router = RouteBuilder::new();
        router.post("/posts/:id", test_handler);
        router.get("/posts/:id", test_handler);
        router
    }

    fn test_handler(req: &mut conduit::Request)
                    -> Result<conduit::Response, Box<Error+Send>> {
        let mut res = vec!();
        res.push(req.params()["id"].clone());
        res.push(format!("{:?}", req.method()));

        Ok(conduit::Response {
            status: (200, "OK"),
            headers: HashMap::new(),
            body: Box::new(MemReader::new(res.connect(", ").into_bytes()))
        })
    }
}
<commit_msg>Add feature attributes<commit_after>#![feature(core, std_misc)]
#![cfg_attr(test, feature(io))]

extern crate "route-recognizer" as router;
extern crate conduit;

use std::collections::hash_map::{HashMap, Entry};
use std::error::Error;
use std::fmt;

use router::{Router, Match};
use conduit::{Method, Handler, Request, Response};

pub struct RouteBuilder {
    routers: HashMap<Method, Router<Box<Handler + Send + Sync>>>
}

pub struct RouterError(String);

impl RouteBuilder {
    pub fn new() -> RouteBuilder {
        RouteBuilder { routers: HashMap::new() }
    }

    pub fn recognize<'a>(&'a self, method: &Method, path: &str)
                         -> Result<Match<&'a Box<Handler + Send + Sync>>,
                                   RouterError>
    {
        match self.routers.get(method) {
            Some(router) => router.recognize(path),
            None => Err(format!("No router found for {:?}", method)),
        }.map_err(RouterError)
    }

    pub fn map<'a, H: Handler>(&'a mut self, method: Method, pattern: &str,
                               handler: H) -> &'a mut RouteBuilder {
        {
            let router = match self.routers.entry(method) {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(Router::new()),
            };
            router.add(pattern, Box::new(handler));
        }
        self
    }

    pub fn get<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                               -> &'a mut RouteBuilder {
        self.map(Method::Get, pattern, handler)
    }

    pub fn post<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                                -> &'a mut RouteBuilder {
        self.map(Method::Post, pattern, handler)
    }

    pub fn put<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                               -> &'a mut RouteBuilder {
        self.map(Method::Put, pattern, handler)
    }

    pub fn delete<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                                  -> &'a mut RouteBuilder {
        self.map(Method::Delete, pattern, handler)
    }

    pub fn head<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                                -> &'a mut RouteBuilder {
        self.map(Method::Head, pattern, handler)
    }
}

impl conduit::Handler for RouteBuilder {
    fn call(&self, request: &mut Request) -> Result<Response, Box<Error+Send>> {
        let m = {
            let method = request.method();
            let path = request.path();

            match self.recognize(&method, path) {
                Ok(m) => m,
                Err(e) => return Err(Box::new(e) as Box<Error+Send>)
            }
        };

        {
            let extensions = request.mut_extensions();
            extensions.insert(m.params.clone());
        }

        (*m.handler).call(request)
    }
}

impl Error for RouterError {
    fn description(&self) -> &str { self.0.as_slice() }
}

impl fmt::Display for RouterError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

pub trait RequestParams<'a> {
    fn params(self) -> &'a router::Params;
}

pub fn params<'a>(req: &'a Request) -> &'a router::Params {
    req.extensions().find::<router::Params>()
        .expect("Missing params")
}

impl<'a> RequestParams<'a> for &'a (Request + 'a) {
    fn params(self) -> &'a router::Params {
        params(self)
    }
}

#[cfg(test)]
mod tests {
    extern crate semver;
    use std::collections::HashMap;
    use std::error::Error;
    use std::old_io::MemReader;
    use std::old_io::net::ip::IpAddr;

    use {RouteBuilder, RequestParams};

    use conduit;
    use conduit::{Handler, Method, Scheme, Host, Headers, Extensions, TypeMap};

    struct RequestSentinel {
        method: Method,
        path: String,
        extensions: conduit::Extensions
    }

    impl RequestSentinel {
        fn new(method: Method, path: &'static str) -> RequestSentinel {
            RequestSentinel {
                path: path.to_string(),
                extensions: TypeMap::new(),
                method: method
            }
        }
    }

    impl conduit::Request for RequestSentinel {
        fn http_version(&self) -> semver::Version { unimplemented!() }
        fn conduit_version(&self) -> semver::Version { unimplemented!() }
        fn method(&self) -> Method { self.method }
        fn scheme(&self) -> Scheme { unimplemented!() }
        fn host<'a>(&'a self) -> Host<'a> { unimplemented!() }
        fn virtual_root<'a>(&'a self) -> Option<&'a str> { unimplemented!() }
        fn path<'a>(&'a self) -> &'a str {
            self.path.as_slice()
        }
        fn query_string<'a>(&'a self) -> Option<&'a str> { unimplemented!() }
        fn remote_ip(&self) -> IpAddr { unimplemented!() }
        fn content_length(&self) -> Option<u64> { unimplemented!() }
        fn headers<'a>(&'a self) -> &'a Headers { unimplemented!() }
        fn body<'a>(&'a mut self) -> &'a mut Reader { unimplemented!() }
        fn extensions<'a>(&'a self) -> &'a Extensions {
            &self.extensions
        }
        fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions {
            &mut self.extensions
        }
    }

    #[test]
    fn basic_get() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::Get, "/posts/1");
        let mut res = router.call(&mut req).ok().expect("No response");

        assert_eq!(res.status, (200, "OK"));
        assert_eq!(res.body.read_to_string().unwrap(), "1, Get".to_string());
    }

    #[test]
    fn basic_post() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::Post, "/posts/10");
        let mut res = router.call(&mut req).ok().expect("No response");

        assert_eq!(res.status, (200, "OK"));
        assert_eq!(res.body.read_to_string().unwrap(), "10, Post".to_string());
    }

    #[test]
    fn nonexistent_route() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::Post, "/nonexistent");
        router.call(&mut req).err().expect("No response");
    }

    fn test_router() -> RouteBuilder {
        let mut router = RouteBuilder::new();
        router.post("/posts/:id", test_handler);
        router.get("/posts/:id", test_handler);
        router
    }

    fn test_handler(req: &mut conduit::Request)
                    -> Result<conduit::Response, Box<Error+Send>> {
        let mut res = vec!();
        res.push(req.params()["id"].clone());
        res.push(format!("{:?}", req.method()));

        Ok(conduit::Response {
            status: (200, "OK"),
            headers: HashMap::new(),
            body: Box::new(MemReader::new(res.connect(", ").into_bytes()))
        })
    }
}
<|endoftext|>


<commit_before>//! Experimental Rust utilities for writing fast, streaming parsers without
//! allocating memory.

#![license = "Public domain (Unlicense)"]
#![experimental]
// Feel free to disable these if they become too annoying.
#![deny(missing_doc)]
#![deny(warnings)]

#![feature(macro_rules, slicing_syntax)]

#[cfg(test)] extern crate test;

// Want to share your experiments, hacks, etc.?  Just add a module.

pub mod iter;
pub mod buffers;
<commit_msg>Remove now-unsupported feature declaration<commit_after>//! Experimental Rust utilities for writing fast, streaming parsers without
//! allocating memory.

#![license = "Public domain (Unlicense)"]
#![experimental]
// Feel free to disable these if they become too annoying.
#![deny(missing_doc)]
#![deny(warnings)]

#![feature(macro_rules)]

#[cfg(test)] extern crate test;

// Want to share your experiments, hacks, etc.?  Just add a module.

pub mod iter;
pub mod buffers;
<|endoftext|>