<commit_before>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc::ty::TypeFoldable;
use rustc::ty::subst::{Kind, Substs};
use rustc::ty::{Ty, TyCtxt, ClosureSubsts, RegionVid, RegionKind};
use rustc::mir::{Mir, Location, Rvalue, BasicBlock, Statement, StatementKind};
use rustc::mir::visit::{MutVisitor, Lookup};
use rustc::mir::transform::{MirPass, MirSource};
use rustc::infer::{self, InferCtxt};
use rustc::util::nodemap::FxHashSet;
use syntax_pos::DUMMY_SP;
use std::collections::HashMap;

#[allow(dead_code)]
struct NLLVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
    lookup_map: HashMap<RegionVid, Lookup>,
    regions: Vec<Region>,
    infcx: InferCtxt<'a, 'gcx, 'tcx>,
}

impl<'a, 'gcx, 'tcx> NLLVisitor<'a, 'gcx, 'tcx> {
    pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self {
        NLLVisitor {
            infcx,
            lookup_map: HashMap::new(),
            regions: vec![],
        }
    }

    pub fn into_results(self) -> HashMap<RegionVid, Lookup> {
        self.lookup_map
    }

    fn renumber_regions<T>(&mut self, value: &T) -> T where T: TypeFoldable<'tcx> {
        self.infcx.tcx.fold_regions(value, &mut false, |_region, _depth| {
            self.regions.push(Region::default());
            self.infcx.next_region_var(infer::MiscVariable(DUMMY_SP))
        })
    }

    fn store_region(&mut self, region: &RegionKind, lookup: Lookup) {
        if let RegionKind::ReVar(rid) = *region {
            self.lookup_map.entry(rid).or_insert(lookup);
        }
    }

    fn store_ty_regions(&mut self, ty: &Ty<'tcx>, lookup: Lookup) {
        for region in ty.regions() {
            self.store_region(region, lookup);
        }
    }

    fn store_kind_regions(&mut self, kind: &'tcx Kind, lookup: Lookup) {
        if let Some(ty) = kind.as_type() {
            self.store_ty_regions(&ty, lookup);
        } else if let Some(region) = kind.as_region() {
            self.store_region(region, lookup);
        }
    }
}

impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
    fn visit_ty(&mut self, ty: &mut Ty<'tcx>, lookup: Lookup) {
        let old_ty = *ty;
        *ty = self.renumber_regions(&old_ty);
        self.store_ty_regions(ty, lookup);
    }

    fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>, location: Location) {
        *substs = self.renumber_regions(&{*substs});
        let lookup = Lookup::Loc(location);
        for kind in *substs {
            self.store_kind_regions(kind, lookup);
        }
    }

    fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) {
        match *rvalue {
            Rvalue::Ref(ref mut r, _, _) => {
                let old_r = *r;
                *r = self.renumber_regions(&old_r);
                let lookup = Lookup::Loc(location);
                self.store_region(r, lookup);
            }
            Rvalue::Use(..) |
            Rvalue::Repeat(..) |
            Rvalue::Len(..) |
            Rvalue::Cast(..) |
            Rvalue::BinaryOp(..) |
            Rvalue::CheckedBinaryOp(..) |
            Rvalue::UnaryOp(..) |
            Rvalue::Discriminant(..) |
            Rvalue::NullaryOp(..) |
            Rvalue::Aggregate(..) => {
                // These variants don't contain regions.
            }
        }
        self.super_rvalue(rvalue, location);
    }

    fn visit_closure_substs(&mut self,
                            substs: &mut ClosureSubsts<'tcx>,
                            location: Location) {
        *substs = self.renumber_regions(substs);
        let lookup = Lookup::Loc(location);
        for kind in substs.substs {
            self.store_kind_regions(kind, lookup);
        }
    }

    fn visit_statement(&mut self,
                       block: BasicBlock,
                       statement: &mut Statement<'tcx>,
                       location: Location) {
        if let StatementKind::EndRegion(_) = statement.kind {
            statement.kind = StatementKind::Nop;
        }
        self.super_statement(block, statement, location);
    }
}

// MIR Pass for non-lexical lifetimes
pub struct NLL;

impl MirPass for NLL {
    fn run_pass<'a, 'tcx>(&self,
                          tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          _: MirSource,
                          mir: &mut Mir<'tcx>) {
        if !tcx.sess.opts.debugging_opts.nll {
            return;
        }

        tcx.infer_ctxt().enter(|infcx| {
            // Clone mir so we can mutate it without disturbing the rest of the compiler
            let mut renumbered_mir = mir.clone();
            let mut visitor = NLLVisitor::new(infcx);
            visitor.visit_mir(&mut renumbered_mir);
            let _results = visitor.into_results();
        })
    }
}

#[derive(Clone, Debug, Default, PartialEq, Eq)]
struct Region {
    points: FxHashSet<Location>,
}
<commit_msg>Convert regions to IndexVec<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc::ty::TypeFoldable;
use rustc::ty::subst::{Kind, Substs};
use rustc::ty::{Ty, TyCtxt, ClosureSubsts, RegionVid, RegionKind};
use rustc::mir::{Mir, Location, Rvalue, BasicBlock, Statement, StatementKind};
use rustc::mir::visit::{MutVisitor, Lookup};
use rustc::mir::transform::{MirPass, MirSource};
use rustc::infer::{self, InferCtxt};
use rustc::util::nodemap::FxHashSet;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use syntax_pos::DUMMY_SP;
use std::collections::HashMap;

#[allow(dead_code)]
struct NLLVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
    lookup_map: HashMap<RegionVid, Lookup>,
    regions: IndexVec<RegionIndex, Region>,
    infcx: InferCtxt<'a, 'gcx, 'tcx>,
}

impl<'a, 'gcx, 'tcx> NLLVisitor<'a, 'gcx, 'tcx> {
    pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self {
        NLLVisitor {
            infcx,
            lookup_map: HashMap::new(),
            regions: IndexVec::new(),
        }
    }

    pub fn into_results(self) -> HashMap<RegionVid, Lookup> {
        self.lookup_map
    }

    fn renumber_regions<T>(&mut self, value: &T) -> T where T: TypeFoldable<'tcx> {
        self.infcx.tcx.fold_regions(value, &mut false, |_region, _depth| {
            self.regions.push(Region::default());
            self.infcx.next_region_var(infer::MiscVariable(DUMMY_SP))
        })
    }

    fn store_region(&mut self, region: &RegionKind, lookup: Lookup) {
        if let RegionKind::ReVar(rid) = *region {
            self.lookup_map.entry(rid).or_insert(lookup);
        }
    }

    fn store_ty_regions(&mut self, ty: &Ty<'tcx>, lookup: Lookup) {
        for region in ty.regions() {
            self.store_region(region, lookup);
        }
    }

    fn store_kind_regions(&mut self, kind: &'tcx Kind, lookup: Lookup) {
        if let Some(ty) = kind.as_type() {
            self.store_ty_regions(&ty, lookup);
        } else if let Some(region) = kind.as_region() {
            self.store_region(region, lookup);
        }
    }
}

impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
    fn visit_ty(&mut self, ty: &mut Ty<'tcx>, lookup: Lookup) {
        let old_ty = *ty;
        *ty = self.renumber_regions(&old_ty);
        self.store_ty_regions(ty, lookup);
    }

    fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>, location: Location) {
        *substs = self.renumber_regions(&{*substs});
        let lookup = Lookup::Loc(location);
        for kind in *substs {
            self.store_kind_regions(kind, lookup);
        }
    }

    fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) {
        match *rvalue {
            Rvalue::Ref(ref mut r, _, _) => {
                let old_r = *r;
                *r = self.renumber_regions(&old_r);
                let lookup = Lookup::Loc(location);
                self.store_region(r, lookup);
            }
            Rvalue::Use(..) |
            Rvalue::Repeat(..) |
            Rvalue::Len(..) |
            Rvalue::Cast(..) |
            Rvalue::BinaryOp(..) |
            Rvalue::CheckedBinaryOp(..) |
            Rvalue::UnaryOp(..) |
            Rvalue::Discriminant(..) |
            Rvalue::NullaryOp(..) |
            Rvalue::Aggregate(..) => {
                // These variants don't contain regions.
            }
        }
        self.super_rvalue(rvalue, location);
    }

    fn visit_closure_substs(&mut self,
                            substs: &mut ClosureSubsts<'tcx>,
                            location: Location) {
        *substs = self.renumber_regions(substs);
        let lookup = Lookup::Loc(location);
        for kind in substs.substs {
            self.store_kind_regions(kind, lookup);
        }
    }

    fn visit_statement(&mut self,
                       block: BasicBlock,
                       statement: &mut Statement<'tcx>,
                       location: Location) {
        if let StatementKind::EndRegion(_) = statement.kind {
            statement.kind = StatementKind::Nop;
        }
        self.super_statement(block, statement, location);
    }
}

// MIR Pass for non-lexical lifetimes
pub struct NLL;

impl MirPass for NLL {
    fn run_pass<'a, 'tcx>(&self,
                          tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          _: MirSource,
                          mir: &mut Mir<'tcx>) {
        if !tcx.sess.opts.debugging_opts.nll {
            return;
        }

        tcx.infer_ctxt().enter(|infcx| {
            // Clone mir so we can mutate it without disturbing the rest of the compiler
            let mut renumbered_mir = mir.clone();
            let mut visitor = NLLVisitor::new(infcx);
            visitor.visit_mir(&mut renumbered_mir);
            let _results = visitor.into_results();
        })
    }
}

#[derive(Clone, Debug, Default, PartialEq, Eq)]
struct Region {
    points: FxHashSet<Location>,
}

#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub struct RegionIndex(pub u32);

impl Idx for RegionIndex {
    #[inline]
    fn new(idx: usize) -> Self {
        assert!(idx <= ::std::u32::MAX as usize);
        RegionIndex(idx as u32)
    }

    #[inline]
    fn index(self) -> usize {
        self.0 as usize
    }
}
<|endoftext|>


<commit_before><commit_msg>Review planet uniform synchronisation<commit_after><|endoftext|>


<commit_before>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

use std::ascii::AsciiExt;
use std::io::{BufferedReader, File};
use regex::Regex;

pub struct ExpectedError {
    pub line: uint,
    pub kind: String,
    pub msg: String,
}

pub static EXPECTED_PATTERN : &'static str = r"//~(?P<adjusts>\^*)\s*(?P<kind>\S*)\s*(?P<msg>.*)";

// Load any test directives embedded in the file
pub fn load_errors(re: &Regex, testfile: &Path) -> Vec<ExpectedError> {
    let mut rdr = BufferedReader::new(File::open(testfile).unwrap());

    rdr.lines().enumerate().filter_map(|(line_no, ln)| {
        parse_expected(line_no + 1, ln.unwrap().as_slice(), re)
    }).collect()
}

fn parse_expected(line_num: uint, line: &str, re: &Regex) -> Option<ExpectedError> {
    re.captures(line).and_then(|caps| {
        let adjusts = caps.name("adjusts").len();
        let kind = caps.name("kind").to_ascii_lower();
        let msg = caps.name("msg").trim().to_string();

        debug!("line={} kind={} msg={}", line_num, kind, msg);
        Some(ExpectedError {
            line: line_num - adjusts,
            kind: kind,
            msg: msg,
        })
    })
}
<commit_msg>compiletest: extend syntax with support for choosing same line as previous line.<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.
use self::WhichLine::*;

use std::ascii::AsciiExt;
use std::io::{BufferedReader, File};
use regex::Regex;

pub struct ExpectedError {
    pub line: uint,
    pub kind: String,
    pub msg: String,
}

/// Looks for either "//~| KIND MESSAGE" or "//~^^... KIND MESSAGE"
/// The former is a "follow" that inherits its target from the preceding line;
/// the latter is an "adjusts" that goes that many lines up.
///
/// Goal is to enable tests both like: //~^^^ ERROR go up three
/// and also //~^ ERROR message one for the preceding line, and
///          //~| ERROR message two for that same line.

pub static EXPECTED_PATTERN : &'static str =
    r"//~(?P<follow>\|)?(?P<adjusts>\^*)\s*(?P<kind>\S*)\s*(?P<msg>.*)";

#[deriving(PartialEq, Show)]
enum WhichLine { ThisLine, FollowPrevious(uint), AdjustBackward(uint) }

// Load any test directives embedded in the file
pub fn load_errors(re: &Regex, testfile: &Path) -> Vec<ExpectedError> {
    let mut rdr = BufferedReader::new(File::open(testfile).unwrap());

    // `last_nonfollow_error` tracks the most recently seen
    // line with an error template that did not use the
    // follow-syntax, "//~| ...".
    //
    // (pnkfelix could not find an easy way to compose Iterator::scan
    // and Iterator::filter_map to pass along this information into
    // `parse_expected`. So instead I am storing that state here and
    // updating it in the map callback below.)
    let mut last_nonfollow_error = None;

    rdr.lines().enumerate().filter_map(|(line_no, ln)| {
        parse_expected(last_nonfollow_error,
                       line_no + 1,
                       ln.unwrap().as_slice(), re)
            .map(|(which, error)| {
                match which {
                    FollowPrevious(_) => {}
                    _ => last_nonfollow_error = Some(error.line),
                }
                error
            })
    }).collect()
}

fn parse_expected(last_nonfollow_error: Option<uint>,
                  line_num: uint,
                  line: &str,
                  re: &Regex) -> Option<(WhichLine, ExpectedError)> {
    re.captures(line).and_then(|caps| {
        let adjusts = caps.name("adjusts").len();
        let kind = caps.name("kind").to_ascii_lower();
        let msg = caps.name("msg").trim().to_string();
        let follow = caps.name("follow").len() > 0;

        let (which, line) = if follow {
            assert!(adjusts == 0, "use either //~| or //~^, not both.");
            let line = last_nonfollow_error.unwrap_or_else(|| {
                panic!("encountered //~| without preceding //~^ line.")
            });
            (FollowPrevious(line), line)
        } else {
            let which =
                if adjusts > 0 { AdjustBackward(adjusts) } else { ThisLine };
            let line = line_num - adjusts;
            (which, line)
        };

        debug!("line={} which={} kind={} msg={}", line_num, which, kind, msg);
        Some((which, ExpectedError { line: line,
                                     kind: kind,
                                     msg: msg, }))
    })
}
<|endoftext|>


<commit_before><commit_msg>impl Stream wrapping<commit_after>use std::io::{ self, Initializer };
use std::os::unix::io::{ AsRawFd, RawFd };
use bytes::{ Buf, BufMut };
use rustls::ServerSession;
use tokio::prelude::*;
use tokio_rustls::{ TlsAcceptor, TlsStream };
use tokio_rusktls::KtlsStream;

pub enum Stream<IO> {
    Socket(IO),
    Tls(TlsStream<IO, ServerSession>),
    Ktls(KtlsStream<IO>)
}

pub enum InnerAccept<IO, Fut> {
    Socket(Option<IO>),
    Fut(Fut),
}

impl<IO> Stream<IO>
where IO: AsyncRead + AsyncWrite + AsRawFd + 'static
{
    pub fn new(io: IO, accept: Option<TlsAcceptor>)
        -> InnerAccept<IO, impl Future<Item=Stream<IO>, Error=io::Error>>
    {
        if let Some(acceptor) = accept {
            let fut = acceptor.accept(io)
                .and_then(|stream| {
                    let (io, session) = stream.into_inner();
                    KtlsStream::new(io, &session)
                        .map(Stream::Ktls)
                        .or_else(|err| {
                            eprintln!("warn: {:?}", err.error);

                            let stream = TlsStream::from((err.inner, session));
                            Ok(Stream::Tls(stream))
                        })
                });

            InnerAccept::Fut(fut)
        } else {
            InnerAccept::Socket(Some(io))
        }
    }
}

impl<IO, Fut> Future for InnerAccept<IO, Fut>
where Fut: Future<Item=Stream<IO>, Error=io::Error>
{
    type Item = Fut::Item;
    type Error = Fut::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        match self {
            InnerAccept::Socket(io) => {
                let io = io.take().unwrap();
                Ok(Async::Ready(Stream::Socket(io)))
            },
            InnerAccept::Fut(fut) => fut.poll()
        }
    }
}

impl<IO> io::Read for Stream<IO>
where IO: AsyncRead + AsyncWrite + AsRawFd
{
    unsafe fn initializer(&self) -> Initializer {
        match self {
            Stream::Socket(io) => io.initializer(),
            Stream::Tls(io) => io.initializer(),
            Stream::Ktls(io) => io.initializer()
        }
    }

    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match self {
            Stream::Socket(io) => io.read(buf),
            Stream::Tls(io) => io.read(buf),
            Stream::Ktls(io) => io.read(buf)
        }
    }
}

impl<IO> io::Write for Stream<IO>
where IO: AsyncRead + AsyncWrite + AsRawFd
{
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match self {
            Stream::Socket(io) => io.write(buf),
            Stream::Tls(io) => io.write(buf),
            Stream::Ktls(io) => io.write(buf)
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        match self {
            Stream::Socket(io) => io.flush(),
            Stream::Tls(io) => io.flush(),
            Stream::Ktls(io) => io.flush()
        }
    }
}

impl<IO> AsyncRead for Stream<IO>
where IO: AsyncRead + AsyncWrite + AsRawFd
{
    unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
        match self {
            Stream::Socket(io) => io.prepare_uninitialized_buffer(buf),
            Stream::Tls(io) => io.prepare_uninitialized_buffer(buf),
            Stream::Ktls(io) => io.prepare_uninitialized_buffer(buf)
        }
    }

    fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
        match self {
            Stream::Socket(io) => io.read_buf(buf),
            Stream::Tls(io) => io.read_buf(buf),
            Stream::Ktls(io) => io.read_buf(buf)
        }
    }
}

impl<IO> AsyncWrite for Stream<IO>
where IO: AsyncRead + AsyncWrite + AsRawFd
{
    fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
        match self {
            Stream::Socket(io) => io.write_buf(buf),
            Stream::Tls(io) => io.write_buf(buf),
            Stream::Ktls(io) => io.write_buf(buf)
        }
    }

    fn shutdown(&mut self) -> Poll<(), io::Error> {
        match self {
            Stream::Socket(io) => io.shutdown(),
            Stream::Tls(io) => io.shutdown(),
            Stream::Ktls(io) => io.shutdown()
        }
    }
}

impl<IO: AsRawFd> AsRawFd for Stream<IO> {
    fn as_raw_fd(&self) -> RawFd {
        match self {
            Stream::Socket(io) => io.as_raw_fd(),
            Stream::Tls(io) => {
                let (io, _) = io.get_ref();
                io.as_raw_fd()
            },
            Stream::Ktls(io) => io.as_raw_fd()
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix up paths in ty::fun<commit_after><|endoftext|>


<commit_before><commit_msg>option type sample<commit_after><|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::path::PathBuf;
use std::result::Result as RResult;
use std::ops::Deref;

use toml::Value;
use clap::App;

use error::RuntimeErrorKind as REK;
use libimagerror::into::IntoError;

generate_error_module!(
    generate_error_types!(ConfigError, ConfigErrorKind,
        TOMLParserError => "TOML Parsing error",
        NoConfigFileFound   => "No config file found",

        ConfigOverrideError => "Config override error",
        ConfigOverrideKeyNotAvailable => "Key not available",
        ConfigOverrideTypeNotMatching => "Configuration Type not matching"

    );
);

pub use self::error::{ConfigError, ConfigErrorKind};

/// Result type of this module. Either `T` or `ConfigError`
pub type Result<T> = RResult<T, ConfigError>;

/// `Configuration` object
///
/// Holds all config variables which are globally available plus the configuration object from the
/// config parser, which can be accessed.
#[derive(Debug)]
pub struct Configuration {

    /// The plain configuration object for direct access if necessary
    config: Value,

    /// The verbosity the program should run with
    verbosity: bool,

    /// The editor which should be used
    editor: Option<String>,

    ///The options the editor should get when opening some file
    editor_opts: String,
}

impl Configuration {

    /// Get a new configuration object.
    ///
    /// The passed runtimepath is used for searching the configuration file, whereas several file
    /// names are tested. If that does not work, the home directory and the XDG basedir are tested
    /// with all variants.
    ///
    /// If that doesn't work either, an error is returned.
    pub fn new(toml_config: Value) -> Configuration {
        let verbosity   = get_verbosity(&toml_config);
        let editor      = get_editor(&toml_config);
        let editor_opts = get_editor_opts(&toml_config);

        debug!("Building configuration");
        debug!("  - verbosity  : {:?}", verbosity);
        debug!("  - editor     : {:?}", editor);
        debug!("  - editor-opts: {}", editor_opts);

        Configuration {
            config: toml_config,
            verbosity: verbosity,
            editor: editor,
            editor_opts: editor_opts,
        }
    }

    /// Get the Editor setting from the configuration
    pub fn editor(&self) -> Option<&String> {
        self.editor.as_ref()
    }

    /// Get the underlying configuration TOML object
    pub fn config(&self) -> &Value {
        &self.config
    }

    /// Get the configuration of the store, if any.
    pub fn store_config(&self) -> Option<&Value> {
        match self.config {
            Value::Table(ref tabl) => tabl.get("store"),
            _ => None,
        }
    }

    /// Override the configuration.
    /// The `v` parameter is expected to contain 'key=value' pairs where the key is a path in the
    /// TOML tree, the value to be an appropriate value.
    ///
    /// The override fails if the configuration which is about to be overridden does not exist or
    /// the `value` part cannot be converted to the type of the configuration value.
    ///
    /// If `v` is empty, this is considered to be a successful `override_config()` call.
    pub fn override_config(&mut self, v: Vec<String>) -> Result<()> {
        use libimagutil::key_value_split::*;
        use libimagutil::iter::*;
        use self::error::ConfigErrorKind as CEK;
        use self::error::MapErrInto;
        use libimagerror::into::IntoError;
        use libimagstore::toml_ext::TomlValueExt;

        v.into_iter()
            .map(|s| { debug!("Trying to process '{}'", s); s })
            .filter_map(|s| match s.into_kv() {
                Some(kv) => Some(kv.into()),
                None => {
                    warn!("Could split at '=' - will be ignore override");
                    None
                }
            })
            .map(|(k, v)| self
                 .config
                 .read(&k[..])
                 .map_err_into(CEK::TOMLParserError)
                 .map(|toml| match toml {
                    Some(value) => match into_value(value, v) {
                        Some(v) => {
                            info!("Successfully overridden: {} = {}", k, v);
                            Ok(v)
                        },
                        None => Err(CEK::ConfigOverrideTypeNotMatching.into_error()),
                    },
                    None => Err(CEK::ConfigOverrideKeyNotAvailable.into_error()),
                })
            )
            .fold_result(|i| i)
            .map_err(Box::new)
            .map_err(|e| CEK::ConfigOverrideError.into_error_with_cause(e))
    }
}

/// Tries to convert the String `s` into the same type as `value`.
///
/// Returns None if string cannot be converted.
///
/// Arrays and Tables are not supported and will yield `None`.
fn into_value(value: Value, s: String) -> Option<Value> {
    use std::str::FromStr;

    match value {
        Value::String(_)  => Some(Value::String(s)),
        Value::Integer(_) => FromStr::from_str(&s[..]).ok().map(Value::Integer),
        Value::Float(_)   => FromStr::from_str(&s[..]).ok().map(Value::Float),
        Value::Boolean(_) => {
            if s == "true" { Some(Value::Boolean(true)) }
            else if s == "false" { Some(Value::Boolean(false)) }
            else { None }
        }
        Value::Datetime(_) => Value::try_from(s).ok(),
        _ => None,
    }
}

impl Deref for Configuration {
    type Target = Value;

    fn deref(&self) -> &Value {
        &self.config
    }

}

fn get_verbosity(v: &Value) -> bool {
    match *v {
        Value::Table(ref t) => t.get("verbose")
                .map_or(false, |v| is_match!(v, &Value::Boolean(true))),
        _ => false,
    }
}

fn get_editor(v: &Value) -> Option<String> {
    match *v {
        Value::Table(ref t) => t.get("editor")
                .and_then(|v| match *v { Value::String(ref s) => Some(s.clone()), _ => None, }),
        _ => None,
    }
}

fn get_editor_opts(v: &Value) -> String {
    match *v {
        Value::Table(ref t) => t.get("editor-opts")
                .and_then(|v| match *v { Value::String(ref s) => Some(s.clone()), _ => None, })
                .unwrap_or_default(),
        _ => String::new(),
    }
}

/// Helper to fetch the config file
///
/// Tests several variants for the config file path and uses the first one which works.
fn fetch_config(rtp: &PathBuf) -> Result<Value> {
    use std::env;
    use std::fs::File;
    use std::io::Read;

    use xdg_basedir;
    use itertools::Itertools;

    use libimagutil::variants::generate_variants as gen_vars;
    use self::error::MapErrInto;

    let variants = vec!["config", "config.toml", "imagrc", "imagrc.toml"];
    let modifier = |base: &PathBuf, v: &'static str| {
        let mut base = base.clone();
        base.push(String::from(v));
        base
    };

    vec![
        vec![rtp.clone()],
        gen_vars(rtp.clone(), variants.clone(), &modifier),

        env::var("HOME").map(|home| gen_vars(PathBuf::from(home), variants.clone(), &modifier))
                        .unwrap_or(vec![]),

        xdg_basedir::get_data_home().map(|data_dir| gen_vars(data_dir, variants.clone(), &modifier))
                                    .unwrap_or(vec![]),
    ].iter()
        .flatten()
        .filter(|path| path.exists() && path.is_file())
        .filter_map(|path| if path.exists() && path.is_file() {
            debug!("Reading {:?}", path);
            let content = {
                let mut s = String::new();
                let f = File::open(path);
                if f.is_err() {
                    return None
                }
                let mut f = f.unwrap();
                f.read_to_string(&mut s).ok();
                s
            };

            trace!("Contents of config file: \n---\n{}\n---", content);

            let toml = ::toml::de::from_str(&content[..])
                .map_err_into(ConfigErrorKind::TOMLParserError)
                .map_err(Box::new)
                .map_err(|e| REK::Instantiate.into_error_with_cause(e));

            Some(toml)
        } else {
            None
        })
        .filter(|loaded| loaded.is_ok())
        .map(|inner| Value::Table(inner.unwrap()))
        .nth(0)
        .ok_or(ConfigErrorKind::NoConfigFileFound.into())
}

pub trait GetConfiguration {
    fn get_configuration(rtp: &PathBuf) -> Result<Configuration> {
        fetch_config(rtp).map(Configuration::new)
    }
}

impl<'a> GetConfiguration for App<'a, 'a> {}

pub trait InternalConfiguration {
    fn enable_hooks() -> bool {
        true
    }

    fn enable_logging() -> bool {
        true
    }
}

impl<'a> InternalConfiguration for App<'a, 'a> {}
<commit_msg>Move `fetch_config` into `GetConfiguration` trait<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::path::PathBuf;
use std::result::Result as RResult;
use std::ops::Deref;

use toml::Value;
use clap::App;

use error::RuntimeErrorKind as REK;
use libimagerror::into::IntoError;

generate_error_module!(
    generate_error_types!(ConfigError, ConfigErrorKind,
        TOMLParserError => "TOML Parsing error",
        NoConfigFileFound   => "No config file found",

        ConfigOverrideError => "Config override error",
        ConfigOverrideKeyNotAvailable => "Key not available",
        ConfigOverrideTypeNotMatching => "Configuration Type not matching"

    );
);

pub use self::error::{ConfigError, ConfigErrorKind};

/// Result type of this module. Either `T` or `ConfigError`
pub type Result<T> = RResult<T, ConfigError>;

/// `Configuration` object
///
/// Holds all config variables which are globally available plus the configuration object from the
/// config parser, which can be accessed.
#[derive(Debug)]
pub struct Configuration {

    /// The plain configuration object for direct access if necessary
    config: Value,

    /// The verbosity the program should run with
    verbosity: bool,

    /// The editor which should be used
    editor: Option<String>,

    ///The options the editor should get when opening some file
    editor_opts: String,
}

impl Configuration {

    /// Get a new configuration object.
    ///
    /// The passed runtimepath is used for searching the configuration file, whereas several file
    /// names are tested. If that does not work, the home directory and the XDG basedir are tested
    /// with all variants.
    ///
    /// If that doesn't work either, an error is returned.
    pub fn new(toml_config: Value) -> Configuration {
        let verbosity   = get_verbosity(&toml_config);
        let editor      = get_editor(&toml_config);
        let editor_opts = get_editor_opts(&toml_config);

        debug!("Building configuration");
        debug!("  - verbosity  : {:?}", verbosity);
        debug!("  - editor     : {:?}", editor);
        debug!("  - editor-opts: {}", editor_opts);

        Configuration {
            config: toml_config,
            verbosity: verbosity,
            editor: editor,
            editor_opts: editor_opts,
        }
    }

    /// Get the Editor setting from the configuration
    pub fn editor(&self) -> Option<&String> {
        self.editor.as_ref()
    }

    /// Get the underlying configuration TOML object
    pub fn config(&self) -> &Value {
        &self.config
    }

    /// Get the configuration of the store, if any.
    pub fn store_config(&self) -> Option<&Value> {
        match self.config {
            Value::Table(ref tabl) => tabl.get("store"),
            _ => None,
        }
    }

    /// Override the configuration.
    /// The `v` parameter is expected to contain 'key=value' pairs where the key is a path in the
    /// TOML tree, the value to be an appropriate value.
    ///
    /// The override fails if the configuration which is about to be overridden does not exist or
    /// the `value` part cannot be converted to the type of the configuration value.
    ///
    /// If `v` is empty, this is considered to be a successful `override_config()` call.
    pub fn override_config(&mut self, v: Vec<String>) -> Result<()> {
        use libimagutil::key_value_split::*;
        use libimagutil::iter::*;
        use self::error::ConfigErrorKind as CEK;
        use self::error::MapErrInto;
        use libimagerror::into::IntoError;
        use libimagstore::toml_ext::TomlValueExt;

        v.into_iter()
            .map(|s| { debug!("Trying to process '{}'", s); s })
            .filter_map(|s| match s.into_kv() {
                Some(kv) => Some(kv.into()),
                None => {
                    warn!("Could split at '=' - will be ignore override");
                    None
                }
            })
            .map(|(k, v)| self
                 .config
                 .read(&k[..])
                 .map_err_into(CEK::TOMLParserError)
                 .map(|toml| match toml {
                    Some(value) => match into_value(value, v) {
                        Some(v) => {
                            info!("Successfully overridden: {} = {}", k, v);
                            Ok(v)
                        },
                        None => Err(CEK::ConfigOverrideTypeNotMatching.into_error()),
                    },
                    None => Err(CEK::ConfigOverrideKeyNotAvailable.into_error()),
                })
            )
            .fold_result(|i| i)
            .map_err(Box::new)
            .map_err(|e| CEK::ConfigOverrideError.into_error_with_cause(e))
    }
}

/// Tries to convert the String `s` into the same type as `value`.
///
/// Returns None if string cannot be converted.
///
/// Arrays and Tables are not supported and will yield `None`.
fn into_value(value: Value, s: String) -> Option<Value> {
    use std::str::FromStr;

    match value {
        Value::String(_)  => Some(Value::String(s)),
        Value::Integer(_) => FromStr::from_str(&s[..]).ok().map(Value::Integer),
        Value::Float(_)   => FromStr::from_str(&s[..]).ok().map(Value::Float),
        Value::Boolean(_) => {
            if s == "true" { Some(Value::Boolean(true)) }
            else if s == "false" { Some(Value::Boolean(false)) }
            else { None }
        }
        Value::Datetime(_) => Value::try_from(s).ok(),
        _ => None,
    }
}

impl Deref for Configuration {
    type Target = Value;

    fn deref(&self) -> &Value {
        &self.config
    }

}

fn get_verbosity(v: &Value) -> bool {
    match *v {
        Value::Table(ref t) => t.get("verbose")
                .map_or(false, |v| is_match!(v, &Value::Boolean(true))),
        _ => false,
    }
}

fn get_editor(v: &Value) -> Option<String> {
    match *v {
        Value::Table(ref t) => t.get("editor")
                .and_then(|v| match *v { Value::String(ref s) => Some(s.clone()), _ => None, }),
        _ => None,
    }
}

fn get_editor_opts(v: &Value) -> String {
    match *v {
        Value::Table(ref t) => t.get("editor-opts")
                .and_then(|v| match *v { Value::String(ref s) => Some(s.clone()), _ => None, })
                .unwrap_or_default(),
        _ => String::new(),
    }
}

pub trait GetConfiguration {
    /// Helper to fetch the config file
    ///
    /// Default implementation tests several variants for the config file path and uses the first
    /// one which works.
    fn get_configuration(rtp: &PathBuf) -> Result<Configuration> {
        use std::env;
        use std::fs::File;
        use std::io::Read;
        use std::io::Write;
        use std::io::stderr;

        use xdg_basedir;
        use itertools::Itertools;

        use libimagutil::variants::generate_variants as gen_vars;
        use libimagerror::trace::trace_error;

        let variants = vec!["config", "config.toml", "imagrc", "imagrc.toml"];
        let modifier = |base: &PathBuf, v: &'static str| {
            let mut base = base.clone();
            base.push(String::from(v));
            base
        };

        vec![
            vec![rtp.clone()],
            gen_vars(rtp.clone(), variants.clone(), &modifier),

            env::var("HOME").map(|home| gen_vars(PathBuf::from(home), variants.clone(), &modifier))
                            .unwrap_or(vec![]),

            xdg_basedir::get_data_home().map(|data_dir| gen_vars(data_dir, variants.clone(), &modifier))
                                        .unwrap_or(vec![]),
        ].iter()
            .flatten()
            .filter(|path| path.exists() && path.is_file())
            .map(|path| {
                let content = {
                    let mut s = String::new();
                    let f = File::open(path);
                    if f.is_err() {
                        return None
                    }
                    let mut f = f.unwrap();
                    f.read_to_string(&mut s).ok();
                    s
                };

                match ::toml::de::from_str(&content[..]) {
                    Ok(res) => res,
                    Err(e) => {
                        write!(stderr(), "Config file parser error:").ok();
                        trace_error(&e);
                        None
                    }
                }
            })
            .filter(|loaded| loaded.is_some())
            .nth(0)
            .map(|inner| Value::Table(inner.unwrap()))
            .ok_or(ConfigErrorKind::NoConfigFileFound.into())
            .map(Configuration::new)
    }
}

impl<'a> GetConfiguration for App<'a, 'a> {}

pub trait InternalConfiguration {
    fn enable_hooks() -> bool {
        true
    }

    fn enable_logging() -> bool {
        true
    }
}

impl<'a> InternalConfiguration for App<'a, 'a> {}
<|endoftext|>


<commit_before><commit_msg>tests: Add sub_command_negate_requred false-negative test<commit_after><|endoftext|>


<commit_before><commit_msg>Fix imports for new viewer interface<commit_after><|endoftext|>


<commit_before><commit_msg>todo count button clicked<commit_after><|endoftext|>


<commit_before>// Extracting metadata from crate files

import driver::session;
import syntax::ast;
import lib::llvm::False;
import lib::llvm::llvm;
import lib::llvm::mk_object_file;
import lib::llvm::mk_section_iter;
import front::attr;
import middle::resolve;
import syntax::walk;
import syntax::codemap::span;
import back::x86;
import util::common;
import std::ivec;
import std::str;
import std::vec;
import std::ebml;
import std::fs;
import std::io;
import std::option;
import std::option::none;
import std::option::some;
import std::map::hashmap;
import syntax::print::pprust;
import common::*;

export read_crates;
export list_file_metadata;

fn metadata_matches(&vec[u8] crate_data,
                    &(@ast::meta_item)[] metas) -> bool {
    auto attrs = decoder::get_crate_attributes(crate_data);
    auto linkage_metas = attr::find_linkage_metas(attrs);

    log #fmt("matching %u metadata requirements against %u items",
             ivec::len(metas), ivec::len(linkage_metas));

    for (@ast::meta_item needed in metas) {
        if (!attr::contains(linkage_metas, needed)) {
            log #fmt("missing %s", pprust::meta_item_to_str(*needed));
            ret false;
        }
    }
    ret true;
}

fn default_native_lib_naming(session::session sess) ->
   rec(str prefix, str suffix) {
    alt (sess.get_targ_cfg().os) {
        case (session::os_win32) { ret rec(prefix="", suffix=".dll"); }
        case (session::os_macos) { ret rec(prefix="lib", suffix=".dylib"); }
        case (session::os_linux) { ret rec(prefix="lib", suffix=".so"); }
    }
}

fn find_library_crate(&session::session sess, &ast::ident ident,
                      &(@ast::meta_item)[] metas,
                      &vec[str] library_search_paths) ->
   option::t[tup(str, vec[u8])] {

    attr::require_unique_names(sess, metas);

    auto crate_name = {
        auto name_items = attr::find_meta_items_by_name(metas, "name");
        alt (ivec::last(name_items)) {
            case (some(?i)) {
                alt (attr::get_meta_item_value_str(i)) {
                    case (some(?n)) { n }
                    case (_) {
                        // FIXME: Probably want a warning here since the user
                        // is using the wrong type of meta item
                        ident
                    }
                }
            }
            case (none) { ident }
        }
    };

    auto nn = default_native_lib_naming(sess);
    let str prefix = nn.prefix + crate_name;
    // FIXME: we could probably use a 'glob' function in std::fs but it will
    // be much easier to write once the unsafe module knows more about FFI
    // tricks. Currently the glob(3) interface is a bit more than we can
    // stomach from here, and writing a C++ wrapper is more work than just
    // manually filtering fs::list_dir here.

    for (str library_search_path in library_search_paths) {
        log #fmt("searching %s", library_search_path);
        for (str path in fs::list_dir(library_search_path)) {
            log #fmt("searching %s", path);
            let str f = fs::basename(path);
            if (!(str::starts_with(f, prefix) &&
                      str::ends_with(f, nn.suffix))) {
                log #fmt("skipping %s, doesn't look like %s*%s", path, prefix,
                         nn.suffix);
                cont;
            }
            alt (get_metadata_section(path)) {
                case (option::some(?cvec)) {
                    if (!metadata_matches(cvec, metas)) {
                        log #fmt("skipping %s, metadata doesn't match", path);
                        cont;
                    }
                    log #fmt("found %s with matching metadata", path);
                    ret some(tup(path, cvec));
                }
                case (_) { }
            }
        }
    }
    ret none;
}

fn get_metadata_section(str filename) -> option::t[vec[u8]] {
    auto b = str::buf(filename);
    auto mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(b);
    if (mb as int == 0) { ret option::none[vec[u8]]; }
    auto of = mk_object_file(mb);
    auto si = mk_section_iter(of.llof);
    while (llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False) {
        auto name_buf = llvm::LLVMGetSectionName(si.llsi);
        auto name = str::str_from_cstr(name_buf);
        if (str::eq(name, x86::get_meta_sect_name())) {
            auto cbuf = llvm::LLVMGetSectionContents(si.llsi);
            auto csz = llvm::LLVMGetSectionSize(si.llsi);
            auto cvbuf = cbuf as vec::vbuf;
            ret option::some[vec[u8]](vec::vec_from_vbuf[u8](cvbuf, csz));
        }
        llvm::LLVMMoveToNextSection(si.llsi);
    }
    ret option::none[vec[u8]];
}

fn load_library_crate(&session::session sess, span span, int cnum,
                      &ast::ident ident, &(@ast::meta_item)[] metas,
                      &vec[str] library_search_paths) {
    alt (find_library_crate(sess, ident, metas, library_search_paths)) {
        case (some(?t)) {
            auto cstore = sess.get_cstore();
            cstore::set_crate_data(cstore, cnum,
                                   rec(name=ident, data=t._1));
            cstore::add_used_crate_file(cstore, t._0);
            ret;
        }
        case (_) { }
    }
    sess.span_fatal(span, #fmt("can't find crate for '%s'", ident));
}

type env =
    @rec(session::session sess,
         resolve::crate_map crate_map,
         @hashmap[str, int] crate_cache,
         vec[str] library_search_paths,
         mutable int next_crate_num);

fn visit_view_item(env e, &@ast::view_item i) {
    alt (i.node) {
        case (ast::view_item_use(?ident, ?meta_items, ?id)) {
            auto cnum;
            if (!e.crate_cache.contains_key(ident)) {
                cnum = e.next_crate_num;
                load_library_crate(e.sess, i.span, cnum, ident,
                                   meta_items, e.library_search_paths);
                e.crate_cache.insert(ident, e.next_crate_num);
                e.next_crate_num += 1;
            } else { cnum = e.crate_cache.get(ident); }
            e.crate_map.insert(id, cnum);
        }
        case (_) { }
    }
}

fn visit_item(env e, &@ast::item i) {
    alt (i.node) {
        case (ast::item_native_mod(?m)) {
            if (m.abi != ast::native_abi_rust &&
                m.abi != ast::native_abi_cdecl) {
                ret;
            }
            auto cstore = e.sess.get_cstore();
            if (!cstore::add_used_library(cstore, m.native_name)) {
                ret;
            }
            for (ast::attribute a in
                     attr::find_attrs_by_name(i.attrs, "link_args")) {
                alt (attr::get_meta_item_value_str(attr::attr_meta(a))) {
                    case (some(?linkarg)) {
                        cstore::add_used_link_args(cstore, linkarg);
                    }
                    case (none) { /* fallthrough */ }
                }
            }
        }
        case (_) {
        }
    }
}

// Reads external crates referenced by "use" directives.
fn read_crates(session::session sess, resolve::crate_map crate_map,
               &ast::crate crate) {
    auto e =
        @rec(sess=sess,
             crate_map=crate_map,
             crate_cache=@std::map::new_str_hash[int](),
             library_search_paths=sess.get_opts().library_search_paths,
             mutable next_crate_num=1);
    auto v =
        rec(visit_view_item_pre=bind visit_view_item(e, _),
            visit_item_pre=bind visit_item(e, _)
            with walk::default_visitor());
    walk::walk_crate(v, crate);
}

fn list_file_metadata(str path, io::writer out) {
    alt (get_metadata_section(path)) {
        case (option::some(?bytes)) {
            decoder::list_crate_metadata(bytes, out);
        }
        case (option::none) {
            out.write_str("Could not find metadata in " + path + ".\n");
        }
    }
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>Comment creader<commit_after>// Extracting metadata from crate files

import driver::session;
import syntax::ast;
import lib::llvm::False;
import lib::llvm::llvm;
import lib::llvm::mk_object_file;
import lib::llvm::mk_section_iter;
import front::attr;
import middle::resolve;
import syntax::walk;
import syntax::codemap::span;
import back::x86;
import util::common;
import std::ivec;
import std::str;
import std::vec;
import std::ebml;
import std::fs;
import std::io;
import std::option;
import std::option::none;
import std::option::some;
import std::map::hashmap;
import syntax::print::pprust;
import common::*;

export read_crates;
export list_file_metadata;

// Traverses an AST, reading all the information about use'd crates and native
// libraries necessary for later resolving, typechecking, linking, etc.
fn read_crates(session::session sess, resolve::crate_map crate_map,
               &ast::crate crate) {
    auto e =
        @rec(sess=sess,
             crate_map=crate_map,
             crate_cache=@std::map::new_str_hash[int](),
             library_search_paths=sess.get_opts().library_search_paths,
             mutable next_crate_num=1);
    auto v =
        rec(visit_view_item_pre=bind visit_view_item(e, _),
            visit_item_pre=bind visit_item(e, _)
            with walk::default_visitor());
    walk::walk_crate(v, crate);
}

// A diagnostic function for dumping crate metadata to an output stream
fn list_file_metadata(str path, io::writer out) {
    alt (get_metadata_section(path)) {
        case (option::some(?bytes)) {
            decoder::list_crate_metadata(bytes, out);
        }
        case (option::none) {
            out.write_str("Could not find metadata in " + path + ".\n");
        }
    }
}

fn metadata_matches(&vec[u8] crate_data,
                    &(@ast::meta_item)[] metas) -> bool {
    auto attrs = decoder::get_crate_attributes(crate_data);
    auto linkage_metas = attr::find_linkage_metas(attrs);

    log #fmt("matching %u metadata requirements against %u items",
             ivec::len(metas), ivec::len(linkage_metas));

    for (@ast::meta_item needed in metas) {
        if (!attr::contains(linkage_metas, needed)) {
            log #fmt("missing %s", pprust::meta_item_to_str(*needed));
            ret false;
        }
    }
    ret true;
}

fn default_native_lib_naming(session::session sess) ->
   rec(str prefix, str suffix) {
    alt (sess.get_targ_cfg().os) {
        case (session::os_win32) { ret rec(prefix="", suffix=".dll"); }
        case (session::os_macos) { ret rec(prefix="lib", suffix=".dylib"); }
        case (session::os_linux) { ret rec(prefix="lib", suffix=".so"); }
    }
}

fn find_library_crate(&session::session sess, &ast::ident ident,
                      &(@ast::meta_item)[] metas,
                      &vec[str] library_search_paths) ->
   option::t[tup(str, vec[u8])] {

    attr::require_unique_names(sess, metas);

    auto crate_name = {
        auto name_items = attr::find_meta_items_by_name(metas, "name");
        alt (ivec::last(name_items)) {
            case (some(?i)) {
                alt (attr::get_meta_item_value_str(i)) {
                    case (some(?n)) { n }
                    case (_) {
                        // FIXME: Probably want a warning here since the user
                        // is using the wrong type of meta item
                        ident
                    }
                }
            }
            case (none) { ident }
        }
    };

    auto nn = default_native_lib_naming(sess);
    let str prefix = nn.prefix + crate_name;
    // FIXME: we could probably use a 'glob' function in std::fs but it will
    // be much easier to write once the unsafe module knows more about FFI
    // tricks. Currently the glob(3) interface is a bit more than we can
    // stomach from here, and writing a C++ wrapper is more work than just
    // manually filtering fs::list_dir here.

    for (str library_search_path in library_search_paths) {
        log #fmt("searching %s", library_search_path);
        for (str path in fs::list_dir(library_search_path)) {
            log #fmt("searching %s", path);
            let str f = fs::basename(path);
            if (!(str::starts_with(f, prefix) &&
                      str::ends_with(f, nn.suffix))) {
                log #fmt("skipping %s, doesn't look like %s*%s", path, prefix,
                         nn.suffix);
                cont;
            }
            alt (get_metadata_section(path)) {
                case (option::some(?cvec)) {
                    if (!metadata_matches(cvec, metas)) {
                        log #fmt("skipping %s, metadata doesn't match", path);
                        cont;
                    }
                    log #fmt("found %s with matching metadata", path);
                    ret some(tup(path, cvec));
                }
                case (_) { }
            }
        }
    }
    ret none;
}

fn get_metadata_section(str filename) -> option::t[vec[u8]] {
    auto b = str::buf(filename);
    auto mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(b);
    if (mb as int == 0) { ret option::none[vec[u8]]; }
    auto of = mk_object_file(mb);
    auto si = mk_section_iter(of.llof);
    while (llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False) {
        auto name_buf = llvm::LLVMGetSectionName(si.llsi);
        auto name = str::str_from_cstr(name_buf);
        if (str::eq(name, x86::get_meta_sect_name())) {
            auto cbuf = llvm::LLVMGetSectionContents(si.llsi);
            auto csz = llvm::LLVMGetSectionSize(si.llsi);
            auto cvbuf = cbuf as vec::vbuf;
            ret option::some[vec[u8]](vec::vec_from_vbuf[u8](cvbuf, csz));
        }
        llvm::LLVMMoveToNextSection(si.llsi);
    }
    ret option::none[vec[u8]];
}

fn load_library_crate(&session::session sess, span span, int cnum,
                      &ast::ident ident, &(@ast::meta_item)[] metas,
                      &vec[str] library_search_paths) {
    alt (find_library_crate(sess, ident, metas, library_search_paths)) {
        case (some(?t)) {
            auto cstore = sess.get_cstore();
            cstore::set_crate_data(cstore, cnum,
                                   rec(name=ident, data=t._1));
            cstore::add_used_crate_file(cstore, t._0);
            ret;
        }
        case (_) { }
    }
    sess.span_fatal(span, #fmt("can't find crate for '%s'", ident));
}

type env =
    @rec(session::session sess,
         resolve::crate_map crate_map,
         @hashmap[str, int] crate_cache,
         vec[str] library_search_paths,
         mutable int next_crate_num);

fn visit_view_item(env e, &@ast::view_item i) {
    alt (i.node) {
        case (ast::view_item_use(?ident, ?meta_items, ?id)) {
            auto cnum;
            if (!e.crate_cache.contains_key(ident)) {
                cnum = e.next_crate_num;
                load_library_crate(e.sess, i.span, cnum, ident,
                                   meta_items, e.library_search_paths);
                e.crate_cache.insert(ident, e.next_crate_num);
                e.next_crate_num += 1;
            } else { cnum = e.crate_cache.get(ident); }
            e.crate_map.insert(id, cnum);
        }
        case (_) { }
    }
}

fn visit_item(env e, &@ast::item i) {
    alt (i.node) {
        case (ast::item_native_mod(?m)) {
            if (m.abi != ast::native_abi_rust &&
                m.abi != ast::native_abi_cdecl) {
                ret;
            }
            auto cstore = e.sess.get_cstore();
            if (!cstore::add_used_library(cstore, m.native_name)) {
                ret;
            }
            for (ast::attribute a in
                     attr::find_attrs_by_name(i.attrs, "link_args")) {
                alt (attr::get_meta_item_value_str(attr::attr_meta(a))) {
                    case (some(?linkarg)) {
                        cstore::add_used_link_args(cstore, linkarg);
                    }
                    case (none) { /* fallthrough */ }
                }
            }
        }
        case (_) {
        }
    }
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


<commit_before><commit_msg>Replace call to retrieve_for_module() with entries()<commit_after><|endoftext|>


<commit_before><commit_msg>Add rust code for say<commit_after>const TEN: u64 = 10;
const HUNDRED: u64 = 100;
const THOUSAND: u64 = 1000;

fn ntable(number: u64) -> &'static str {
    match number {
        0 => "zero",
        1 => "one",
        2 => "two",
        3 => "three",
        4 => "four",
        5 => "five",
        6 => "six",
        7 => "seven",
        8 => "eight",
        9 => "nine",
        10 => "ten",
        11 => "eleven",
        12 => "twelve",
        13 => "thirteen",
        14 => "fourteen",
        15 => "fifteen",
        16 => "sixteen",
        17 => "seventeen",
        18 => "eighteen",
        19 => "nineteen",
        20 => "twenty",
        30 => "thirty",
        40 => "forty",
        50 => "fifty",
        60 => "sixty",
        70 => "seventy",
        80 => "eighty",
        90 => "ninety",
        _ => "",
    }
}

fn translate(number: u64) -> String {
    let mut result = String::new();

    let hundreds = number / HUNDRED;
    let tens = number % HUNDRED;

    if hundreds != 0 {
        result = ntable(hundreds).to_string() + " hundred";

        if tens == 0 {
            return result;
        } else {
            result += " ";
        }
    }

    let digit = tens % TEN;

    if tens <= 20 || digit == 0 {
        result += ntable(tens);
    } else {
        result += ntable(tens - digit);
        result += "-";
        result += ntable(digit);
    }

    result
}

static UINTS: [&str; 7] = [
    "",
    "thousand",
    "million",
    "billion",
    "trillion",
    "quadrillion",
    "quintillion",
];

pub fn encode(number: u64) -> String {
    if number < THOUSAND {
        return translate(number);
    }

    let mut f = number;
    let mut d = Vec::new();

    while f > 0 {
        let r = f % THOUSAND;

        d.push(r);

        f /= THOUSAND;
    }

    d.into_iter()
        .map(translate)
        .zip(UINTS.into_iter())
        .filter_map(|(v, u)| {
            if v == "zero" {
                return None;
            }

            if u.is_empty() {
                Some(v)
            } else {
                Some(v + " " + u)
            }
        })
        .rev()
        .collect::<Vec<_>>()
        .join(" ")
}
<|endoftext|>


<commit_before><commit_msg>small note about `drain` iterator method<commit_after>use std::iter::FromIterator;

fn main() {
    let mut outer = "Earth".to_string();
    let inner = String::from_iter(outer.drain(1..4));

    assert_eq!(outer, "Eh");
    assert_eq!(inner, "art");
}
<|endoftext|>


<commit_before><commit_msg>2019: Day 10, part 2.<commit_after>use std::collections::HashSet;
use std::convert::TryInto;
use std::io;
use std::io::Read;
use std::iter;

mod errors;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct Asteroid {
    y: i128,
    x: i128,
}

impl Asteroid {
    fn angle(&self, other: &Asteroid) -> f64 {
        let y: f64 = (other.y - self.y) as f64;
        let x: f64 = (other.x - self.x) as f64;
        modulus(
            y.atan2(x) + std::f64::consts::FRAC_PI_2,
            std::f64::consts::PI * 2.0,
        )
    }
}

struct Asteroids(HashSet<Asteroid>);

impl Asteroids {
    fn iter(&self) -> impl Iterator<Item = &Asteroid> {
        self.0.iter()
    }

    fn count_in_line_of_sight(&self, asteroid: &Asteroid) -> usize {
        self.iter()
            .filter(|other| asteroid != *other)
            .filter(|other| !self.blocked(asteroid, other))
            .count()
    }

    fn vaporize_from(&self, station: &Asteroid) -> Vec<Asteroid> {
        if self.0.is_empty() {
            Vec::new()
        } else {
            let (mut result, later): (Vec<Asteroid>, Vec<Asteroid>) = self
                .0
                .iter()
                .filter(|other| &station != other)
                .partition(|other| !self.blocked(station, other));
            result.sort_by(|a, b| station.angle(a).partial_cmp(&station.angle(b)).unwrap());
            result.append(&mut Asteroids(later.into_iter().collect()).vaporize_from(station));
            result
        }
    }

    fn blocked(&self, a: &Asteroid, b: &Asteroid) -> bool {
        let x = b.x - a.x;
        let y = b.y - a.y;
        let divisor = gcd(x.abs(), y.abs());
        (1..divisor)
            .map(|n| Asteroid {
                x: a.x + x / divisor * n,
                y: a.y + y / divisor * n,
            })
            .filter(|other| a != other && b != other)
            .any(|other| self.0.contains(&other))
    }
}

impl iter::FromIterator<Asteroid> for Asteroids {
    fn from_iter<T: IntoIterator<Item = Asteroid>>(iterator: T) -> Self {
        Asteroids(iterator.into_iter().collect())
    }
}

fn main() -> io::Result<()> {
    let mut input = String::new();
    io::stdin().read_to_string(&mut input)?;
    let asteroids = input
        .trim()
        .split("\n")
        .enumerate()
        .flat_map(|(y, row)| {
            row.trim()
                .chars()
                .enumerate()
                .flat_map(move |(x, cell)| match cell {
                    '#' => Some(Asteroid {
                        x: x.try_into().unwrap(),
                        y: y.try_into().unwrap(),
                    }),
                    '.' => None,
                    invalid => panic!("Invalid character: {}", invalid),
                })
        })
        .collect::<Asteroids>();

    let station = asteroids
        .iter()
        .max_by_key(|asteroid| asteroids.count_in_line_of_sight(asteroid))
        .map(|asteroid| asteroid.clone())
        .ok_or(errors::io("No asteroids!"))?;

    let vaporized_order = asteroids.vaporize_from(&station);
    let chosen = vaporized_order[199];

    println!("{}", chosen.x * 100 + chosen.y);

    Ok(())
}

fn gcd(a: i128, b: i128) -> i128 {
    iter::successors(Some((a, b)), |(a, b)| {
        if *b == 0 {
            None
        } else {
            Some((*b, *a % *b))
        }
    })
    .last()
    .unwrap()
    .0
}

fn modulus(n: f64, d: f64) -> f64 {
    if n >= 0.0 {
        n % d
    } else {
        modulus(n + d, d)
    }
}
<|endoftext|>


<commit_before><commit_msg>Use empty check instead of length check<commit_after><|endoftext|>


<commit_before><commit_msg>add new<commit_after>fn checkPerfectNumber(num: u32) -> bool {
    if num <= 1 {
        return false;
    }

    let mut result = 0;
    let x = num as f32;
    for i in 1..1 + x.sqrt() as u32 {
        if num % i == 0 {
            println!("{}", num / i);
            result += i + num / i;
        }
        //println!("{}", i);
    }
    if result - num == num {
        return true;
    }
    //println!("{}", x.sqrt() as u32);
    return false;
}

fn main() {
    println!("{}", checkPerfectNumber(10));
    println!("{}", checkPerfectNumber(28));
}
<|endoftext|>


<commit_before><commit_msg>Add slice exercise from @ruipserra!!! 💫✨<commit_after><|endoftext|>


<commit_before>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

// Code for annotating snippets.

use syntax_pos::{Span, FileMap};
use CodeMapper;
use std::rc::Rc;
use Level;

#[derive(Clone)]
pub struct SnippetData {
    codemap: Rc<CodeMapper>,
    files: Vec<FileInfo>,
}

#[derive(Clone)]
pub struct FileInfo {
    file: Rc<FileMap>,

    /// The "primary file", if any, gets a `-->` marker instead of
    /// `>>>`, and has a line-number/column printed and not just a
    /// filename (other files are not guaranteed to have line numbers
    /// or columns). It appears first in the listing. It is known to
    /// contain at least one primary span, though primary spans (which
    /// are designated with `^^^`) may also occur in other files.
    primary_span: Option<Span>,

    lines: Vec<Line>,
}

#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Line {
    pub line_index: usize,
    pub annotations: Vec<Annotation>,
}

#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct MultilineAnnotation {
    pub depth: usize,
    pub line_start: usize,
    pub line_end: usize,
    pub start_col: usize,
    pub end_col: usize,
    pub is_primary: bool,
    pub label: Option<String>,
}

impl MultilineAnnotation {
    pub fn increase_depth(&mut self) {
        self.depth += 1;
    }

    pub fn as_start(&self) -> Annotation {
        Annotation {
            start_col: self.start_col,
            end_col: self.start_col + 1,
            is_primary: self.is_primary,
            label: None,
            annotation_type: AnnotationType::MultilineStart(self.depth)
        }
    }

    pub fn as_end(&self) -> Annotation {
        Annotation {
            start_col: self.end_col.saturating_sub(1),
            end_col: self.end_col,
            is_primary: self.is_primary,
            label: self.label.clone(),
            annotation_type: AnnotationType::MultilineEnd(self.depth)
        }
    }

    pub fn as_line(&self) -> Annotation {
        Annotation {
            start_col: 0,
            end_col: 0,
            is_primary: self.is_primary,
            label: None,
            annotation_type: AnnotationType::MultilineLine(self.depth)
        }
    }
}

#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub enum AnnotationType {
    /// Annotation under a single line of code
    Singleline,

    /// Annotation enclosing the first and last character of a multiline span
    Multiline(MultilineAnnotation),

    // The Multiline type above is replaced with the following three in order
    // to reuse the current label drawing code.
    //
    // Each of these corresponds to one part of the following diagram:
    //
    //     x |   foo(1 + bar(x,
    //       |  _________^              < MultilineStart
    //     x | |             y),        < MultilineLine
    //       | |______________^ label   < MultilineEnd
    //     x |       z);
    /// Annotation marking the first character of a fully shown multiline span
    MultilineStart(usize),
    /// Annotation marking the last character of a fully shown multiline span
    MultilineEnd(usize),
    /// Line at the left enclosing the lines of a fully shown multiline span
    // Just a placeholder for the drawing algorithm, to know that it shouldn't skip the first 4
    // and last 2 lines of code. The actual line is drawn in `emit_message_default` and not in
    // `draw_multiline_line`.
    MultilineLine(usize),
}

#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Annotation {
    /// Start column, 0-based indexing -- counting *characters*, not
    /// utf-8 bytes. Note that it is important that this field goes
    /// first, so that when we sort, we sort orderings by start
    /// column.
    pub start_col: usize,

    /// End column within the line (exclusive)
    pub end_col: usize,

    /// Is this annotation derived from primary span
    pub is_primary: bool,

    /// Optional label to display adjacent to the annotation.
    pub label: Option<String>,

    /// Is this a single line, multiline or multiline span minimized down to a
    /// smaller span.
    pub annotation_type: AnnotationType,
}

impl Annotation {
    /// Whether this annotation is a vertical line placeholder.
    pub fn is_line(&self) -> bool {
        if let AnnotationType::MultilineLine(_) = self.annotation_type {
            true
        } else {
            false
        }
    }

    pub fn is_multiline(&self) -> bool {
        match self.annotation_type {
            AnnotationType::Multiline(_) |
            AnnotationType::MultilineStart(_) |
            AnnotationType::MultilineLine(_) |
            AnnotationType::MultilineEnd(_) => true,
            _ => false,
        }
    }

    pub fn len(&self) -> usize {
        // Account for usize underflows
        if self.end_col > self.start_col {
            self.end_col - self.start_col
        } else {
            self.start_col - self.end_col
        }
    }

    pub fn has_label(&self) -> bool {
        if let Some(ref label) = self.label {
            // Consider labels with no text as effectively not being there
            // to avoid weird output with unnecessary vertical lines, like:
            //
            //     X | fn foo(x: u32) {
            //       | -------^------
            //       | |      |
            //       | |
            //       |
            //
            // Note that this would be the complete output users would see.
            label.len() > 0
        } else {
            false
        }
    }

    pub fn takes_space(&self) -> bool {
        // Multiline annotations always have to keep vertical space.
        match self.annotation_type {
            AnnotationType::MultilineStart(_) |
            AnnotationType::MultilineEnd(_) => true,
            _ => false,
        }
    }
}

#[derive(Debug)]
pub struct StyledString {
    pub text: String,
    pub style: Style,
}

#[derive(Copy, Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
pub enum Style {
    HeaderMsg,
    LineAndColumn,
    LineNumber,
    Quotation,
    UnderlinePrimary,
    UnderlineSecondary,
    LabelPrimary,
    LabelSecondary,
    OldSchoolNoteText,
    NoStyle,
    Level(Level),
    Highlight,
}
<commit_msg>Rollup merge of #47842 - Manishearth:dead-code, r=nagisa Remove dead code The Clone impl makes the lint ignore the type.<commit_after>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

// Code for annotating snippets.

use Level;

#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Line {
    pub line_index: usize,
    pub annotations: Vec<Annotation>,
}

#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct MultilineAnnotation {
    pub depth: usize,
    pub line_start: usize,
    pub line_end: usize,
    pub start_col: usize,
    pub end_col: usize,
    pub is_primary: bool,
    pub label: Option<String>,
}

impl MultilineAnnotation {
    pub fn increase_depth(&mut self) {
        self.depth += 1;
    }

    pub fn as_start(&self) -> Annotation {
        Annotation {
            start_col: self.start_col,
            end_col: self.start_col + 1,
            is_primary: self.is_primary,
            label: None,
            annotation_type: AnnotationType::MultilineStart(self.depth)
        }
    }

    pub fn as_end(&self) -> Annotation {
        Annotation {
            start_col: self.end_col.saturating_sub(1),
            end_col: self.end_col,
            is_primary: self.is_primary,
            label: self.label.clone(),
            annotation_type: AnnotationType::MultilineEnd(self.depth)
        }
    }

    pub fn as_line(&self) -> Annotation {
        Annotation {
            start_col: 0,
            end_col: 0,
            is_primary: self.is_primary,
            label: None,
            annotation_type: AnnotationType::MultilineLine(self.depth)
        }
    }
}

#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub enum AnnotationType {
    /// Annotation under a single line of code
    Singleline,

    /// Annotation enclosing the first and last character of a multiline span
    Multiline(MultilineAnnotation),

    // The Multiline type above is replaced with the following three in order
    // to reuse the current label drawing code.
    //
    // Each of these corresponds to one part of the following diagram:
    //
    //     x |   foo(1 + bar(x,
    //       |  _________^              < MultilineStart
    //     x | |             y),        < MultilineLine
    //       | |______________^ label   < MultilineEnd
    //     x |       z);
    /// Annotation marking the first character of a fully shown multiline span
    MultilineStart(usize),
    /// Annotation marking the last character of a fully shown multiline span
    MultilineEnd(usize),
    /// Line at the left enclosing the lines of a fully shown multiline span
    // Just a placeholder for the drawing algorithm, to know that it shouldn't skip the first 4
    // and last 2 lines of code. The actual line is drawn in `emit_message_default` and not in
    // `draw_multiline_line`.
    MultilineLine(usize),
}

#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Annotation {
    /// Start column, 0-based indexing -- counting *characters*, not
    /// utf-8 bytes. Note that it is important that this field goes
    /// first, so that when we sort, we sort orderings by start
    /// column.
    pub start_col: usize,

    /// End column within the line (exclusive)
    pub end_col: usize,

    /// Is this annotation derived from primary span
    pub is_primary: bool,

    /// Optional label to display adjacent to the annotation.
    pub label: Option<String>,

    /// Is this a single line, multiline or multiline span minimized down to a
    /// smaller span.
    pub annotation_type: AnnotationType,
}

impl Annotation {
    /// Whether this annotation is a vertical line placeholder.
    pub fn is_line(&self) -> bool {
        if let AnnotationType::MultilineLine(_) = self.annotation_type {
            true
        } else {
            false
        }
    }

    pub fn is_multiline(&self) -> bool {
        match self.annotation_type {
            AnnotationType::Multiline(_) |
            AnnotationType::MultilineStart(_) |
            AnnotationType::MultilineLine(_) |
            AnnotationType::MultilineEnd(_) => true,
            _ => false,
        }
    }

    pub fn len(&self) -> usize {
        // Account for usize underflows
        if self.end_col > self.start_col {
            self.end_col - self.start_col
        } else {
            self.start_col - self.end_col
        }
    }

    pub fn has_label(&self) -> bool {
        if let Some(ref label) = self.label {
            // Consider labels with no text as effectively not being there
            // to avoid weird output with unnecessary vertical lines, like:
            //
            //     X | fn foo(x: u32) {
            //       | -------^------
            //       | |      |
            //       | |
            //       |
            //
            // Note that this would be the complete output users would see.
            label.len() > 0
        } else {
            false
        }
    }

    pub fn takes_space(&self) -> bool {
        // Multiline annotations always have to keep vertical space.
        match self.annotation_type {
            AnnotationType::MultilineStart(_) |
            AnnotationType::MultilineEnd(_) => true,
            _ => false,
        }
    }
}

#[derive(Debug)]
pub struct StyledString {
    pub text: String,
    pub style: Style,
}

#[derive(Copy, Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
pub enum Style {
    HeaderMsg,
    LineAndColumn,
    LineNumber,
    Quotation,
    UnderlinePrimary,
    UnderlineSecondary,
    LabelPrimary,
    LabelSecondary,
    OldSchoolNoteText,
    NoStyle,
    Level(Level),
    Highlight,
}
<|endoftext|>


<commit_before><commit_msg>Add the mpsc.rs file (sigh); get rid of `End<T>`.<commit_after>//! Multi-producer single-consumer queues.
//!
//! Since the standard library's implementation of `mpsc` requires us to clone the senders in
//! advance, such that we cannot store them in our global state outside a lock, we must implement
//! our own `mpsc` queue.
//!
//! Right now, the implementation is really nothing but a wrapper around `Mutex<Vec<T>>`, and
//! although this is reasonably fast as the lock is only held for very short time, it is
//! sub-optimal, and blocking.

use parking_lot::Mutex;
use std::sync::Arc;
use std::mem;

/// Create a MPSC pair.
///
/// This creates a "channel", i.e. a pair of sender and receiver connected to each other.
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
    // Create a new ARC.
    let end = Arc::new(Mutex::new(Vec::new()));

    (Sender {
        inner: end.clone(),
    }, Receiver {
        inner: end,
    })
}

/// The sender of a MPSC channel.
pub struct Sender<T> {
    /// The wrapped end.
    inner: Arc<Mutex<Vec<T>>>,
}

impl<T> Sender<T> {
    /// Send an item to this channel.
    pub fn send(&self, item: T) {
        // Lock the vector, and push.
        self.inner.lock().push(item);
    }
}

/// The receiver of a MPSC channel.
pub struct Receiver<T> {
    /// The wrapped end.
    inner: Arc<Mutex<Vec<T>>>,
}

impl<T> Receiver<T> {
    /// Receive all the elements in the queue.
    ///
    /// This takes all the elements and applies the given closure to them in an unspecified order.
    pub fn recv_all<F>(&self, f: F)
    where F: Fn(T) {
        // Lock the vector, and replace it by an empty vector, then iterate.
        for i in mem::replace(&mut *self.inner.lock(), Vec::new()) {
            f(i);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Added gtk::HeaderBar example<commit_after>use gtk::{Inhibit};
use gtk::Orientation::{Vertical};
use gtk::prelude::*;
use relm_derive::{Msg, widget};
use relm::{Component, Widget, init};

use self::HeaderMsg::*;
use self::WinMsg::*;

#[derive(Msg)]
pub enum HeaderMsg {
    Add,
    Remove,
}

#[widget]
impl Widget for Header {
    fn model() -> () {

    }

    fn update(&mut self, event: HeaderMsg) {
        match event {
            Add => println!("Add"),
            Remove => println!("Remove"),
        }
    }

    view! {
        #[name="titlebar"]
        gtk::HeaderBar {
            title: Some("Title"),
            show_close_button: true,

            #[name="add_button"]
            gtk::Button {
                clicked => Add,
                label: "Add",
            },

            #[name="remove_button"]
            gtk::Button {
                clicked => Remove,
                label: "Remove",
            },
        }
    }
}

pub struct Model {
    header: Component<Header>,
}

#[derive(Msg)]
pub enum WinMsg {
    Quit,
}

#[widget]
impl Widget for Win {
    fn model() -> Model {
        let header = init::<Header>(()).expect("Header");

        Model {
            header
        }
    }

    fn update(&mut self, event: WinMsg) {
        match event {
            Quit => gtk::main_quit(),
        }
    }

    view! {
        #[name="window"]
        gtk::Window {
            titlebar: Some(self.model.header.widget()),

            #[name="app"]
            gtk::Box {
                orientation: Vertical
            },

            delete_event(_, _) => (Quit, Inhibit(false)),
        }
    }
}

fn main() {
    Win::run(()).expect("Window::run");
}
<|endoftext|>