<commit_before>use std::cell::RefCell;

use proc_macro2::{Delimiter, Span};

use buffer::Cursor;
use error::{self, Error};
use span::IntoSpans;
use token::Token;

/// Support for checking the next token in a stream to decide how to parse.
///
/// An important advantage over [`ParseStream::peek`] is that here we
/// automatically construct an appropriate error message based on the token
/// alternatives that get peeked. If you are producing your own error message,
/// go ahead and use `ParseStream::peek` instead.
///
/// Use [`ParseStream::lookahead1`] to construct this object.
///
/// [`ParseStream::peek`]: struct.ParseBuffer.html#method.peek
/// [`ParseStream::lookahead1`]: struct.ParseBuffer.html#method.lookahead1
///
/// # Example
///
/// ```
/// # extern crate syn;
/// #
/// use syn::{ConstParam, Ident, Lifetime, LifetimeDef, Token, TypeParam};
/// use syn::parse::{Parse, ParseStream, Result};
///
/// // A generic parameter, a single one of the comma-separated elements inside
/// // angle brackets in:
/// //
/// //     fn f<T: Clone, 'a, 'b: 'a, const N: usize>() { ... }
/// //
/// // On invalid input, lookahead gives us a reasonable error message.
/// //
/// //     error: expected one of: identifier, lifetime, `const`
/// //       |
/// //     5 |     fn f<!Sized>() {}
/// //       |          ^
/// enum GenericParam {
///     Type(TypeParam),
///     Lifetime(LifetimeDef),
///     Const(ConstParam),
/// }
///
/// impl Parse for GenericParam {
///     fn parse(input: ParseStream) -> Result<Self> {
///         let lookahead = input.lookahead1();
///         if lookahead.peek(Ident) {
///             input.parse().map(GenericParam::Type)
///         } else if lookahead.peek(Lifetime) {
///             input.parse().map(GenericParam::Lifetime)
///         } else if lookahead.peek(Token![const]) {
///             input.parse().map(GenericParam::Const)
///         } else {
///             Err(lookahead.error())
///         }
///     }
/// }
/// #
/// # fn main() {}
/// ```
pub struct Lookahead1<'a> {
    scope: Span,
    cursor: Cursor<'a>,
    comparisons: RefCell<Vec<&'static str>>,
}

pub fn new(scope: Span, cursor: Cursor) -> Lookahead1 {
    Lookahead1 {
        scope: scope,
        cursor: cursor,
        comparisons: RefCell::new(Vec::new()),
    }
}

fn peek_impl(
    lookahead: &Lookahead1,
    peek: fn(Cursor) -> bool,
    display: fn() -> &'static str,
) -> bool {
    if peek(lookahead.cursor) {
        return true;
    }
    lookahead.comparisons.borrow_mut().push(display());
    false
}

impl<'a> Lookahead1<'a> {
    /// Looks at the next token in the parse stream to determine whether it
    /// matches the requested type of token.
    ///
    /// # Syntax
    ///
    /// Note that this method does not use turbofish syntax. Pass the peek type
    /// inside of parentheses.
    ///
    /// - `input.peek(Token![struct])`
    /// - `input.peek(Token![==])`
    /// - `input.peek(Ident)`
    /// - `input.peek(Lifetime)`
    /// - `input.peek(token::Brace)`
    pub fn peek<T: Peek>(&self, token: T) -> bool {
        let _ = token;
        peek_impl(self, T::Token::peek, T::Token::display)
    }

    /// Triggers an error at the current position of the parse stream.
    ///
    /// The error message will identify all of the expected token types that
    /// have been peeked against this lookahead instance.
    pub fn error(self) -> Error {
        let comparisons = self.comparisons.borrow();
        match comparisons.len() {
            0 => if self.cursor.eof() {
                Error::new(self.scope, "unexpected end of input")
            } else {
                Error::new(self.cursor.span(), "unexpected token")
            },
            1 => {
                let message = format!("expected {}", comparisons[0]);
                error::new_at(self.scope, self.cursor, message)
            }
            _ => {
                let join = comparisons.join(", ");
                let message = format!("expected one of: {}", join);
                error::new_at(self.scope, self.cursor, message)
            }
        }
    }
}

/// Types that can be parsed by looking at just one token.
///
/// Use [`ParseStream::peek`] to peek one of these types in a parse stream
/// without consuming it from the stream.
///
/// This trait is sealed and cannot be implemented for types outside of Syn.
///
/// [`ParseStream::peek`]: struct.ParseBuffer.html#method.peek
pub trait Peek: private::Sealed {
    // Not public API.
    #[doc(hidden)]
    type Token: Token;
}

impl<F: FnOnce(TokenMarker) -> T, T: Token> Peek for F {
    type Token = T;
}

pub enum TokenMarker {}

impl<S> IntoSpans<S> for TokenMarker {
    fn into_spans(self) -> S {
        match self {}
    }
}

pub fn is_delimiter(cursor: Cursor, delimiter: Delimiter) -> bool {
    cursor.group(delimiter).is_some()
}

mod private {
    use super::{Token, TokenMarker};
    pub trait Sealed {}
    impl<F: FnOnce(TokenMarker) -> T, T: Token> Sealed for F {}
}
<commit_msg>Improve error message for 2 possibilities in lookahead<commit_after>use std::cell::RefCell;

use proc_macro2::{Delimiter, Span};

use buffer::Cursor;
use error::{self, Error};
use span::IntoSpans;
use token::Token;

/// Support for checking the next token in a stream to decide how to parse.
///
/// An important advantage over [`ParseStream::peek`] is that here we
/// automatically construct an appropriate error message based on the token
/// alternatives that get peeked. If you are producing your own error message,
/// go ahead and use `ParseStream::peek` instead.
///
/// Use [`ParseStream::lookahead1`] to construct this object.
///
/// [`ParseStream::peek`]: struct.ParseBuffer.html#method.peek
/// [`ParseStream::lookahead1`]: struct.ParseBuffer.html#method.lookahead1
///
/// # Example
///
/// ```
/// # extern crate syn;
/// #
/// use syn::{ConstParam, Ident, Lifetime, LifetimeDef, Token, TypeParam};
/// use syn::parse::{Parse, ParseStream, Result};
///
/// // A generic parameter, a single one of the comma-separated elements inside
/// // angle brackets in:
/// //
/// //     fn f<T: Clone, 'a, 'b: 'a, const N: usize>() { ... }
/// //
/// // On invalid input, lookahead gives us a reasonable error message.
/// //
/// //     error: expected one of: identifier, lifetime, `const`
/// //       |
/// //     5 |     fn f<!Sized>() {}
/// //       |          ^
/// enum GenericParam {
///     Type(TypeParam),
///     Lifetime(LifetimeDef),
///     Const(ConstParam),
/// }
///
/// impl Parse for GenericParam {
///     fn parse(input: ParseStream) -> Result<Self> {
///         let lookahead = input.lookahead1();
///         if lookahead.peek(Ident) {
///             input.parse().map(GenericParam::Type)
///         } else if lookahead.peek(Lifetime) {
///             input.parse().map(GenericParam::Lifetime)
///         } else if lookahead.peek(Token![const]) {
///             input.parse().map(GenericParam::Const)
///         } else {
///             Err(lookahead.error())
///         }
///     }
/// }
/// #
/// # fn main() {}
/// ```
pub struct Lookahead1<'a> {
    scope: Span,
    cursor: Cursor<'a>,
    comparisons: RefCell<Vec<&'static str>>,
}

pub fn new(scope: Span, cursor: Cursor) -> Lookahead1 {
    Lookahead1 {
        scope: scope,
        cursor: cursor,
        comparisons: RefCell::new(Vec::new()),
    }
}

fn peek_impl(
    lookahead: &Lookahead1,
    peek: fn(Cursor) -> bool,
    display: fn() -> &'static str,
) -> bool {
    if peek(lookahead.cursor) {
        return true;
    }
    lookahead.comparisons.borrow_mut().push(display());
    false
}

impl<'a> Lookahead1<'a> {
    /// Looks at the next token in the parse stream to determine whether it
    /// matches the requested type of token.
    ///
    /// # Syntax
    ///
    /// Note that this method does not use turbofish syntax. Pass the peek type
    /// inside of parentheses.
    ///
    /// - `input.peek(Token![struct])`
    /// - `input.peek(Token![==])`
    /// - `input.peek(Ident)`
    /// - `input.peek(Lifetime)`
    /// - `input.peek(token::Brace)`
    pub fn peek<T: Peek>(&self, token: T) -> bool {
        let _ = token;
        peek_impl(self, T::Token::peek, T::Token::display)
    }

    /// Triggers an error at the current position of the parse stream.
    ///
    /// The error message will identify all of the expected token types that
    /// have been peeked against this lookahead instance.
    pub fn error(self) -> Error {
        let comparisons = self.comparisons.borrow();
        match comparisons.len() {
            0 => if self.cursor.eof() {
                Error::new(self.scope, "unexpected end of input")
            } else {
                Error::new(self.cursor.span(), "unexpected token")
            },
            1 => {
                let message = format!("expected {}", comparisons[0]);
                error::new_at(self.scope, self.cursor, message)
            }
            2 => {
                let message = format!("expected {} or {}", comparisons[0], comparisons[1]);
                error::new_at(self.scope, self.cursor, message)
            }
            _ => {
                let join = comparisons.join(", ");
                let message = format!("expected one of: {}", join);
                error::new_at(self.scope, self.cursor, message)
            }
        }
    }
}

/// Types that can be parsed by looking at just one token.
///
/// Use [`ParseStream::peek`] to peek one of these types in a parse stream
/// without consuming it from the stream.
///
/// This trait is sealed and cannot be implemented for types outside of Syn.
///
/// [`ParseStream::peek`]: struct.ParseBuffer.html#method.peek
pub trait Peek: private::Sealed {
    // Not public API.
    #[doc(hidden)]
    type Token: Token;
}

impl<F: FnOnce(TokenMarker) -> T, T: Token> Peek for F {
    type Token = T;
}

pub enum TokenMarker {}

impl<S> IntoSpans<S> for TokenMarker {
    fn into_spans(self) -> S {
        match self {}
    }
}

pub fn is_delimiter(cursor: Cursor, delimiter: Delimiter) -> bool {
    cursor.group(delimiter).is_some()
}

mod private {
    use super::{Token, TokenMarker};
    pub trait Sealed {}
    impl<F: FnOnce(TokenMarker) -> T, T: Token> Sealed for F {}
}
<|endoftext|>


<commit_before>use profiler;

use leveldb::database::Database as _LevelDB;
use leveldb::iterator::{Iterator as _Iterator, Iterable};
use leveldb::error::Error as _Error;
use leveldb::database::snapshots::Snapshot as _Snapshot;
use leveldb::options::{WriteOptions, ReadOptions};
use leveldb::database::batch::Writebatch;
use leveldb::batch::Batch;
use leveldb::snapshots::Snapshots;

use std::fs;
use std::io;
use std::mem;
use std::path::Path;
use std::error;
use std::sync::Arc;

pub use leveldb::options::Options as LevelDBOptions;
pub use leveldb::database::cache::Cache as LevelDBCache;

use super::{Database, Iterator, Iter, Snapshot, Error, Patch, Change, Result};

const LEVELDB_READ_OPTIONS: ReadOptions<'static> = ReadOptions {
    verify_checksums: false,
    fill_cache: true,
    snapshot: None,
};

const LEVELDB_WRITE_OPTIONS: WriteOptions = WriteOptions { sync: false };

#[derive(Clone)]
pub struct LevelDB {
    db: Arc<_LevelDB>,
}

struct LevelDBSnapshot {
    _db: Arc<_LevelDB>,
    snapshot: _Snapshot<'static>,
}

struct LevelDBIterator<'a> {
    iter: _Iterator<'a>,
}

impl From<_Error> for Error {
    fn from(err: _Error) -> Self {
        Error::new(error::Error::description(&err))
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Self {
        Error::new(error::Error::description(&err))
    }
}

impl LevelDB {
    // TODO: configurate LRU cache
    pub fn open(path: &Path, options: LevelDBOptions) -> Result<LevelDB> {
        if options.create_if_missing {
            fs::create_dir_all(path)?;
        }
        let database = _LevelDB::open(path, options)?;
        Ok(LevelDB { db: Arc::new(database) })
    }
}

impl Database for LevelDB {
    fn clone(&self) -> Box<Database> {
        Box::new(Clone::clone(self))
    }

    fn snapshot(&self) -> Box<Snapshot> {
        let _p = profiler::ProfilerSpan::new("LevelDB::snapshot");
        Box::new(LevelDBSnapshot {
                     _db: self.db.clone(),
                     snapshot: unsafe { mem::transmute(self.db.snapshot()) },
                 })
    }

    fn merge(&mut self, patch: Patch) -> Result<()> {
        let _p = profiler::ProfilerSpan::new("LevelDB::merge");
        let mut batch = Writebatch::new();
        for (key, change) in patch {
            match change {
                Change::Put(ref v) => batch.put(key, v),
                Change::Delete => batch.delete(key),
            }
        }
        self.db
            .write(LEVELDB_WRITE_OPTIONS, &batch)
            .map_err(Into::into)
    }
}

impl Snapshot for LevelDBSnapshot {
    fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
        let _p = profiler::ProfilerSpan::new("LevelDBSnapshot::get");
        match self.snapshot.get(LEVELDB_READ_OPTIONS, key) {
            Ok(value) => value,
            Err(err) => panic!(err),
        }
    }

    fn iter<'a>(&'a self, from: &[u8]) -> Iter<'a> {
        let _p = profiler::ProfilerSpan::new("LevelDBSnapshot::iter");
        let mut iter = self.snapshot.iter(LEVELDB_READ_OPTIONS);
        iter.seek(from);
        Box::new(LevelDBIterator { iter: iter })
    }
}

impl<'a> Iterator<'a> for LevelDBIterator<'a> {
    fn next(&mut self) -> Option<(&[u8], &[u8])> {
        let _p = profiler::ProfilerSpan::new("LevelDBIterator::next");
        self.iter.next()
    }

    fn peek(&mut self) -> Option<(&[u8], &[u8])> {
        let _p = profiler::ProfilerSpan::new("LevelDBIterator::peek");
        self.iter.peek()
    }
}

impl ::std::fmt::Debug for LevelDB {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "LevelDB(..)")
    }
}

impl ::std::fmt::Debug for LevelDBSnapshot {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "LevelDBSnapshot(..)")
    }
}
<commit_msg>Use AsRef<Path> for LevelDB::open<commit_after>use profiler;

use leveldb::database::Database as _LevelDB;
use leveldb::iterator::{Iterator as _Iterator, Iterable};
use leveldb::error::Error as _Error;
use leveldb::database::snapshots::Snapshot as _Snapshot;
use leveldb::options::{WriteOptions, ReadOptions};
use leveldb::database::batch::Writebatch;
use leveldb::batch::Batch;
use leveldb::snapshots::Snapshots;

use std::fs;
use std::io;
use std::mem;
use std::path::Path;
use std::error;
use std::sync::Arc;

pub use leveldb::options::Options as LevelDBOptions;
pub use leveldb::database::cache::Cache as LevelDBCache;

use super::{Database, Iterator, Iter, Snapshot, Error, Patch, Change, Result};

const LEVELDB_READ_OPTIONS: ReadOptions<'static> = ReadOptions {
    verify_checksums: false,
    fill_cache: true,
    snapshot: None,
};

const LEVELDB_WRITE_OPTIONS: WriteOptions = WriteOptions { sync: false };

#[derive(Clone)]
pub struct LevelDB {
    db: Arc<_LevelDB>,
}

struct LevelDBSnapshot {
    _db: Arc<_LevelDB>,
    snapshot: _Snapshot<'static>,
}

struct LevelDBIterator<'a> {
    iter: _Iterator<'a>,
}

impl From<_Error> for Error {
    fn from(err: _Error) -> Self {
        Error::new(error::Error::description(&err))
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Self {
        Error::new(error::Error::description(&err))
    }
}

impl LevelDB {
    // TODO: configurate LRU cache
    pub fn open<P: AsRef<Path>>(path: P, options: LevelDBOptions) -> Result<LevelDB> {
        if options.create_if_missing {
            fs::create_dir_all(path.as_ref())?;
        }
        let database = _LevelDB::open(path.as_ref(), options)?;
        Ok(LevelDB { db: Arc::new(database) })
    }
}

impl Database for LevelDB {
    fn clone(&self) -> Box<Database> {
        Box::new(Clone::clone(self))
    }

    fn snapshot(&self) -> Box<Snapshot> {
        let _p = profiler::ProfilerSpan::new("LevelDB::snapshot");
        Box::new(LevelDBSnapshot {
                     _db: self.db.clone(),
                     snapshot: unsafe { mem::transmute(self.db.snapshot()) },
                 })
    }

    fn merge(&mut self, patch: Patch) -> Result<()> {
        let _p = profiler::ProfilerSpan::new("LevelDB::merge");
        let mut batch = Writebatch::new();
        for (key, change) in patch {
            match change {
                Change::Put(ref v) => batch.put(key, v),
                Change::Delete => batch.delete(key),
            }
        }
        self.db
            .write(LEVELDB_WRITE_OPTIONS, &batch)
            .map_err(Into::into)
    }
}

impl Snapshot for LevelDBSnapshot {
    fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
        let _p = profiler::ProfilerSpan::new("LevelDBSnapshot::get");
        match self.snapshot.get(LEVELDB_READ_OPTIONS, key) {
            Ok(value) => value,
            Err(err) => panic!(err),
        }
    }

    fn iter<'a>(&'a self, from: &[u8]) -> Iter<'a> {
        let _p = profiler::ProfilerSpan::new("LevelDBSnapshot::iter");
        let mut iter = self.snapshot.iter(LEVELDB_READ_OPTIONS);
        iter.seek(from);
        Box::new(LevelDBIterator { iter: iter })
    }
}

impl<'a> Iterator<'a> for LevelDBIterator<'a> {
    fn next(&mut self) -> Option<(&[u8], &[u8])> {
        let _p = profiler::ProfilerSpan::new("LevelDBIterator::next");
        self.iter.next()
    }

    fn peek(&mut self) -> Option<(&[u8], &[u8])> {
        let _p = profiler::ProfilerSpan::new("LevelDBIterator::peek");
        self.iter.peek()
    }
}

impl ::std::fmt::Debug for LevelDB {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "LevelDB(..)")
    }
}

impl ::std::fmt::Debug for LevelDBSnapshot {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "LevelDBSnapshot(..)")
    }
}
<|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.

#[cfg(stage0)]
use prelude::v1::*;

use ops::{Add, Sub, Mul, Div};
use sys::time::SteadyTime;

const NANOS_PER_SEC: u32 = 1_000_000_000;
const NANOS_PER_MILLI: u32 = 1_000_000;
const MILLIS_PER_SEC: u64 = 1_000;

/// A duration type to represent a span of time, typically used for system
/// timeouts.
///
/// Each duration is composed of a number of seconds and nanosecond precision.
/// APIs binding a system timeout will typically round up the nanosecond
/// precision if the underlying system does not support that level of precision.
///
/// Durations implement many common traits, including `Add`, `Sub`, and other
/// ops traits. Currently a duration may only be inspected for its number of
/// seconds and its nanosecond precision.
///
/// # Examples
///
/// ```
/// #![feature(duration)]
/// use std::time::Duration;
///
/// let five_seconds = Duration::new(5, 0);
/// let five_seconds_and_five_nanos = five_seconds + Duration::new(0, 5);
///
/// assert_eq!(five_seconds_and_five_nanos.as_secs(), 5);
/// assert_eq!(five_seconds_and_five_nanos.subsec_nanos(), 5);
///
/// let ten_millis = Duration::from_millis(10);
/// ```
#[stable(feature = "duration", since = "1.3.0")]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct Duration {
    secs: u64,
    nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC
}

impl Duration {
    /// Crates a new `Duration` from the specified number of seconds and
    /// additional nanosecond precision.
    ///
    /// If the nanoseconds is greater than 1 billion (the number of nanoseconds
    /// in a second), then it will carry over into the seconds provided.
    #[stable(feature = "duration", since = "1.3.0")]
    pub fn new(secs: u64, nanos: u32) -> Duration {
        let secs = secs + (nanos / NANOS_PER_SEC) as u64;
        let nanos = nanos % NANOS_PER_SEC;
        Duration { secs: secs, nanos: nanos }
    }

    /// Runs a closure, returning the duration of time it took to run the
    /// closure.
    #[unstable(feature = "duration_span",
               reason = "unsure if this is the right API or whether it should \
                         wait for a more general \"moment in time\" \
                         abstraction")]
    pub fn span<F>(f: F) -> Duration where F: FnOnce() {
        let start = SteadyTime::now();
        f();
        &SteadyTime::now() - &start
    }

    /// Creates a new `Duration` from the specified number of seconds.
    #[stable(feature = "duration", since = "1.3.0")]
    pub fn from_secs(secs: u64) -> Duration {
        Duration { secs: secs, nanos: 0 }
    }

    /// Creates a new `Duration` from the specified number of milliseconds.
    #[stable(feature = "duration", since = "1.3.0")]
    pub fn from_millis(millis: u64) -> Duration {
        let secs = millis / MILLIS_PER_SEC;
        let nanos = ((millis % MILLIS_PER_SEC) as u32) * NANOS_PER_MILLI;
        Duration { secs: secs, nanos: nanos }
    }

    /// Returns the number of whole seconds represented by this duration.
    ///
    /// The extra precision represented by this duration is ignored (e.g. extra
    /// nanoseconds are not represented in the returned value).
    #[stable(feature = "duration", since = "1.3.0")]
    pub fn as_secs(&self) -> u64 { self.secs }

    /// Returns the nanosecond precision represented by this duration.
    ///
    /// This method does **not** return the length of the duration when
    /// represented by nanoseconds. The returned number always represents a
    /// fractional portion of a second (e.g. it is less than one billion).
    #[stable(feature = "duration", since = "1.3.0")]
    pub fn subsec_nanos(&self) -> u32 { self.nanos }
}

impl Add for Duration {
    type Output = Duration;

    fn add(self, rhs: Duration) -> Duration {
        let mut secs = self.secs.checked_add(rhs.secs)
                           .expect("overflow when adding durations");
        let mut nanos = self.nanos + rhs.nanos;
        if nanos >= NANOS_PER_SEC {
            nanos -= NANOS_PER_SEC;
            secs = secs.checked_add(1).expect("overflow when adding durations");
        }
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

impl Sub for Duration {
    type Output = Duration;

    fn sub(self, rhs: Duration) -> Duration {
        let mut secs = self.secs.checked_sub(rhs.secs)
                           .expect("overflow when subtracting durations");
        let nanos = if self.nanos >= rhs.nanos {
            self.nanos - rhs.nanos
        } else {
            secs = secs.checked_sub(1)
                       .expect("overflow when subtracting durations");
            self.nanos + NANOS_PER_SEC - rhs.nanos
        };
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

impl Mul<u32> for Duration {
    type Output = Duration;

    fn mul(self, rhs: u32) -> Duration {
        // Multiply nanoseconds as u64, because it cannot overflow that way.
        let total_nanos = self.nanos as u64 * rhs as u64;
        let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
        let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
        let secs = self.secs.checked_mul(rhs as u64)
                       .and_then(|s| s.checked_add(extra_secs))
                       .expect("overflow when multiplying duration");
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

impl Div<u32> for Duration {
    type Output = Duration;

    fn div(self, rhs: u32) -> Duration {
        let secs = self.secs / (rhs as u64);
        let carry = self.secs - secs * (rhs as u64);
        let extra_nanos = carry * (NANOS_PER_SEC as u64) / (rhs as u64);
        let nanos = self.nanos / rhs + (extra_nanos as u32);
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

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

    #[test]
    fn creation() {
        assert!(Duration::from_secs(1) != Duration::from_secs(0));
        assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
                   Duration::from_secs(3));
        assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),
                   Duration::new(4, 10 * 1_000_000));
        assert_eq!(Duration::from_millis(4000), Duration::new(4, 0));
    }

    #[test]
    fn secs() {
        assert_eq!(Duration::new(0, 0).as_secs(), 0);
        assert_eq!(Duration::from_secs(1).as_secs(), 1);
        assert_eq!(Duration::from_millis(999).as_secs(), 0);
        assert_eq!(Duration::from_millis(1001).as_secs(), 1);
    }

    #[test]
    fn nanos() {
        assert_eq!(Duration::new(0, 0).subsec_nanos(), 0);
        assert_eq!(Duration::new(0, 5).subsec_nanos(), 5);
        assert_eq!(Duration::new(0, 1_000_000_001).subsec_nanos(), 1);
        assert_eq!(Duration::from_secs(1).subsec_nanos(), 0);
        assert_eq!(Duration::from_millis(999).subsec_nanos(), 999 * 1_000_000);
        assert_eq!(Duration::from_millis(1001).subsec_nanos(), 1 * 1_000_000);
    }

    #[test]
    fn add() {
        assert_eq!(Duration::new(0, 0) + Duration::new(0, 1),
                   Duration::new(0, 1));
        assert_eq!(Duration::new(0, 500_000_000) + Duration::new(0, 500_000_001),
                   Duration::new(1, 1));
    }

    #[test]
    fn sub() {
        assert_eq!(Duration::new(0, 1) - Duration::new(0, 0),
                   Duration::new(0, 1));
        assert_eq!(Duration::new(0, 500_000_001) - Duration::new(0, 500_000_000),
                   Duration::new(0, 1));
        assert_eq!(Duration::new(1, 0) - Duration::new(0, 1),
                   Duration::new(0, 999_999_999));
    }

    #[test] #[should_panic]
    fn sub_bad1() {
        Duration::new(0, 0) - Duration::new(0, 1);
    }

    #[test] #[should_panic]
    fn sub_bad2() {
        Duration::new(0, 0) - Duration::new(1, 0);
    }

    #[test]
    fn mul() {
        assert_eq!(Duration::new(0, 1) * 2, Duration::new(0, 2));
        assert_eq!(Duration::new(1, 1) * 3, Duration::new(3, 3));
        assert_eq!(Duration::new(0, 500_000_001) * 4, Duration::new(2, 4));
        assert_eq!(Duration::new(0, 500_000_001) * 4000,
                   Duration::new(2000, 4000));
    }

    #[test]
    fn div() {
        assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));
        assert_eq!(Duration::new(1, 1) / 3, Duration::new(0, 333_333_333));
        assert_eq!(Duration::new(99, 999_999_000) / 100,
                   Duration::new(0, 999_999_990));
    }
}
<commit_msg>Add back and deprecate old methods.<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.

#[cfg(stage0)]
use prelude::v1::*;

use ops::{Add, Sub, Mul, Div};
use sys::time::SteadyTime;

const NANOS_PER_SEC: u32 = 1_000_000_000;
const NANOS_PER_MILLI: u32 = 1_000_000;
const MILLIS_PER_SEC: u64 = 1_000;

/// A duration type to represent a span of time, typically used for system
/// timeouts.
///
/// Each duration is composed of a number of seconds and nanosecond precision.
/// APIs binding a system timeout will typically round up the nanosecond
/// precision if the underlying system does not support that level of precision.
///
/// Durations implement many common traits, including `Add`, `Sub`, and other
/// ops traits. Currently a duration may only be inspected for its number of
/// seconds and its nanosecond precision.
///
/// # Examples
///
/// ```
/// #![feature(duration)]
/// use std::time::Duration;
///
/// let five_seconds = Duration::new(5, 0);
/// let five_seconds_and_five_nanos = five_seconds + Duration::new(0, 5);
///
/// assert_eq!(five_seconds_and_five_nanos.as_secs(), 5);
/// assert_eq!(five_seconds_and_five_nanos.subsec_nanos(), 5);
///
/// let ten_millis = Duration::from_millis(10);
/// ```
#[stable(feature = "duration", since = "1.3.0")]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct Duration {
    secs: u64,
    nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC
}

impl Duration {
    /// Crates a new `Duration` from the specified number of seconds and
    /// additional nanosecond precision.
    ///
    /// If the nanoseconds is greater than 1 billion (the number of nanoseconds
    /// in a second), then it will carry over into the seconds provided.
    #[stable(feature = "duration", since = "1.3.0")]
    pub fn new(secs: u64, nanos: u32) -> Duration {
        let secs = secs + (nanos / NANOS_PER_SEC) as u64;
        let nanos = nanos % NANOS_PER_SEC;
        Duration { secs: secs, nanos: nanos }
    }

    /// Runs a closure, returning the duration of time it took to run the
    /// closure.
    #[unstable(feature = "duration_span",
               reason = "unsure if this is the right API or whether it should \
                         wait for a more general \"moment in time\" \
                         abstraction")]
    pub fn span<F>(f: F) -> Duration where F: FnOnce() {
        let start = SteadyTime::now();
        f();
        &SteadyTime::now() - &start
    }

    /// Creates a new `Duration` from the specified number of seconds.
    #[stable(feature = "duration", since = "1.3.0")]
    pub fn from_secs(secs: u64) -> Duration {
        Duration { secs: secs, nanos: 0 }
    }

    /// Creates a new `Duration` from the specified number of milliseconds.
    #[stable(feature = "duration", since = "1.3.0")]
    pub fn from_millis(millis: u64) -> Duration {
        let secs = millis / MILLIS_PER_SEC;
        let nanos = ((millis % MILLIS_PER_SEC) as u32) * NANOS_PER_MILLI;
        Duration { secs: secs, nanos: nanos }
    }

    /// Returns the number of whole seconds represented by this duration.
    ///
    /// The extra precision represented by this duration is ignored (e.g. extra
    /// nanoseconds are not represented in the returned value).
    #[stable(feature = "duration", since = "1.3.0")]
    pub fn as_secs(&self) -> u64 { self.secs }

    #[deprecated(reason = "renamed to `as_secs`", since = "1.3.0")]
    #[unstable(feature = "duration_deprecated")]
    /// Returns the number of whole seconds represented by this duration.
    ///
    /// The extra precision represented by this duration is ignored (e.g. extra
    /// nanoseconds are not represented in the returned value).
    pub fn secs(&self) -> u64 { self.as_secs() }

    /// Returns the nanosecond precision represented by this duration.
    ///
    /// This method does **not** return the length of the duration when
    /// represented by nanoseconds. The returned number always represents a
    /// fractional portion of a second (e.g. it is less than one billion).
    #[stable(feature = "duration", since = "1.3.0")]
    pub fn subsec_nanos(&self) -> u32 { self.nanos }

    #[deprecated(reason = "renamed to `subsec_nanos`", since = "1.3.0")]
    #[unstable(feature = "duration_deprecated")]
    /// Returns the nanosecond precision represented by this duration.
    ///
    /// This method does **not** return the length of the duration when
    /// represented by nanoseconds. The returned number always represents a
    /// fractional portion of a second (e.g. it is less than one billion).
    pub fn extra_nanos(&self) -> u32 { self.subsec_nanos() }
}

impl Add for Duration {
    type Output = Duration;

    fn add(self, rhs: Duration) -> Duration {
        let mut secs = self.secs.checked_add(rhs.secs)
                           .expect("overflow when adding durations");
        let mut nanos = self.nanos + rhs.nanos;
        if nanos >= NANOS_PER_SEC {
            nanos -= NANOS_PER_SEC;
            secs = secs.checked_add(1).expect("overflow when adding durations");
        }
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

impl Sub for Duration {
    type Output = Duration;

    fn sub(self, rhs: Duration) -> Duration {
        let mut secs = self.secs.checked_sub(rhs.secs)
                           .expect("overflow when subtracting durations");
        let nanos = if self.nanos >= rhs.nanos {
            self.nanos - rhs.nanos
        } else {
            secs = secs.checked_sub(1)
                       .expect("overflow when subtracting durations");
            self.nanos + NANOS_PER_SEC - rhs.nanos
        };
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

impl Mul<u32> for Duration {
    type Output = Duration;

    fn mul(self, rhs: u32) -> Duration {
        // Multiply nanoseconds as u64, because it cannot overflow that way.
        let total_nanos = self.nanos as u64 * rhs as u64;
        let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
        let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
        let secs = self.secs.checked_mul(rhs as u64)
                       .and_then(|s| s.checked_add(extra_secs))
                       .expect("overflow when multiplying duration");
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

impl Div<u32> for Duration {
    type Output = Duration;

    fn div(self, rhs: u32) -> Duration {
        let secs = self.secs / (rhs as u64);
        let carry = self.secs - secs * (rhs as u64);
        let extra_nanos = carry * (NANOS_PER_SEC as u64) / (rhs as u64);
        let nanos = self.nanos / rhs + (extra_nanos as u32);
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

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

    #[test]
    fn creation() {
        assert!(Duration::from_secs(1) != Duration::from_secs(0));
        assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
                   Duration::from_secs(3));
        assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),
                   Duration::new(4, 10 * 1_000_000));
        assert_eq!(Duration::from_millis(4000), Duration::new(4, 0));
    }

    #[test]
    fn secs() {
        assert_eq!(Duration::new(0, 0).as_secs(), 0);
        assert_eq!(Duration::from_secs(1).as_secs(), 1);
        assert_eq!(Duration::from_millis(999).as_secs(), 0);
        assert_eq!(Duration::from_millis(1001).as_secs(), 1);
    }

    #[test]
    fn nanos() {
        assert_eq!(Duration::new(0, 0).subsec_nanos(), 0);
        assert_eq!(Duration::new(0, 5).subsec_nanos(), 5);
        assert_eq!(Duration::new(0, 1_000_000_001).subsec_nanos(), 1);
        assert_eq!(Duration::from_secs(1).subsec_nanos(), 0);
        assert_eq!(Duration::from_millis(999).subsec_nanos(), 999 * 1_000_000);
        assert_eq!(Duration::from_millis(1001).subsec_nanos(), 1 * 1_000_000);
    }

    #[test]
    fn add() {
        assert_eq!(Duration::new(0, 0) + Duration::new(0, 1),
                   Duration::new(0, 1));
        assert_eq!(Duration::new(0, 500_000_000) + Duration::new(0, 500_000_001),
                   Duration::new(1, 1));
    }

    #[test]
    fn sub() {
        assert_eq!(Duration::new(0, 1) - Duration::new(0, 0),
                   Duration::new(0, 1));
        assert_eq!(Duration::new(0, 500_000_001) - Duration::new(0, 500_000_000),
                   Duration::new(0, 1));
        assert_eq!(Duration::new(1, 0) - Duration::new(0, 1),
                   Duration::new(0, 999_999_999));
    }

    #[test] #[should_panic]
    fn sub_bad1() {
        Duration::new(0, 0) - Duration::new(0, 1);
    }

    #[test] #[should_panic]
    fn sub_bad2() {
        Duration::new(0, 0) - Duration::new(1, 0);
    }

    #[test]
    fn mul() {
        assert_eq!(Duration::new(0, 1) * 2, Duration::new(0, 2));
        assert_eq!(Duration::new(1, 1) * 3, Duration::new(3, 3));
        assert_eq!(Duration::new(0, 500_000_001) * 4, Duration::new(2, 4));
        assert_eq!(Duration::new(0, 500_000_001) * 4000,
                   Duration::new(2000, 4000));
    }

    #[test]
    fn div() {
        assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));
        assert_eq!(Duration::new(1, 1) / 3, Duration::new(0, 333_333_333));
        assert_eq!(Duration::new(99, 999_999_000) / 100,
                   Duration::new(0, 999_999_990));
    }
}
<|endoftext|>


<commit_before>use hir::AsAssocItem;
use ide_db::helpers::{
    insert_use::{insert_use, ImportScope},
    mod_path_to_ast,
};
use syntax::{ast, match_ast, ted, AstNode, SyntaxNode};

use crate::{AssistContext, AssistId, AssistKind, Assists};

// Assist: replace_qualified_name_with_use
//
// Adds a use statement for a given fully-qualified name.
//
// ```
// # mod std { pub mod collections { pub struct HashMap<T, U>(T, U); } }
// fn process(map: std::collections::$0HashMap<String, String>) {}
// ```
// ->
// ```
// use std::collections::HashMap;
//
// # mod std { pub mod collections { pub struct HashMap<T, U>(T, U); } }
// fn process(map: HashMap<String, String>) {}
// ```
pub(crate) fn replace_qualified_name_with_use(
    acc: &mut Assists,
    ctx: &AssistContext,
) -> Option<()> {
    let path: ast::Path = ctx.find_node_at_offset()?;
    // We don't want to mess with use statements
    if path.syntax().ancestors().find_map(ast::UseTree::cast).is_some() {
        cov_mark::hit!(not_applicable_in_use);
        return None;
    }

    if path.qualifier().is_none() {
        cov_mark::hit!(dont_import_trivial_paths);
        return None;
    }

    let res = ctx.sema.resolve_path(&path)?;
    let def: hir::ItemInNs = match res {
        hir::PathResolution::Def(def) if def.as_assoc_item(ctx.sema.db).is_none() => def.into(),
        hir::PathResolution::Macro(mac) => mac.into(),
        _ => return None,
    };

    let target = path.syntax().text_range();
    let scope = ImportScope::find_insert_use_container_with_macros(path.syntax(), &ctx.sema)?;
    let mod_path = ctx.sema.scope(path.syntax()).module()?.find_use_path_prefixed(
        ctx.sema.db,
        def,
        ctx.config.insert_use.prefix_kind,
    )?;
    acc.add(
        AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite),
        "Replace qualified path with use",
        target,
        |builder| {
            // Now that we've brought the name into scope, re-qualify all paths that could be
            // affected (that is, all paths inside the node we added the `use` to).
            let scope = match scope {
                ImportScope::File(it) => ImportScope::File(builder.make_mut(it)),
                ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
                ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
            };
            let path = mod_path_to_ast(&mod_path);
            shorten_paths(scope.as_syntax_node(), &path.clone_for_update());
            insert_use(&scope, path, &ctx.config.insert_use);
        },
    )
}

/// Adds replacements to `re` that shorten `path` in all descendants of `node`.
fn shorten_paths(node: &SyntaxNode, path: &ast::Path) {
    for child in node.children() {
        match_ast! {
            match child {
                // Don't modify `use` items, as this can break the `use` item when injecting a new
                // import into the use tree.
                ast::Use(_it) => continue,
                // Don't descend into submodules, they don't have the same `use` items in scope.
                // FIXME: This isn't true due to `super::*` imports?
                ast::Module(_it) => continue,
                ast::Path(p) => if maybe_replace_path(p.clone(), path.clone()).is_none() {
                    shorten_paths(p.syntax(), path);
                },
                _ => shorten_paths(&child, path),
            }
        }
    }
}

fn maybe_replace_path(path: ast::Path, target: ast::Path) -> Option<()> {
    if !path_eq_no_generics(path.clone(), target) {
        return None;
    }

    // Shorten `path`, leaving only its last segment.
    if let Some(parent) = path.qualifier() {
        ted::remove(parent.syntax());
    }
    if let Some(double_colon) = path.coloncolon_token() {
        ted::remove(&double_colon);
    }

    Some(())
}

fn path_eq_no_generics(lhs: ast::Path, rhs: ast::Path) -> bool {
    let mut lhs_curr = lhs;
    let mut rhs_curr = rhs;
    loop {
        match lhs_curr.segment().zip(rhs_curr.segment()) {
            Some((lhs, rhs))
                if lhs.coloncolon_token().is_some() == rhs.coloncolon_token().is_some()
                    && lhs
                        .name_ref()
                        .zip(rhs.name_ref())
                        .map_or(false, |(lhs, rhs)| lhs.text() == rhs.text()) =>
            {
                ()
            }
            _ => return false,
        }

        match (lhs_curr.qualifier(), rhs_curr.qualifier()) {
            (Some(lhs), Some(rhs)) => {
                lhs_curr = lhs;
                rhs_curr = rhs;
            }
            (None, None) => return true,
            _ => return false,
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable};

    use super::*;

    #[test]
    fn test_replace_already_imported() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod std { pub mod fs { pub struct Path; } }
use std::fs;

fn main() {
    std::f$0s::Path
}",
            r"
mod std { pub mod fs { pub struct Path; } }
use std::fs;

fn main() {
    fs::Path
}",
        )
    }

    #[test]
    fn test_replace_add_use_no_anchor() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod std { pub mod fs { pub struct Path; } }
std::fs::Path$0
    ",
            r"
use std::fs::Path;

mod std { pub mod fs { pub struct Path; } }
Path
    ",
        );
    }

    #[test]
    fn test_replace_add_use_no_anchor_middle_segment() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod std { pub mod fs { pub struct Path; } }
std::fs$0::Path
    ",
            r"
use std::fs;

mod std { pub mod fs { pub struct Path; } }
fs::Path
    ",
        );
    }
    #[test]
    #[test]
    fn dont_import_trivial_paths() {
        cov_mark::check!(dont_import_trivial_paths);
        check_assist_not_applicable(replace_qualified_name_with_use, r"impl foo$0 for () {}");
    }

    #[test]
    fn test_replace_not_applicable_in_use() {
        cov_mark::check!(not_applicable_in_use);
        check_assist_not_applicable(replace_qualified_name_with_use, r"use std::fmt$0;");
    }

    #[test]
    fn replaces_all_affected_paths() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod std { pub mod fmt { pub trait Debug {} } }
fn main() {
    std::fmt::Debug$0;
    let x: std::fmt::Debug = std::fmt::Debug;
}
    ",
            r"
use std::fmt::Debug;

mod std { pub mod fmt { pub trait Debug {} } }
fn main() {
    Debug;
    let x: Debug = Debug;
}
    ",
        );
    }

    #[test]
    fn does_not_replace_in_submodules() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod std { pub mod fmt { pub trait Debug {} } }
fn main() {
    std::fmt::Debug$0;
}

mod sub {
    fn f() {
        std::fmt::Debug;
    }
}
    ",
            r"
use std::fmt::Debug;

mod std { pub mod fmt { pub trait Debug {} } }
fn main() {
    Debug;
}

mod sub {
    fn f() {
        std::fmt::Debug;
    }
}
    ",
        );
    }

    #[test]
    fn does_not_replace_in_use() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod std { pub mod fmt { pub trait Display {} } }
use std::fmt::Display;

fn main() {
    std::fmt$0;
}
    ",
            r"
mod std { pub mod fmt { pub trait Display {} } }
use std::fmt::{self, Display};

fn main() {
    fmt;
}
    ",
        );
    }

    #[test]
    fn does_not_replace_assoc_item_path() {
        check_assist_not_applicable(
            replace_qualified_name_with_use,
            r"
pub struct Foo;
impl Foo {
    pub fn foo() {}
}

fn main() {
    Foo::foo$0();
}
",
        );
    }
}
<commit_msg>`replace_qualified_name_with_use` keeps qualifier for import<commit_after>use hir::AsAssocItem;
use ide_db::helpers::{
    insert_use::{insert_use, ImportScope},
    mod_path_to_ast,
};
use syntax::{
    ast::{self, make},
    match_ast, ted, AstNode, SyntaxNode,
};

use crate::{AssistContext, AssistId, AssistKind, Assists};

// Assist: replace_qualified_name_with_use
//
// Adds a use statement for a given fully-qualified name.
//
// ```
// # mod std { pub mod collections { pub struct HashMap<T, U>(T, U); } }
// fn process(map: std::collections::$0HashMap<String, String>) {}
// ```
// ->
// ```
// use std::collections::HashMap;
//
// # mod std { pub mod collections { pub struct HashMap<T, U>(T, U); } }
// fn process(map: HashMap<String, String>) {}
// ```
pub(crate) fn replace_qualified_name_with_use(
    acc: &mut Assists,
    ctx: &AssistContext,
) -> Option<()> {
    let path: ast::Path = ctx.find_node_at_offset()?;
    // We don't want to mess with use statements
    if path.syntax().ancestors().find_map(ast::UseTree::cast).is_some() {
        cov_mark::hit!(not_applicable_in_use);
        return None;
    }

    if path.qualifier().is_none() {
        cov_mark::hit!(dont_import_trivial_paths);
        return None;
    }

    // only offer replacement for non assoc items
    match ctx.sema.resolve_path(&path)? {
        hir::PathResolution::Def(def) if def.as_assoc_item(ctx.sema.db).is_none() => (),
        hir::PathResolution::Macro(_) => (),
        _ => return None,
    }
    // then search for an import for the first path segment of what we want to replace
    // that way it is less likely that we import the item from a different location due re-exports
    let module = match ctx.sema.resolve_path(&path.first_qualifier_or_self())? {
        hir::PathResolution::Def(module @ hir::ModuleDef::Module(_)) => module,
        _ => return None,
    };

    let scope = ImportScope::find_insert_use_container_with_macros(path.syntax(), &ctx.sema)?;
    let path_to_qualifier = ctx.sema.scope(path.syntax()).module()?.find_use_path_prefixed(
        ctx.sema.db,
        module,
        ctx.config.insert_use.prefix_kind,
    )?;
    let target = path.syntax().text_range();
    acc.add(
        AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite),
        "Replace qualified path with use",
        target,
        |builder| {
            // Now that we've brought the name into scope, re-qualify all paths that could be
            // affected (that is, all paths inside the node we added the `use` to).
            let scope = match scope {
                ImportScope::File(it) => ImportScope::File(builder.make_mut(it)),
                ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
                ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
            };
            // stick the found import in front of the to be replaced path
            let path = match mod_path_to_ast(&path_to_qualifier).qualifier() {
                Some(qualifier) => make::path_concat(qualifier, path),
                None => path,
            };
            shorten_paths(scope.as_syntax_node(), &path.clone_for_update());
            insert_use(&scope, path, &ctx.config.insert_use);
        },
    )
}

/// Adds replacements to `re` that shorten `path` in all descendants of `node`.
fn shorten_paths(node: &SyntaxNode, path: &ast::Path) {
    for child in node.children() {
        match_ast! {
            match child {
                // Don't modify `use` items, as this can break the `use` item when injecting a new
                // import into the use tree.
                ast::Use(_it) => continue,
                // Don't descend into submodules, they don't have the same `use` items in scope.
                // FIXME: This isn't true due to `super::*` imports?
                ast::Module(_it) => continue,
                ast::Path(p) => if maybe_replace_path(p.clone(), path.clone()).is_none() {
                    shorten_paths(p.syntax(), path);
                },
                _ => shorten_paths(&child, path),
            }
        }
    }
}

fn maybe_replace_path(path: ast::Path, target: ast::Path) -> Option<()> {
    if !path_eq_no_generics(path.clone(), target) {
        return None;
    }

    // Shorten `path`, leaving only its last segment.
    if let Some(parent) = path.qualifier() {
        ted::remove(parent.syntax());
    }
    if let Some(double_colon) = path.coloncolon_token() {
        ted::remove(&double_colon);
    }

    Some(())
}

fn path_eq_no_generics(lhs: ast::Path, rhs: ast::Path) -> bool {
    let mut lhs_curr = lhs;
    let mut rhs_curr = rhs;
    loop {
        match lhs_curr.segment().zip(rhs_curr.segment()) {
            Some((lhs, rhs))
                if lhs.coloncolon_token().is_some() == rhs.coloncolon_token().is_some()
                    && lhs
                        .name_ref()
                        .zip(rhs.name_ref())
                        .map_or(false, |(lhs, rhs)| lhs.text() == rhs.text()) =>
            {
                ()
            }
            _ => return false,
        }

        match (lhs_curr.qualifier(), rhs_curr.qualifier()) {
            (Some(lhs), Some(rhs)) => {
                lhs_curr = lhs;
                rhs_curr = rhs;
            }
            (None, None) => return true,
            _ => return false,
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable};

    use super::*;

    #[test]
    fn test_replace_already_imported() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod std { pub mod fs { pub struct Path; } }
use std::fs;

fn main() {
    std::f$0s::Path
}",
            r"
mod std { pub mod fs { pub struct Path; } }
use std::fs;

fn main() {
    fs::Path
}",
        )
    }

    #[test]
    fn test_replace_add_use_no_anchor() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod std { pub mod fs { pub struct Path; } }
std::fs::Path$0
    ",
            r"
use std::fs::Path;

mod std { pub mod fs { pub struct Path; } }
Path
    ",
        );
    }

    #[test]
    fn test_replace_add_use_no_anchor_middle_segment() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod std { pub mod fs { pub struct Path; } }
std::fs$0::Path
    ",
            r"
use std::fs;

mod std { pub mod fs { pub struct Path; } }
fs::Path
    ",
        );
    }
    #[test]
    #[test]
    fn dont_import_trivial_paths() {
        cov_mark::check!(dont_import_trivial_paths);
        check_assist_not_applicable(replace_qualified_name_with_use, r"impl foo$0 for () {}");
    }

    #[test]
    fn test_replace_not_applicable_in_use() {
        cov_mark::check!(not_applicable_in_use);
        check_assist_not_applicable(replace_qualified_name_with_use, r"use std::fmt$0;");
    }

    #[test]
    fn replaces_all_affected_paths() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod std { pub mod fmt { pub trait Debug {} } }
fn main() {
    std::fmt::Debug$0;
    let x: std::fmt::Debug = std::fmt::Debug;
}
    ",
            r"
use std::fmt::Debug;

mod std { pub mod fmt { pub trait Debug {} } }
fn main() {
    Debug;
    let x: Debug = Debug;
}
    ",
        );
    }

    #[test]
    fn does_not_replace_in_submodules() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod std { pub mod fmt { pub trait Debug {} } }
fn main() {
    std::fmt::Debug$0;
}

mod sub {
    fn f() {
        std::fmt::Debug;
    }
}
    ",
            r"
use std::fmt::Debug;

mod std { pub mod fmt { pub trait Debug {} } }
fn main() {
    Debug;
}

mod sub {
    fn f() {
        std::fmt::Debug;
    }
}
    ",
        );
    }

    #[test]
    fn does_not_replace_in_use() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod std { pub mod fmt { pub trait Display {} } }
use std::fmt::Display;

fn main() {
    std::fmt$0;
}
    ",
            r"
mod std { pub mod fmt { pub trait Display {} } }
use std::fmt::{self, Display};

fn main() {
    fmt;
}
    ",
        );
    }

    #[test]
    fn does_not_replace_assoc_item_path() {
        check_assist_not_applicable(
            replace_qualified_name_with_use,
            r"
pub struct Foo;
impl Foo {
    pub fn foo() {}
}

fn main() {
    Foo::foo$0();
}
",
        );
    }

    #[test]
    fn replace_reuses_path_qualifier() {
        check_assist(
            replace_qualified_name_with_use,
            r"
pub mod foo {
    struct Foo;
}

mod bar {
    pub use super::foo::Foo as Bar;
}

fn main() {
    foo::Foo$0;
}
",
            r"
use foo::Foo;

pub mod foo {
    struct Foo;
}

mod bar {
    pub use super::foo::Foo as Bar;
}

fn main() {
    Foo;
}
",
        );
    }
}
<|endoftext|>


<commit_before>//! Proxy engine
//!
//! This module is intended for processing incoming requests from clients,
//! handling occurred errors during a work, communicating with a message
//! broker and preparing appropriate responses in the certain format.
//!

pub mod router;
pub mod serializer;

use std::sync::{Arc, RwLock};
use std::str::{from_utf8};
use std::vec::{Vec};

use json::{parse as json_parse};
use futures::{Stream};
use futures::future::{Future};
use futures::sync::{mpsc};
use lapin_futures_rustls::lapin::types::{AMQPValue, FieldTable};
use lapin_futures_rustls::lapin::channel::{
    BasicConsumeOptions,
    BasicProperties,
    BasicPublishOptions,
    QueueDeclareOptions,
    QueueDeleteOptions,
    QueueBindOptions,
    QueueUnbindOptions,
};
use tungstenite::{Message};
use uuid::{Uuid};

pub use self::router::{Router, Endpoint, extract_endpoints};
pub use self::serializer::{Serializer, JsonMessage};

use super::cli::{CliOptions};
use super::error::{Result, PathfinderError};
use super::rabbitmq::{RabbitMQClient, RabbitMQFuture};

/// Alias type for msps sender.
pub type MessageSender = mpsc::UnboundedSender<Message>;

/// Proxy engine for processing messages, handling errors and communicating with a message broker.
pub struct Engine {
    router: Arc<RwLock<Box<Router>>>
}

impl Engine {
    /// Returns a new instance of `Engine`.
    pub fn new(cli: &CliOptions, router: Box<Router>) -> Engine {
        Engine {
            router: Arc::new(RwLock::new(router))
        }
    }

    /// TODO: Replace endpoint/queue clones onto a one struct with expected fields
    /// Main handler for generating a response per each incoming request.
    pub fn handle(&self,
                  message: JsonMessage,
                  transmitter: MessageSender,
                  rabbitmq_client: Arc<RwLock<Box<RabbitMQClient>>>
    ) -> RabbitMQFuture {
        let message_nested = message.clone();
        let url = message_nested["url"].as_str().unwrap();

        let endpoint = self.router.clone().read().unwrap().match_url_or_default(&url).read().unwrap();
        let endpoint_link = endpoint.clone();
        let endpoint_publish = endpoint.clone();
        let endpoint_unbind = endpoint.clone();

        let queue_name = Arc::new(format!("{}", Uuid::new_v4()));
        let queue_name_bind = queue_name.clone();
        let queue_name_response = queue_name.clone();
        let queue_name_consumer = queue_name.clone();
        let queue_name_unbind = queue_name.clone();
        let queue_name_delete = queue_name.clone();

        let request_headers = self.prepare_request_headers(&message_nested, endpoint.clone());
        let channel = rabbitmq_client.clone().read().unwrap().get_channel();

        Box::new(
            // 1. Create a channel
            channel

            // 2. Declare a response queue
            .and_then(move |channel| {
                let queue_declare_options = QueueDeclareOptions {
                    passive: false,
                    durable: true,
                    exclusive: true,
                    auto_delete: false,
                    ..Default::default()
                };

                channel.queue_declare(&queue_name, queue_declare_options, FieldTable::new())
                    .map(move |queue| (channel, queue))
            })

            // 3. Link the response queue the exchange
            .and_then(move |(channel, queue)| {
                channel.queue_bind(
                    &queue_name_bind,
                    &endpoint_link.get_response_exchange(),
                    &queue_name_bind,
                    QueueBindOptions::default(),
                    FieldTable::new()
                )
                    .map(move |_| (channel, queue))
            })

             // 4. Publish message into the microservice queue and make ensure that it's delivered
            .and_then(move |(channel, queue)| {
                let publish_message_options = BasicPublishOptions {
                    mandatory: true,
                    immediate: false,
                    ..Default::default()
                };

                let mut message_headers = FieldTable::new();
                for &(ref key, ref value) in request_headers.clone().iter() {
                    let header_name = key.to_string();
                    let header_value = AMQPValue::LongString(value.to_string());
                    message_headers.insert(header_name, header_value);
                }

                let event_name = message["event-name"].as_str().unwrap_or("null");

                let basic_properties = BasicProperties::default()
                    .with_content_type("application/json".to_string())    // Content type
                    .with_headers(message_headers)                        // Headers for the message
                    .with_delivery_mode(2)                                // Message must be persistent
                    .with_reply_to(queue_name_response.to_string())       // Response queue
                    .with_correlation_id(event_name.clone().to_string()); // Event name

                channel.basic_publish(
                    &endpoint_publish.get_request_exchange(),
                    &endpoint_publish.get_microservice(),
                    message["content"].dump().as_bytes().to_vec(),
                    publish_message_options,
                    basic_properties
                )
                    .map(move |_confirmation| (channel, queue))
            })

            // 5. Consume a response message from the queue, that was declared on the 2nd step
            .and_then(move |(channel, queue)| {
                channel.basic_consume(
                    &queue,
                    "response_consumer",
                    BasicConsumeOptions::default(),
                    FieldTable::new()
                )
                    .and_then(move |stream| {
                        stream.take(1)
                              .into_future()
                              .map_err(|(err, _)| err)
                              .map(move |(message, _)| (channel, queue, message.unwrap()))
                    })
            })

            // 6. Prepare a response for a client, serialize and sent via WebSocket transmitter
            .and_then(move |(channel, queue, message)| {
                let raw_data = from_utf8(&message.data).unwrap();
                let json = Arc::new(Box::new(json_parse(raw_data).unwrap()));
                let serializer = Serializer::new();
                let response = serializer.serialize(json.dump()).unwrap();
                transmitter.unbounded_send(response).unwrap();
                channel.basic_ack(message.delivery_tag, false)
                    .map(move |_confirmation| (channel, queue))
            })

            // 7. Unbind the response queue from the exchange point
            .and_then(move |(channel, queue)| {
               channel.queue_unbind(
                   &queue_name_unbind,
                   &endpoint_unbind.get_response_exchange(),
                   &endpoint_unbind.get_microservice(),
                   QueueUnbindOptions::default(),
                   FieldTable::new()
                )
                   .map(move |_| channel)
            })

            // 8. Delete the response queue
            .and_then(move |channel| {
                let queue_delete_options = QueueDeleteOptions {
                    if_unused: false,
                    if_empty: false,
                    ..Default::default()
                };

                channel.queue_delete(&queue_name_delete, queue_delete_options)
                    .map(move |_| channel)
            })

            // 9. Close the channel
            .and_then(move |channel| {
                channel.close(200, "Close the channel.")
            })

            .then(move |result| {
                match result {
                    Ok(_) => Ok(()),
                    Err(err) => {
                        error!("Error in RabbitMQ client. Reason -> {}", err);
                        let message = String::from("The request wasn't processed. Please, try once again.");
                        Err(PathfinderError::MessageBrokerError(message))
                    }
                }
            })
        )
    }

    /// Transforms an error (which is a string) into JSON object in the special format.
    pub fn wrap_an_error(&self, err: &str) -> Message {
        let json_error_message = object!("details" => err);
        let serializer = Serializer::new();
        serializer.serialize(json_error_message.dump()).unwrap()
    }

    /// Serialize a JSON object into message.
    pub fn serialize_message(&self, json: JsonMessage) -> Message {
        let serializer = Serializer::new();
        serializer.serialize(json.dump()).unwrap()
    }

    /// Deserialize a message into JSON object.
    pub fn deserialize_message(&self, message: &Message) -> Result<JsonMessage> {
        let serializer = Serializer::new();
        serializer.deserialize(message)
    }

    /// Prepares a list of key-value pairs for headers in message.
    fn prepare_request_headers(&self, json: &JsonMessage, endpoint: Box<Endpoint>) -> Box<Vec<(String, String)>> {
        Box::new(vec![
            (String::from("Microservice-Name"), endpoint.get_microservice()),
            (String::from("Request-URI"), endpoint.get_url()),
            (String::from("Event-Name"), json["event-name"].as_str().unwrap_or("null").to_string()),
            (String::from("Token"), json["token"].as_str().unwrap_or("null").to_string())
        ])
    }
}
<commit_msg>Fixed lifetime issues for the Engine struct<commit_after>//! Proxy engine
//!
//! This module is intended for processing incoming requests from clients,
//! handling occurred errors during a work, communicating with a message
//! broker and preparing appropriate responses in the certain format.
//!

pub mod router;
pub mod serializer;

use std::sync::{Arc, RwLock};
use std::str::{from_utf8};
use std::vec::{Vec};

use json::{parse as json_parse};
use futures::{Stream};
use futures::future::{Future};
use futures::sync::{mpsc};
use lapin_futures_rustls::lapin::types::{AMQPValue, FieldTable};
use lapin_futures_rustls::lapin::channel::{
    BasicConsumeOptions,
    BasicProperties,
    BasicPublishOptions,
    QueueDeclareOptions,
    QueueDeleteOptions,
    QueueBindOptions,
    QueueUnbindOptions,
};
use tungstenite::{Message};
use uuid::{Uuid};

pub use self::router::{Router, Endpoint, extract_endpoints};
pub use self::serializer::{Serializer, JsonMessage};

use super::cli::{CliOptions};
use super::error::{Result, PathfinderError};
use super::rabbitmq::{RabbitMQClient, RabbitMQFuture};

/// Alias type for msps sender.
pub type MessageSender = mpsc::UnboundedSender<Message>;

/// Proxy engine for processing messages, handling errors and communicating with a message broker.
pub struct Engine {
    router: Arc<RwLock<Box<Router>>>
}

impl Engine {
    /// Returns a new instance of `Engine`.
    pub fn new(cli: &CliOptions, router: Box<Router>) -> Engine {
        Engine {
            router: Arc::new(RwLock::new(router))
        }
    }

    /// TODO: Replace endpoint/queue clones onto a one struct with expected fields
    /// Main handler for generating a response per each incoming request.
    pub fn handle(&self,
                  message: JsonMessage,
                  transmitter: MessageSender,
                  rabbitmq_client: Arc<RwLock<Box<RabbitMQClient>>>
    ) -> RabbitMQFuture {
        let message_nested = message.clone();
        let url = message_nested["url"].as_str().unwrap();

        let router_local = self.router.clone();
        let matched_endpoint = router_local.read().unwrap().match_url_or_default(&url);
        let endpoint = matched_endpoint.read().unwrap();
        let endpoint_link = endpoint.clone();
        let endpoint_publish = endpoint.clone();
        let endpoint_unbind = endpoint.clone();

        let queue_name = Arc::new(format!("{}", Uuid::new_v4()));
        let queue_name_bind = queue_name.clone();
        let queue_name_response = queue_name.clone();
        let queue_name_consumer = queue_name.clone();
        let queue_name_unbind = queue_name.clone();
        let queue_name_delete = queue_name.clone();

        let request_headers = self.prepare_request_headers(&message_nested, endpoint.clone());
        let rabbitmq_client_local = rabbitmq_client.clone();
        let channel = rabbitmq_client_local.read().unwrap().get_channel();

        Box::new(
            // 1. Create a channel
            channel

            // 2. Declare a response queue
            .and_then(move |channel| {
                let queue_declare_options = QueueDeclareOptions {
                    passive: false,
                    durable: true,
                    exclusive: true,
                    auto_delete: false,
                    ..Default::default()
                };

                channel.queue_declare(&queue_name, queue_declare_options, FieldTable::new())
                    .map(move |queue| (channel, queue))
            })

            // 3. Link the response queue the exchange
            .and_then(move |(channel, queue)| {
                channel.queue_bind(
                    &queue_name_bind,
                    &endpoint_link.get_response_exchange(),
                    &queue_name_bind,
                    QueueBindOptions::default(),
                    FieldTable::new()
                )
                    .map(move |_| (channel, queue))
            })

             // 4. Publish message into the microservice queue and make ensure that it's delivered
            .and_then(move |(channel, queue)| {
                let publish_message_options = BasicPublishOptions {
                    mandatory: true,
                    immediate: false,
                    ..Default::default()
                };

                let mut message_headers = FieldTable::new();
                for &(ref key, ref value) in request_headers.clone().iter() {
                    let header_name = key.to_string();
                    let header_value = AMQPValue::LongString(value.to_string());
                    message_headers.insert(header_name, header_value);
                }

                let event_name = message["event-name"].as_str().unwrap_or("null");

                let basic_properties = BasicProperties::default()
                    .with_content_type("application/json".to_string())    // Content type
                    .with_headers(message_headers)                        // Headers for the message
                    .with_delivery_mode(2)                                // Message must be persistent
                    .with_reply_to(queue_name_response.to_string())       // Response queue
                    .with_correlation_id(event_name.clone().to_string()); // Event name

                channel.basic_publish(
                    &endpoint_publish.get_request_exchange(),
                    &endpoint_publish.get_microservice(),
                    message["content"].dump().as_bytes().to_vec(),
                    publish_message_options,
                    basic_properties
                )
                    .map(move |_confirmation| (channel, queue))
            })

            // 5. Consume a response message from the queue, that was declared on the 2nd step
            .and_then(move |(channel, queue)| {
                channel.basic_consume(
                    &queue,
                    "response_consumer",
                    BasicConsumeOptions::default(),
                    FieldTable::new()
                )
                    .and_then(move |stream| {
                        stream.take(1)
                              .into_future()
                              .map_err(|(err, _)| err)
                              .map(move |(message, _)| (channel, queue, message.unwrap()))
                    })
            })

            // 6. Prepare a response for a client, serialize and sent via WebSocket transmitter
            .and_then(move |(channel, queue, message)| {
                let raw_data = from_utf8(&message.data).unwrap();
                let json = Arc::new(Box::new(json_parse(raw_data).unwrap()));
                let serializer = Serializer::new();
                let response = serializer.serialize(json.dump()).unwrap();
                transmitter.unbounded_send(response).unwrap();
                channel.basic_ack(message.delivery_tag, false)
                    .map(move |_confirmation| (channel, queue))
            })

            // 7. Unbind the response queue from the exchange point
            .and_then(move |(channel, queue)| {
               channel.queue_unbind(
                   &queue_name_unbind,
                   &endpoint_unbind.get_response_exchange(),
                   &endpoint_unbind.get_microservice(),
                   QueueUnbindOptions::default(),
                   FieldTable::new()
                )
                   .map(move |_| channel)
            })

            // 8. Delete the response queue
            .and_then(move |channel| {
                let queue_delete_options = QueueDeleteOptions {
                    if_unused: false,
                    if_empty: false,
                    ..Default::default()
                };

                channel.queue_delete(&queue_name_delete, queue_delete_options)
                    .map(move |_| channel)
            })

            // 9. Close the channel
            .and_then(move |channel| {
                channel.close(200, "Close the channel.")
            })

            .then(move |result| {
                match result {
                    Ok(_) => Ok(()),
                    Err(err) => {
                        error!("Error in RabbitMQ client. Reason -> {}", err);
                        let message = String::from("The request wasn't processed. Please, try once again.");
                        Err(PathfinderError::MessageBrokerError(message))
                    }
                }
            })
        )
    }

    /// Transforms an error (which is a string) into JSON object in the special format.
    pub fn wrap_an_error(&self, err: &str) -> Message {
        let json_error_message = object!("details" => err);
        let serializer = Serializer::new();
        serializer.serialize(json_error_message.dump()).unwrap()
    }

    /// Serialize a JSON object into message.
    pub fn serialize_message(&self, json: JsonMessage) -> Message {
        let serializer = Serializer::new();
        serializer.serialize(json.dump()).unwrap()
    }

    /// Deserialize a message into JSON object.
    pub fn deserialize_message(&self, message: &Message) -> Result<JsonMessage> {
        let serializer = Serializer::new();
        serializer.deserialize(message)
    }

    /// Prepares a list of key-value pairs for headers in message.
    fn prepare_request_headers(&self, json: &JsonMessage, endpoint: Box<Endpoint>) -> Box<Vec<(String, String)>> {
        Box::new(vec![
            (String::from("Microservice-Name"), endpoint.get_microservice()),
            (String::from("Request-URI"), endpoint.get_url()),
            (String::from("Event-Name"), json["event-name"].as_str().unwrap_or("null").to_string()),
            (String::from("Token"), json["token"].as_str().unwrap_or("null").to_string())
        ])
    }
}
<|endoftext|>


<commit_before>
/// The type of merge vectors.
#[derive(Clone,Debug)]
pub struct MergeVec<T> where T: Ord {
    content: Vec<T>,                // the content changed only by user
    sort_index: Vec<usize>,         // where the sort reference is stored
    sorted: Vec<SortTarget>,        //  holes if changed
    unsorted: Vec<Option<usize>>    // new, unsorted content
}

#[derive(Clone,Copy,Debug)]
enum SortTarget {
    Content(usize),
    Unsorted(usize),
    Removed,
}

struct ContentIter<'a> {
    index: usize,
    vec: &'a Vec<SortTarget>,
}

impl<'a> Iterator for ContentIter<'a> {
    type Item = usize;
    fn next(&mut self) -> Option<usize> {
        while self.index < self.vec.len() {
            let i = self.index;
            self.index += 1;
            if let SortTarget::Content(c) = self.vec[i] {
                return Some(c);
            }
        }
        return None
    }
}

struct OpContentIter<'a> {
    index: usize,
    vec: &'a Vec<Option<usize>>,
}

impl<'a> Iterator for OpContentIter<'a> {
    type Item = usize;
    fn next(&mut self) -> Option<usize> {
        while self.index < self.vec.len() {
            let i = self.index;
            self.index += 1;
            if let Some(c) = self.vec[i] {
                return Some(c);
            }
        }
        return None
    }
}

#[derive(Clone,Debug)]
pub struct MergeVecIter<'a, T> where T: 'a {
    index: usize,
    content: &'a[T],
    sort_order: &'a[SortTarget],
}

impl<'a, T> Iterator for MergeVecIter<'a, T> where T: 'a {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        let sorted_index = self.index;
        self.index += 1;
        self.sort_order.get(sorted_index).and_then(|&target| {
            match target {
                SortTarget::Content(i) => self.content.get(i),
                _ => None
            }
        })
    }
}

impl<T> MergeVec<T> where T: Ord {
    /// The length of the vector.
    pub fn len(&self) -> usize {
        self.content.len()
    }

    /// Append an element to the end of the content.
    pub fn push(&mut self, value: T) {
        //println!("vec push index {:?}", self.len());

        let content_index = self.content.len();
        if value >= self.content[content_index] {
            // in order
            let sort_index = self.sorted.len();
            self.sort_index.push(sort_index);
            self.sorted.push(SortTarget::Content(content_index));
        } else {
            // out of order
            let new_index = self.unsorted.len();
            let sort_index = self.sorted.len();
            self.sort_index.push(sort_index);
            self.sorted.push(SortTarget::Unsorted(new_index));
            self.unsorted.push(Some(content_index));
        }
        self.content.push(value);
    }

    /// Set the `i`th element of the vector.
    /// Panics if the vector contains fewer than `i` elements.
    pub fn set(&mut self, index: usize, value: T) {
        //println!("vec set index {:?}", index);
        let sort_index = self.sort_index[index];
        let old_loc = self.sorted[sort_index];
        match old_loc {
            SortTarget::Content(_) => {
                if !self.would_be_sorted(sort_index, &value) {
                    let new_index = self.unsorted.len();
                    self.sorted[sort_index] = SortTarget::Unsorted(new_index);
                    self.unsorted.push(Some(index));
                }
            }
            SortTarget::Unsorted(unsort_index) => {
                if self.would_be_sorted(sort_index, &value) {
                    self.unsorted[unsort_index] = None;
                    self.sorted[sort_index] = SortTarget::Content(index);
                }
            }
            SortTarget::Removed => {
                if self.would_be_sorted(sort_index, &value) {
                    self.sorted[sort_index] = SortTarget::Content(index);
                } else {
                    let new_index = self.unsorted.len();
                    self.sorted[sort_index] = SortTarget::Unsorted(new_index);
                    self.unsorted.push(Some(index));
                }
            }
        }
        self.content[index] = value;
    }

    fn would_be_sorted(&self, sort_index: usize, value: &T) -> bool {
        if sort_index > 0 {
            if let SortTarget::Content(content_index) = self.sorted[sort_index - 1] {
                if self.content[content_index] > *value { return false; }
            } else {
                // TODO: Should we search through unsorted/removed values?
                return false;
            }
        }
        if sort_index < self.sorted.len() - 1 {
            if let SortTarget::Content(content_index) = self.sorted[sort_index + 1] {
                if self.content[content_index] < *value { return false; }
            } else {
                // TODO: Should we search through unsorted/removed values?
                return false;
            }
        }
        return true;
    }

    /// Truncate this vector.
    pub fn truncate(&mut self, len: usize) {
        //println!("vec truncate to {:?}", len);

        // remove all linked values
        for index in len..self.content.len() {
            let sort_index = self.sort_index[index];
            match self.sorted[sort_index] {
                SortTarget::Content(_) => self.sorted[sort_index] = SortTarget::Removed,
                SortTarget::Unsorted(unsort_index) => {
                    self.unsorted[unsort_index] = None;
                    self.sorted[sort_index] = SortTarget::Removed;
                },
                SortTarget::Removed => {}
            }
        }
        //truncate data
        self.content.truncate(len);
        self.sort_index.truncate(len);
    }

    /// Create a new, empty vector.
    pub fn new() -> MergeVec<T> {
        MergeVec {
            content: Vec::new(),
            sort_index: Vec::new(),
            sorted: Vec::new(),
            unsorted: Vec::new(),
        }
    }

    /// Consolidate incremental data, in preparation of producing a sorted iterator
    pub fn sort(&mut self) {
        self.unsorted.sort();
        let mut new_sort = Vec::with_capacity(self.content.len());
        {
            let mut a_iter = ContentIter { index: 0, vec: &self.sorted};
            let mut b_iter = OpContentIter { index: 0, vec: &self.unsorted};
            let mut op_a = a_iter.next();
            let mut op_b = b_iter.next();
            // merge
            loop {
                if let Some(index_a) = op_a {
                if let Some(index_b) = op_b {
                    if self.content[index_a] <= self.content[index_b] {
                        self.sort_index[index_a] = new_sort.len();
                        new_sort.push(SortTarget::Content(index_a));
                        op_a = a_iter.next();
                    } else {
                        self.sort_index[index_b] = new_sort.len();
                        new_sort.push(SortTarget::Content(index_b));
                        op_b = b_iter.next();
                    }
                } else { break; }
                } else { break; }
            }
            // add data from longer iter
            while let Some(index_a) = op_a {
                self.sort_index[index_a] = new_sort.len();
                new_sort.push(SortTarget::Content(index_a));
                op_a = a_iter.next();
            }
            while let Some(index_b) = op_b {
                self.sort_index[index_b] = new_sort.len();
                new_sort.push(SortTarget::Content(index_b));
                op_b = b_iter.next();
            }
        }
        //finalize vecs
        self.sorted = new_sort;
        self.unsorted = Vec::new();
    }

    pub fn sorted_iter(&mut self) -> MergeVecIter<T> {
        self.sort();
        MergeVecIter {
            index: 0,
            content: &self.content,
            sort_order: &self.sorted,
        }
    }

    /// Get the `i`th element of the vector.
    /// Returns `None` if the vector contains fewer than `i` elements.
    pub fn get(&self, index: usize) -> Option<&T> {
        self.content.get(index)
    }
}

impl<T> From<Vec<T>> for MergeVec<T> where T: Ord + Clone {
    fn from(vec: Vec<T>) -> MergeVec<T> {
        let length = vec.len();
        MergeVec {
            content: vec,
            sort_index: (0..length).collect(),
            sorted: (0..length).map(|i| SortTarget::Unsorted(i)).collect(),
            unsorted: (0..length).map(|i| Some(i)).collect(),
        }
    }
}

#[test]
fn test_push() {
    let mut vec = MergeVec::new();
    assert_eq!(vec.len(), 0);
    assert_eq!(vec.get(0), None);

    vec.push(0);
    assert_eq!(vec.len(), 1);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0]);

    vec.push(30);
    assert_eq!(vec.len(), 2);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &30]);

    vec.push(20);
    assert_eq!(vec.len(), 3);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &20, &30]);

}

#[test]
fn test_set() {
    let mut vec = MergeVec::from(vec![0, 30, 20, 10]);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &20, &30]);

}
<commit_msg>debug sort<commit_after>use std::cmp::Ordering;

/// The type of merge vectors.
#[derive(Clone,Debug)]
pub struct MergeVec<T> where T: Ord {
    content: Vec<T>,                // the content changed only by user
    sort_index: Vec<usize>,         // where the sort reference is stored
    sorted: Vec<SortTarget>,        //  holes if changed
    unsorted: Vec<Option<usize>>    // new, unsorted content
}

#[derive(Clone,Copy,Debug)]
enum SortTarget {
    Content(usize),
    Unsorted(usize),
    Removed,
}

#[derive(Debug)]
struct ContentIter<'a> {
    index: usize,
    vec: &'a Vec<SortTarget>,
}

impl<'a> Iterator for ContentIter<'a> {
    type Item = usize;
    fn next(&mut self) -> Option<usize> {
        while self.index < self.vec.len() {
            let i = self.index;
            self.index += 1;
            if let SortTarget::Content(c) = self.vec[i] {
                return Some(c);
            }
        }
        return None
    }
}

#[derive(Debug)]
struct OpContentIter<'a> {
    index: usize,
    vec: &'a Vec<Option<usize>>,
}

impl<'a> Iterator for OpContentIter<'a> {
    type Item = usize;
    fn next(&mut self) -> Option<usize> {
        while self.index < self.vec.len() {
            let i = self.index;
            self.index += 1;
            if let Some(c) = self.vec[i] {
                return Some(c);
            }
        }
        return None
    }
}

#[derive(Clone,Debug)]
pub struct MergeVecIter<'a, T> where T: 'a {
    index: usize,
    content: &'a[T],
    sort_order: &'a[SortTarget],
}

impl<'a, T> Iterator for MergeVecIter<'a, T> where T: 'a {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        let sorted_index = self.index;
        self.index += 1;
        self.sort_order.get(sorted_index).and_then(|&target| {
            match target {
                SortTarget::Content(i) => self.content.get(i),
                _ => None
            }
        })
    }
}

// borrow helper to separate the two fields into different mutability classes
fn sort_new_indexes<T: Ord>(indexes: &mut Vec<Option<usize>>, content: &Vec<T>) {
    indexes.sort_by(|&a,&b| {
        match (a, b) {
            (None, None) => Ordering::Equal,
            (None, _) => Ordering::Less,
            (_, None) => Ordering::Greater,
            (Some(a), Some(b)) => { content[a].cmp(&content[b]) }
        }
    });
}

impl<T> MergeVec<T> where T: Ord {
    /// The length of the vector.
    pub fn len(&self) -> usize {
        self.content.len()
    }

    /// Append an element to the end of the content.
    pub fn push(&mut self, value: T) {
        //println!("vec push index {:?}", self.len());

        if self.content.len() == 0 {
            // empty
            self.sort_index.push(0);
            self.sorted.push(SortTarget::Content(0));
            self.content.push(value);
            return;
        }
        let content_index = self.content.len();
        if value >= self.content[content_index - 1] {
            // in order
            let sort_index = self.sorted.len();
            self.sort_index.push(sort_index);
            self.sorted.push(SortTarget::Content(content_index));
        } else {
            // out of order
            let new_index = self.unsorted.len();
            let sort_index = self.sorted.len();
            self.sort_index.push(sort_index);
            self.sorted.push(SortTarget::Unsorted(new_index));
            self.unsorted.push(Some(content_index));
        }
        self.content.push(value);
    }

    /// Set the `i`th element of the vector.
    /// Panics if the vector contains fewer than `i` elements.
    pub fn set(&mut self, index: usize, value: T) {
        //println!("vec set index {:?}", index);
        let sort_index = self.sort_index[index];
        let old_loc = self.sorted[sort_index];
        match old_loc {
            SortTarget::Content(_) => {
                if !self.would_be_sorted(sort_index, &value) {
                    let new_index = self.unsorted.len();
                    self.sorted[sort_index] = SortTarget::Unsorted(new_index);
                    self.unsorted.push(Some(index));
                }
            }
            SortTarget::Unsorted(unsort_index) => {
                if self.would_be_sorted(sort_index, &value) {
                    self.unsorted[unsort_index] = None;
                    self.sorted[sort_index] = SortTarget::Content(index);
                }
            }
            SortTarget::Removed => {
                if self.would_be_sorted(sort_index, &value) {
                    self.sorted[sort_index] = SortTarget::Content(index);
                } else {
                    let new_index = self.unsorted.len();
                    self.sorted[sort_index] = SortTarget::Unsorted(new_index);
                    self.unsorted.push(Some(index));
                }
            }
        }
        self.content[index] = value;
    }

    fn would_be_sorted(&self, sort_index: usize, value: &T) -> bool {
        if sort_index > 0 {
            if let SortTarget::Content(content_index) = self.sorted[sort_index - 1] {
                if self.content[content_index] > *value { return false; }
            } else {
                // TODO: Should we search through unsorted/removed values?
                return false;
            }
        }
        if sort_index < self.sorted.len() - 1 {
            if let SortTarget::Content(content_index) = self.sorted[sort_index + 1] {
                if self.content[content_index] < *value { return false; }
            } else {
                // TODO: Should we search through unsorted/removed values?
                return false;
            }
        }
        return true;
    }

    /// Truncate this vector.
    pub fn truncate(&mut self, len: usize) {
        //println!("vec truncate to {:?}", len);

        // remove all linked values
        for index in len..self.content.len() {
            let sort_index = self.sort_index[index];
            match self.sorted[sort_index] {
                SortTarget::Content(_) => self.sorted[sort_index] = SortTarget::Removed,
                SortTarget::Unsorted(unsort_index) => {
                    self.unsorted[unsort_index] = None;
                    self.sorted[sort_index] = SortTarget::Removed;
                },
                SortTarget::Removed => {}
            }
        }
        //truncate data
        self.content.truncate(len);
        self.sort_index.truncate(len);
    }

    /// Create a new, empty vector.
    pub fn new() -> MergeVec<T> {
        MergeVec {
            content: Vec::new(),
            sort_index: Vec::new(),
            sorted: Vec::new(),
            unsorted: Vec::new(),
        }
    }

    /// Consolidate incremental data, in preparation of producing a sorted iterator
    pub fn sort(&mut self) {
        sort_new_indexes(&mut self.unsorted, &self.content);
        let mut new_sort = Vec::with_capacity(self.content.len());
        {
            let mut a_iter = ContentIter { index: 0, vec: &self.sorted};
            let mut b_iter = OpContentIter { index: 0, vec: &self.unsorted};
            let mut op_a = a_iter.next();
            let mut op_b = b_iter.next();
            // merge
            loop {
                if let Some(index_a) = op_a {
                if let Some(index_b) = op_b {
                    if self.content[index_a] <= self.content[index_b] {
                        self.sort_index[index_a] = new_sort.len();
                        new_sort.push(SortTarget::Content(index_a));
                        op_a = a_iter.next();
                    } else {
                        self.sort_index[index_b] = new_sort.len();
                        new_sort.push(SortTarget::Content(index_b));
                        op_b = b_iter.next();
                    }
                } else { break; }
                } else { break; }
            }
            // add data from longer iter
            while let Some(index_a) = op_a {
                self.sort_index[index_a] = new_sort.len();
                new_sort.push(SortTarget::Content(index_a));
                op_a = a_iter.next();
            }
            while let Some(index_b) = op_b {
                self.sort_index[index_b] = new_sort.len();
                new_sort.push(SortTarget::Content(index_b));
                op_b = b_iter.next();
            }
        }
        //finalize vecs
        self.sorted = new_sort;
        self.unsorted = Vec::new();

    }

    pub fn sorted_iter(&mut self) -> MergeVecIter<T> {
        self.sort();
        MergeVecIter {
            index: 0,
            content: &self.content,
            sort_order: &self.sorted,
        }
    }

    /// Get the `i`th element of the vector.
    /// Returns `None` if the vector contains fewer than `i` elements.
    pub fn get(&self, index: usize) -> Option<&T> {
        self.content.get(index)
    }
}

impl<T> From<Vec<T>> for MergeVec<T> where T: Ord + Clone {
    fn from(vec: Vec<T>) -> MergeVec<T> {
        let length = vec.len();
        MergeVec {
            content: vec,
            sort_index: (0..length).collect(),
            sorted: (0..length).map(|i| SortTarget::Unsorted(i)).collect(),
            unsorted: (0..length).map(|i| Some(i)).collect(),
        }
    }
}

#[test]
fn test_push() {
    let mut vec = MergeVec::new();
    assert_eq!(vec.len(), 0);
    assert_eq!(vec.get(0), None);

    vec.push(0);
    assert_eq!(vec.len(), 1);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0]);

    vec.push(30);
    assert_eq!(vec.len(), 2);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &30]);

    vec.push(20);
    assert_eq!(vec.len(), 3);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &20, &30]);

    assert_eq!(vec.len(), 3);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &20, &30]);

    vec.push(10);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &20, &30]);

    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &20, &30]);
}

#[test]
fn test_set() {
    let mut vec = MergeVec::from(vec![0, 30, 20, 10]);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &20, &30]);

    vec.set(2, 21);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&21));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &21, &30]);

    vec.set(2, 31);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&31));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &30, &31]);

    vec.set(2, 1);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&1));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &1, &10, &30]);
}
<|endoftext|>