<commit_before>// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/// The set of user configurable options for compiling zero or more regexes.
#[derive(Clone, Debug)]
pub struct RegexOptions {
    pub pats: Vec<String>,
    pub size_limit: usize,
    pub dfa_size_limit: usize,
    pub case_insensitive: bool,
    pub multi_line: bool,
    pub dot_matches_new_line: bool,
    pub swap_greed: bool,
    pub ignore_whitespace: bool,
    pub unicode: bool,
}

impl Default for RegexOptions {
    fn default() -> Self {
        RegexOptions {
            pats: vec![],
            size_limit: 10 * (1<<20),
            dfa_size_limit: 2 * (1<<20),
            case_insensitive: false,
            multi_line: false,
            dot_matches_new_line: false,
            swap_greed: false,
            ignore_whitespace: false,
            unicode: true,
        }
    }
}

macro_rules! define_builder {
    ($name:ident, $regex_mod:ident, $unicode:expr, $only_utf8:expr) => {
        pub mod $name {
            use error::Error;
            use exec::ExecBuilder;
            use super::RegexOptions;

            use $regex_mod::Regex;

/// A configurable builder for a regular expression.
///
/// A builder can be used to configure how the regex is built, for example, by
/// setting the default flags (which can be overridden in the expression
/// itself) or setting various limits.
pub struct RegexBuilder(RegexOptions);

impl RegexBuilder {
    /// Create a new regular expression builder with the given pattern.
    ///
    /// If the pattern is invalid, then an error will be returned when
    /// `compile` is called.
    pub fn new(pattern: &str) -> RegexBuilder {
        let mut builder = RegexBuilder(RegexOptions::default());
        builder.0.pats.push(pattern.to_owned());
        builder.0.unicode = $unicode;
        builder
    }

    /// Consume the builder and compile the regular expression.
    pub fn compile(self) -> Result<Regex, Error> {
        ExecBuilder::new_options(self.0)
            .only_utf8($only_utf8)
            .build()
            .map(Regex::from)
    }

    /// Set the value for the case insensitive (`i`) flag.
    pub fn case_insensitive(mut self, yes: bool) -> RegexBuilder {
        self.0.case_insensitive = yes;
        self
    }

    /// Set the value for the multi-line matching (`m`) flag.
    pub fn multi_line(mut self, yes: bool) -> RegexBuilder {
        self.0.multi_line = yes;
        self
    }

    /// Set the value for the any character (`s`) flag, where in `.` matches
    /// anything when `s` is set and matches anything except for new line when
    /// it is not set (the default).
    ///
    /// N.B. "matches anything" means "any byte" for `regex::bytes::Regex`
    /// expressions and means "any Unicode codepoint" for `regex::Regex`
    /// expressions.
    pub fn dot_matches_new_line(mut self, yes: bool) -> RegexBuilder {
        self.0.dot_matches_new_line = yes;
        self
    }

    /// Set the value for the greedy swap (`U`) flag.
    pub fn swap_greed(mut self, yes: bool) -> RegexBuilder {
        self.0.swap_greed = yes;
        self
    }

    /// Set the value for the ignore whitespace (`x`) flag.
    pub fn ignore_whitespace(mut self, yes: bool) -> RegexBuilder {
        self.0.ignore_whitespace = yes;
        self
    }

    /// Set the value for the Unicode (`u`) flag.
    ///
    /// For byte based regular expressions, this is disabled by default.
    pub fn unicode(mut self, yes: bool) -> RegexBuilder {
        self.0.unicode = yes;
        self
    }

    /// Set the approximate size limit of the compiled regular expression.
    ///
    /// This roughly corresponds to the number of bytes occupied by a single
    /// compiled program. If the program exceeds this number, then a
    /// compilation error is returned.
    pub fn size_limit(mut self, limit: usize) -> RegexBuilder {
        self.0.size_limit = limit;
        self
    }

    /// Set the approximate size of the cache used by the DFA.
    ///
    /// This roughly corresponds to the number of bytes that the DFA will
    /// use while searching.
    ///
    /// Note that this is a *per thread* limit. There is no way to set a global
    /// limit. In particular, if a regex is used from multiple threads
    /// simulanteously, then each thread may use up to the number of bytes
    /// specified here.
    pub fn dfa_size_limit(mut self, limit: usize) -> RegexBuilder {
        self.0.dfa_size_limit = limit;
        self
    }
}
        }
    }
}

define_builder!(bytes, re_bytes, false, false);
define_builder!(unicode, re_unicode, true, true);
<commit_msg>Explicitly state that flags aren't incorporated into the pattern string.<commit_after>// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/// The set of user configurable options for compiling zero or more regexes.
#[derive(Clone, Debug)]
pub struct RegexOptions {
    pub pats: Vec<String>,
    pub size_limit: usize,
    pub dfa_size_limit: usize,
    pub case_insensitive: bool,
    pub multi_line: bool,
    pub dot_matches_new_line: bool,
    pub swap_greed: bool,
    pub ignore_whitespace: bool,
    pub unicode: bool,
}

impl Default for RegexOptions {
    fn default() -> Self {
        RegexOptions {
            pats: vec![],
            size_limit: 10 * (1<<20),
            dfa_size_limit: 2 * (1<<20),
            case_insensitive: false,
            multi_line: false,
            dot_matches_new_line: false,
            swap_greed: false,
            ignore_whitespace: false,
            unicode: true,
        }
    }
}

macro_rules! define_builder {
    ($name:ident, $regex_mod:ident, $unicode:expr, $only_utf8:expr) => {
        pub mod $name {
            use error::Error;
            use exec::ExecBuilder;
            use super::RegexOptions;

            use $regex_mod::Regex;

/// A configurable builder for a regular expression.
///
/// A builder can be used to configure how the regex is built, for example, by
/// setting the default flags (which can be overridden in the expression
/// itself) or setting various limits.
pub struct RegexBuilder(RegexOptions);

impl RegexBuilder {
    /// Create a new regular expression builder with the given pattern.
    ///
    /// If the pattern is invalid, then an error will be returned when
    /// `compile` is called.
    pub fn new(pattern: &str) -> RegexBuilder {
        let mut builder = RegexBuilder(RegexOptions::default());
        builder.0.pats.push(pattern.to_owned());
        builder.0.unicode = $unicode;
        builder
    }

    /// Consume the builder and compile the regular expression.
    ///
    /// Note that calling `as_str` on the resulting `Regex` will produce the
    /// pattern given to `new` verbatim. Notably, it will not incorporate any
    /// of the flags set on this builder.
    pub fn compile(self) -> Result<Regex, Error> {
        ExecBuilder::new_options(self.0)
            .only_utf8($only_utf8)
            .build()
            .map(Regex::from)
    }

    /// Set the value for the case insensitive (`i`) flag.
    pub fn case_insensitive(mut self, yes: bool) -> RegexBuilder {
        self.0.case_insensitive = yes;
        self
    }

    /// Set the value for the multi-line matching (`m`) flag.
    pub fn multi_line(mut self, yes: bool) -> RegexBuilder {
        self.0.multi_line = yes;
        self
    }

    /// Set the value for the any character (`s`) flag, where in `.` matches
    /// anything when `s` is set and matches anything except for new line when
    /// it is not set (the default).
    ///
    /// N.B. "matches anything" means "any byte" for `regex::bytes::Regex`
    /// expressions and means "any Unicode codepoint" for `regex::Regex`
    /// expressions.
    pub fn dot_matches_new_line(mut self, yes: bool) -> RegexBuilder {
        self.0.dot_matches_new_line = yes;
        self
    }

    /// Set the value for the greedy swap (`U`) flag.
    pub fn swap_greed(mut self, yes: bool) -> RegexBuilder {
        self.0.swap_greed = yes;
        self
    }

    /// Set the value for the ignore whitespace (`x`) flag.
    pub fn ignore_whitespace(mut self, yes: bool) -> RegexBuilder {
        self.0.ignore_whitespace = yes;
        self
    }

    /// Set the value for the Unicode (`u`) flag.
    ///
    /// For byte based regular expressions, this is disabled by default.
    pub fn unicode(mut self, yes: bool) -> RegexBuilder {
        self.0.unicode = yes;
        self
    }

    /// Set the approximate size limit of the compiled regular expression.
    ///
    /// This roughly corresponds to the number of bytes occupied by a single
    /// compiled program. If the program exceeds this number, then a
    /// compilation error is returned.
    pub fn size_limit(mut self, limit: usize) -> RegexBuilder {
        self.0.size_limit = limit;
        self
    }

    /// Set the approximate size of the cache used by the DFA.
    ///
    /// This roughly corresponds to the number of bytes that the DFA will
    /// use while searching.
    ///
    /// Note that this is a *per thread* limit. There is no way to set a global
    /// limit. In particular, if a regex is used from multiple threads
    /// simulanteously, then each thread may use up to the number of bytes
    /// specified here.
    pub fn dfa_size_limit(mut self, limit: usize) -> RegexBuilder {
        self.0.dfa_size_limit = limit;
        self
    }
}
        }
    }
}

define_builder!(bytes, re_bytes, false, false);
define_builder!(unicode, re_unicode, true, true);
<|endoftext|>


<commit_before>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the
// terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not
// distributed with this file, You can
// obtain one at
// http://mozilla.org/MPL/2.0/.
//
// This Source Code Form is "Incompatible
// With Secondary Licenses", as defined by
// the Mozilla Public License, v. 2.0.

//! ReadBuffer crate.

use super::message::Message;

#[derive(Clone)]
pub struct ReadBuffer {
    /// Current message
    c_msg: Message,
    /// Current bytes remaining for next read
    c_remaining: u16,
    /// Current buffer
    c_buffer: Vec<u8>,
    /// Queue of messages created during last read
    queue: Vec<Message>
}

impl ReadBuffer {

    /// Creates a new ReadBuffer
    pub fn new() -> ReadBuffer {
        ReadBuffer {
            c_msg: Message::new(),
            c_remaining: 2u16,
            c_buffer: Vec::<u8>::with_capacity(2),
            queue: Vec::<Message>::new()
        }
    }

    /// Returns the number of remaining u8 needed to fill the current buffer
    pub fn remaining(&self) -> u16 {
        self.c_remaining.clone()
    }

    /// Pushes elem onto buffer
    pub fn push(&mut self, elem: u8) {
        self.c_buffer.push(elem);
        self.c_remaining -= 1;
    }

    /// Sets the buffer's capacity to size
    pub fn set_capacity(&mut self, size: u16) {
        self.c_remaining = size;
        self.c_buffer = Vec::<u8>::with_capacity(size as usize);
    }

    /// Calculates the payload len from the current buffer
    pub fn calc_payload_len(&mut self) {
        let mut len = 0u16;
        len = len | self.c_buffer[0] as u16;
        len = (len << 8) | self.c_buffer[1] as u16;
        self.c_msg.len = len;
    }

    /// Returns the total length of the expected payload
    pub fn payload_len(&self) -> u16 {
        self.c_msg.len.clone()
    }

    /// Pushes the current message into the buffer's message queue and resets
    /// to default state
    pub fn reset(&mut self) {
        self.queue.push(self.c_msg.clone());
        self.c_msg = Message::new();
        self.c_remaining = 2u16;
        self.c_buffer = Vec::<u8>::with_capacity(2);
    }

    /// Returns the length of internal message queue
    pub fn queue_len(&self) -> usize {
        self.queue.len()
    }

    /// Returns a mutable reference to the internal message queue
    pub fn queue_as_mut(&mut self) -> &mut Vec<Message> {
        &mut self.queue
    }

    /// Drains the queue returning a Vec<Vec<u8>> representing each payload
    pub fn drain_queue(&mut self) -> Vec<Vec<u8>> {
        let mut buffer = Vec::<Vec<u8>>::with_capacity(self.queue.len());
        unsafe {
            buffer.set_len(self.queue.len());
        }
        let mut pos = (self.queue.len() - 1) as isize;
        while let Some(msg) = self.queue.pop() {
            buffer.insert(pos as usize, msg.payload);
            pos -= 1;
        }
        buffer
    }
}
<commit_msg>Buffer iteration change to help with debugging<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the
// terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not
// distributed with this file, You can
// obtain one at
// http://mozilla.org/MPL/2.0/.
//
// This Source Code Form is "Incompatible
// With Secondary Licenses", as defined by
// the Mozilla Public License, v. 2.0.

//! ReadBuffer crate.

use super::message::Message;

#[derive(Clone)]
pub struct ReadBuffer {
    /// Current message
    c_msg: Message,
    /// Current bytes remaining for next read
    c_remaining: u16,
    /// Current buffer
    c_buffer: Vec<u8>,
    /// Queue of messages created during last read
    queue: Vec<Message>
}

impl ReadBuffer {

    /// Creates a new ReadBuffer
    pub fn new() -> ReadBuffer {
        ReadBuffer {
            c_msg: Message::new(),
            c_remaining: 2u16,
            c_buffer: Vec::<u8>::with_capacity(2),
            queue: Vec::<Message>::new()
        }
    }

    /// Returns the number of remaining u8 needed to fill the current buffer
    pub fn remaining(&self) -> u16 {
        self.c_remaining.clone()
    }

    /// Pushes elem onto buffer
    pub fn push(&mut self, elem: u8) {
        self.c_buffer.push(elem);
        self.c_remaining -= 1;
    }

    /// Sets the buffer's capacity to size
    pub fn set_capacity(&mut self, size: u16) {
        self.c_remaining = size;
        self.c_buffer = Vec::<u8>::with_capacity(size as usize);
    }

    /// Calculates the payload len from the current buffer
    pub fn calc_payload_len(&mut self) {
        let mut len = 0u16;
        len = len | self.c_buffer[0] as u16;
        len = (len << 8) | self.c_buffer[1] as u16;
        self.c_msg.len = len;
    }

    /// Returns the total length of the expected payload
    pub fn payload_len(&self) -> u16 {
        self.c_msg.len.clone()
    }

    /// Pushes the current message into the buffer's message queue and resets
    /// to default state
    pub fn reset(&mut self) {
        self.queue.push(self.c_msg.clone());
        self.c_msg = Message::new();
        self.c_remaining = 2u16;
        self.c_buffer = Vec::<u8>::with_capacity(2);
    }

    /// Returns the length of internal message queue
    pub fn queue_len(&self) -> usize {
        self.queue.len()
    }

    /// Returns a mutable reference to the internal message queue
    pub fn queue_as_mut(&mut self) -> &mut Vec<Message> {
        &mut self.queue
    }

    /// Drains the queue returning a Vec<Vec<u8>> representing each payload
    pub fn drain_queue(&mut self) -> Vec<Vec<u8>> {
        // let mut buffer = Vec::<Vec<u8>>::with_capacity(self.queue.len());
        // unsafe {
        //     buffer.set_len(self.queue.len());
        // }
        // let mut pos = (self.queue.len() - 1) as isize;
        // while let Some(msg) = self.queue.pop() {
        //     buffer.insert(pos as usize, msg.payload);
        //     pos -= 1;
        // }
        // buffer

        // FIXME - This is the worst.
        // I think something is wrong with the code above, so this is
        // the current, slow, approach
        let mut buffer = Vec::<Vec<u8>>::with_capacity(self.queue.len());
        for msg in self.queue.iter() {
            let payload = msg.payload.clone();
            buffer.push(payload);
        }

        self.queue = Vec::<Message>::new();
        buffer
    }
}
<|endoftext|>


<commit_before>// Copyright 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.

#![feature(test)]
#![cfg_attr(feature = "pattern", feature(core))]

extern crate regex;
extern crate test;

// Due to macro scoping rules, this definition only applies for the modules
// defined below. Effectively, it allows us to use the same tests for both
// native and dynamic regexes.
macro_rules! regex(
    ($re:expr) => (
        match ::regex::Regex::new($re) {
            Ok(re) => re,
            Err(err) => panic!("{}", err),
        }
    );
);

#[cfg(feature = "pattern")]
macro_rules! searcher_expr { ($e:expr) => ($e) }
#[cfg(not(feature = "pattern"))]
macro_rules! searcher_expr { ($e:expr) => ({}) }

mod tests;
<commit_msg>Allow testing on stable Rust<commit_after>// Copyright 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_attr(feature = "pattern", feature(core))]

extern crate regex;

// Due to macro scoping rules, this definition only applies for the modules
// defined below. Effectively, it allows us to use the same tests for both
// native and dynamic regexes.
macro_rules! regex(
    ($re:expr) => (
        match ::regex::Regex::new($re) {
            Ok(re) => re,
            Err(err) => panic!("{}", err),
        }
    );
);

#[cfg(feature = "pattern")]
macro_rules! searcher_expr { ($e:expr) => ($e) }
#[cfg(not(feature = "pattern"))]
macro_rules! searcher_expr { ($e:expr) => ({}) }

mod tests;
<|endoftext|>


<commit_before>use toml::Value;

use vcs::git::action::StoreAction;

pub fn commit_interactive(config: &Value) -> bool {
    unimplemented!()
}

pub fn commit_message(config: &Value, action: StoreAction) -> Option<String> {
    if commit_interactive(config) {
        unimplemented!()
    } else {
        unimplemented!()
    }
}
<commit_msg>Add helper to check config whether to abort the hook failing<commit_after>use toml::Value;

use vcs::git::action::StoreAction;

pub fn commit_interactive(config: &Value) -> bool {
    unimplemented!()
}

pub fn commit_message(config: &Value, action: StoreAction) -> Option<String> {
    if commit_interactive(config) {
        unimplemented!()
    } else {
        unimplemented!()
    }
}

pub fn abort_on_repo_init_err(cfg: Option<&Value>) -> bool {
    cfg.map(|cfg| {
        match cfg.lookup("abort_on_repo_init_failure") {
            Some(&Value::Boolean(b)) => b,
            Some(_) => {
                warn!("Configuration error, 'abort_on_repo_init_failure' must be a Boolean (true|false).");
                warn!("Assuming 'true' now.");
                true
            },
            None => {
                debug!("No key `abort_on_repo_init_failure' - Assuming 'true'");
                true
            },
        }
    })
    .unwrap_or(false)
}

<|endoftext|>


<commit_before>//! The state object that describes a single segment's information to visualize.

use super::{output_str, output_vec};
use livesplit_core::component::splits::State as SplitsComponentState;
use std::io::Write;
use std::os::raw::c_char;

/// type
pub type OwnedSplitsComponentState = Box<SplitsComponentState>;

/// drop
#[no_mangle]
pub extern "C" fn SplitsComponentState_drop(this: OwnedSplitsComponentState) {
    drop(this);
}

/// Describes whether a more pronounced separator should be shown in front of
/// the last segment provided.
#[no_mangle]
pub extern "C" fn SplitsComponentState_final_separator_shown(this: &SplitsComponentState) -> bool {
    this.show_final_separator
}

/// Returns the amount of segments to visualize.
#[no_mangle]
pub extern "C" fn SplitsComponentState_len(this: &SplitsComponentState) -> usize {
    this.splits.len()
}

/// Returns the amount of icon changes that happened in this state object.
#[no_mangle]
pub extern "C" fn SplitsComponentState_icon_change_count(this: &SplitsComponentState) -> usize {
    this.icon_changes.len()
}

/// Accesses the index of the segment of the icon change with the specified
/// index. This is based on the index in the run, not on the index of the
/// SplitState in the State object. The corresponding index is the index field
/// of the SplitState object. You may not provide an out of bounds index.
#[no_mangle]
pub extern "C" fn SplitsComponentState_icon_change_segment_index(
    this: &SplitsComponentState,
    icon_change_index: usize,
) -> usize {
    this.icon_changes[icon_change_index].segment_index
}

/// The icon data of the segment of the icon change with the specified index.
/// The buffer may be empty. This indicates that there is no icon. You may not
/// provide an out of bounds index.
#[no_mangle]
pub extern "C" fn SplitsComponentState_icon_change_icon_ptr(
    this: &SplitsComponentState,
    icon_change_index: usize,
) -> *const u8 {
    this.icon_changes[icon_change_index].icon.as_ptr()
}

/// The length of the icon data of the segment of the icon change with the
/// specified index.
#[no_mangle]
pub extern "C" fn SplitsComponentState_icon_change_icon_len(
    this: &SplitsComponentState,
    icon_change_index: usize,
) -> usize {
    this.icon_changes[icon_change_index].icon.len()
}

/// The name of the segment with the specified index. You may not provide an out
/// of bounds index.
#[no_mangle]
pub extern "C" fn SplitsComponentState_name(
    this: &SplitsComponentState,
    index: usize,
) -> *const c_char {
    output_str(&this.splits[index].name)
}

/// The amount of columns to visualize for the segment with the specified index.
/// The columns are specified from right to left. You may not provide an out of
/// bounds index. The amount of columns to visualize may differ from segment to
/// segment.
#[no_mangle]
pub extern "C" fn SplitsComponentState_columns_len(
    this: &SplitsComponentState,
    index: usize,
) -> usize {
    this.splits[index].columns.len()
}

/// The column's value to show for the split and column with the specified
/// index. The columns are specified from right to left. You may not provide an
/// out of bounds index.
#[no_mangle]
pub extern "C" fn SplitsComponentState_column_value(
    this: &SplitsComponentState,
    index: usize,
    column_index: usize,
) -> *const c_char {
    output_str(&this.splits[index].columns[column_index].value)
}

/// The semantic coloring information the column's value carries of the segment
/// and column with the specified index. The columns are specified from right to
/// left. You may not provide an out of bounds index.
#[no_mangle]
pub extern "C" fn SplitsComponentState_column_semantic_color(
    this: &SplitsComponentState,
    index: usize,
    column_index: usize,
) -> *const c_char {
    output_vec(|f| {
        write!(
            f,
            "{:?}",
            this.splits[index].columns[column_index].semantic_color
        )
        .unwrap()
    })
}

/// Describes if the segment with the specified index is the segment the active
/// attempt is currently on.
#[no_mangle]
pub extern "C" fn SplitsComponentState_is_current_split(
    this: &SplitsComponentState,
    index: usize,
) -> bool {
    this.splits[index].is_current_split
}
<commit_msg>Add SplitsComponentState_column_label to C API<commit_after>//! The state object that describes a single segment's information to visualize.

use super::{output_str, output_vec};
use livesplit_core::component::splits::State as SplitsComponentState;
use std::io::Write;
use std::os::raw::c_char;

/// type
pub type OwnedSplitsComponentState = Box<SplitsComponentState>;

/// drop
#[no_mangle]
pub extern "C" fn SplitsComponentState_drop(this: OwnedSplitsComponentState) {
    drop(this);
}

/// Describes whether a more pronounced separator should be shown in front of
/// the last segment provided.
#[no_mangle]
pub extern "C" fn SplitsComponentState_final_separator_shown(this: &SplitsComponentState) -> bool {
    this.show_final_separator
}

/// Returns the amount of segments to visualize.
#[no_mangle]
pub extern "C" fn SplitsComponentState_len(this: &SplitsComponentState) -> usize {
    this.splits.len()
}

/// Returns the amount of icon changes that happened in this state object.
#[no_mangle]
pub extern "C" fn SplitsComponentState_icon_change_count(this: &SplitsComponentState) -> usize {
    this.icon_changes.len()
}

/// Accesses the index of the segment of the icon change with the specified
/// index. This is based on the index in the run, not on the index of the
/// SplitState in the State object. The corresponding index is the index field
/// of the SplitState object. You may not provide an out of bounds index.
#[no_mangle]
pub extern "C" fn SplitsComponentState_icon_change_segment_index(
    this: &SplitsComponentState,
    icon_change_index: usize,
) -> usize {
    this.icon_changes[icon_change_index].segment_index
}

/// The icon data of the segment of the icon change with the specified index.
/// The buffer may be empty. This indicates that there is no icon. You may not
/// provide an out of bounds index.
#[no_mangle]
pub extern "C" fn SplitsComponentState_icon_change_icon_ptr(
    this: &SplitsComponentState,
    icon_change_index: usize,
) -> *const u8 {
    this.icon_changes[icon_change_index].icon.as_ptr()
}

/// The length of the icon data of the segment of the icon change with the
/// specified index.
#[no_mangle]
pub extern "C" fn SplitsComponentState_icon_change_icon_len(
    this: &SplitsComponentState,
    icon_change_index: usize,
) -> usize {
    this.icon_changes[icon_change_index].icon.len()
}

/// The name of the segment with the specified index. You may not provide an out
/// of bounds index.
#[no_mangle]
pub extern "C" fn SplitsComponentState_name(
    this: &SplitsComponentState,
    index: usize,
) -> *const c_char {
    output_str(&this.splits[index].name)
}

/// The amount of columns to visualize for the segment with the specified index.
/// The columns are specified from right to left. You may not provide an out of
/// bounds index. The amount of columns to visualize may differ from segment to
/// segment.
#[no_mangle]
pub extern "C" fn SplitsComponentState_columns_len(
    this: &SplitsComponentState,
    index: usize,
) -> usize {
    this.splits[index].columns.len()
}

/// The column's value to show for the split and column with the specified
/// index. The columns are specified from right to left. You may not provide an
/// out of bounds index.
#[no_mangle]
pub extern "C" fn SplitsComponentState_column_value(
    this: &SplitsComponentState,
    index: usize,
    column_index: usize,
) -> *const c_char {
    output_str(&this.splits[index].columns[column_index].value)
}

/// The semantic coloring information the column's value carries of the segment
/// and column with the specified index. The columns are specified from right to
/// left. You may not provide an out of bounds index.
#[no_mangle]
pub extern "C" fn SplitsComponentState_column_semantic_color(
    this: &SplitsComponentState,
    index: usize,
    column_index: usize,
) -> *const c_char {
    output_vec(|f| {
        write!(
            f,
            "{:?}",
            this.splits[index].columns[column_index].semantic_color
        )
        .unwrap()
    })
}

/// Describes if the segment with the specified index is the segment the active
/// attempt is currently on.
#[no_mangle]
pub extern "C" fn SplitsComponentState_is_current_split(
    this: &SplitsComponentState,
    index: usize,
) -> bool {
    this.splits[index].is_current_split
}

/// Returns the label of a specific column
#[no_mangle]
pub extern "C" fn SplitsComponentState_column_label(this: &SplitsComponentState,index: usize,) -> *const c_char {
    let labels = this.column_labels.clone();
    if labels.is_none() {
        return output_str(&"");
    }
    let hthing = &labels.unwrap()[index];
    return output_str(hthing);
}
<|endoftext|>


<commit_before>//! Matrix device identifiers.

#[cfg(feature = "rand")]
use crate::generate_localpart;

opaque_identifier! {
    /// A Matrix key ID.
    ///
    /// Device identifiers in Matrix are completely opaque character sequences. This type is
    /// provided simply for its semantic value.
    pub type DeviceId;
}

impl DeviceId {
    /// Generates a random `DeviceId`, suitable for assignment to a new device.
    #[cfg(feature = "rand")]
    #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
    pub fn new() -> Box<Self> {
        Self::from_owned(generate_localpart(8))
    }
}

opaque_identifier! {
    /// A Matrix key identifier.
    ///
    /// Key identifiers in Matrix are opaque character sequences of `[a-zA-Z_]`. This type is provided
    /// simply for its semantic value.
    pub type KeyName;
}

#[cfg(all(test, feature = "rand"))]
mod tests {
    use super::DeviceId;

    #[test]
    fn generate_device_id() {
        assert_eq!(DeviceId::new().as_str().len(), 8);
    }
}
<commit_msg>identifiers: Fix line wrapping<commit_after>//! Matrix device identifiers.

#[cfg(feature = "rand")]
use crate::generate_localpart;

opaque_identifier! {
    /// A Matrix key ID.
    ///
    /// Device identifiers in Matrix are completely opaque character sequences. This type is
    /// provided simply for its semantic value.
    pub type DeviceId;
}

impl DeviceId {
    /// Generates a random `DeviceId`, suitable for assignment to a new device.
    #[cfg(feature = "rand")]
    #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
    pub fn new() -> Box<Self> {
        Self::from_owned(generate_localpart(8))
    }
}

opaque_identifier! {
    /// A Matrix key identifier.
    ///
    /// Key identifiers in Matrix are opaque character sequences of `[a-zA-Z_]`. This type is
    /// provided simply for its semantic value.
    pub type KeyName;
}

#[cfg(all(test, feature = "rand"))]
mod tests {
    use super::DeviceId;

    #[test]
    fn generate_device_id() {
        assert_eq!(DeviceId::new().as_str().len(), 8);
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! `TimeoutAdjuster` is used to dynamically change propose timeout.

use std::fmt::Debug;

use events::Milliseconds;
use storage::Snapshot;
use blockchain::Schema;

/// `TimeoutAdjuster` trait is used to dynamically change propose timeout.
///
/// # Examples
///
/// Implementing `TimeoutAdjuster`:
///
/// ```
/// use exonum::node::State;
/// use exonum::node::timeout_adjuster::TimeoutAdjuster;
/// use exonum::events::Milliseconds;
/// use exonum::storage::Snapshot;
///
/// # #[allow(dead_code)]
/// struct CustomAdjuster {}
///
/// impl TimeoutAdjuster for CustomAdjuster {
///     fn adjust_timeout(&mut self, state: &State, _: &Snapshot) -> Milliseconds {
///         // Simply increase propose time after empty blocks.
///         if state.transactions()
///                 .read().expect("Expected read lock").is_empty() {
///             1000
///         } else {
///             200
///         }
///     }
/// }
/// ```
/// For more examples see `Constant`, `Dynamic` and `MovingAverage` implementations.
pub trait TimeoutAdjuster: Send + Debug {
    /// Called during node initialization and after accepting a new height.
    fn adjust_timeout(&mut self, view: &Snapshot) -> Milliseconds;
}

/// `Adjuster` implementation that returns value of `propose_timeout` field from `ConsensusConfig`.
#[derive(Debug)]
pub struct Constant {
    timeout: Milliseconds,
}

impl Constant {
    /// Creates a new `Constant` timeout adjuster instance with the given timeout.
    ///
    /// # Examples
    ///
    /// ```
    /// use exonum::node::timeout_adjuster::Constant;
    ///
    /// let mut adjuster = Constant::new(10);
    /// ```
    pub fn new(timeout: Milliseconds) -> Self {
        Constant { timeout }
    }
}

impl TimeoutAdjuster for Constant {
    fn adjust_timeout(&mut self, _: &Snapshot) -> Milliseconds {
        self.timeout
    }
}

/// `Adjuster` implementation that returns minimal or maximal timeout value depending on the
/// transactions amount in the previous block.
#[derive(Debug, Default)]
pub struct Dynamic {
    min: Milliseconds,
    max: Milliseconds,
    threshold: u32,
}

impl Dynamic {
    /// Creates a new `Dynamic` timeout adjuster instance with given parameters.
    ///
    /// # Examples
    ///
    /// ```
    /// use exonum::node::timeout_adjuster::Dynamic;
    ///
    /// let mut adjuster = Dynamic::new(1, 10, 100);
    /// ```
    pub fn new(min: Milliseconds, max: Milliseconds, threshold: u32) -> Self {
        Dynamic {
            min,
            max,
            threshold,
        }
    }

    fn adjust_timeout_impl(&mut self, current_load: u32) -> Milliseconds {
        if current_load >= self.threshold {
            self.min
        } else {
            self.max
        }
    }
}

impl TimeoutAdjuster for Dynamic {
    fn adjust_timeout(&mut self, snapshot: &Snapshot) -> Milliseconds {
        let schema = Schema::new(snapshot);
        let threshold = self.threshold;
        self.adjust_timeout_impl(schema.last_block().map_or(
            threshold,
            |block| block.tx_count(),
        ))
    }
}

/// Moving average timeout calculation. Initial timeout is equal to `min_timeout`.
#[derive(Debug)]
pub struct MovingAverage {
    min: f64,
    max: f64,
    adjustment_speed: f64,
    txs_block_limit: f64,
    optimal_block_load: f64,
    previous_timeout: f64,
}

impl MovingAverage {
    /// Creates `MovingAverage` that generates values between `min_timeout` and `max_timeout`.
    ///
    /// # Examples
    ///
    /// ```
    /// use exonum::node::timeout_adjuster::MovingAverage;
    ///
    /// let mut adjuster = MovingAverage::new(1, 10, 0.5, 0.75);
    /// ```
    pub fn new(
        min: Milliseconds,
        max: Milliseconds,
        adjustment_speed: f64,
        txs_block_limit: u32,
        optimal_block_load: f64,
    ) -> Self {
        MovingAverage {
            min: min as f64,
            max: max as f64,
            adjustment_speed,
            txs_block_limit: txs_block_limit as f64,
            optimal_block_load,
            previous_timeout: min as f64,
        }
    }

    fn adjust_timeout_impl(&mut self, current_load: f64) -> Milliseconds {
        let optimal_load = self.txs_block_limit * self.optimal_block_load;
        let load_percent = current_load / optimal_load;

        let target_t = if current_load < optimal_load {
            self.max - (self.max - self.previous_timeout) * load_percent
        } else {
            self.previous_timeout -
                (self.previous_timeout - self.min) * (load_percent - 1.) /
                    (1. / self.optimal_block_load - 1.)
        };

        self.previous_timeout = target_t * self.adjustment_speed +
            self.previous_timeout * (1. - self.adjustment_speed);
        self.previous_timeout.round() as Milliseconds
    }
}

impl TimeoutAdjuster for MovingAverage {
    fn adjust_timeout(&mut self, snapshot: &Snapshot) -> Milliseconds {
        let schema = Schema::new(snapshot);
        self.adjust_timeout_impl(schema.last_block().map_or(
            0.,
            |block| block.tx_count() as f64,
        ))
    }
}

#[cfg(test)]
mod tests {
    use env_logger;

    use super::*;
    use events::Milliseconds;

    #[test]
    fn dynamic_timeout_adjuster() {
        static MIN_TIMEOUT: Milliseconds = 1;
        static MAX_TIMEOUT: Milliseconds = 10;
        static THRESHOLD: u32 = 2;

        let test_data = [
            (0, MAX_TIMEOUT),
            (1, MAX_TIMEOUT),
            (2, MIN_TIMEOUT),
            (3, MIN_TIMEOUT),
            (10, MIN_TIMEOUT),
            (100, MIN_TIMEOUT),
        ];

        let mut adjuster = Dynamic::new(MIN_TIMEOUT, MAX_TIMEOUT, THRESHOLD);

        for data in &test_data {
            assert_eq!(data.1, adjuster.adjust_timeout_impl(data.0));
        }
    }

    #[test]
    fn moving_average_timeout_adjuster() {
        let _ = env_logger::init();

        static MIN_TIMEOUT: Milliseconds = 1;
        static MAX_TIMEOUT: Milliseconds = 10000;
        static TXS_BLOCK_LIMIT: f64 = 5000.;
        static TEST_COUNT: usize = 10;

        let mut adjuster =
            MovingAverage::new(MIN_TIMEOUT, MAX_TIMEOUT, 0.75, TXS_BLOCK_LIMIT as u32, 0.7);

        // Timeout should stay minimal if there are `TXS_BLOCK_LIMIT` or more transactions.
        for _ in 0..TEST_COUNT {
            assert_eq!(MIN_TIMEOUT, adjuster.adjust_timeout_impl(TXS_BLOCK_LIMIT));
        }

        for _ in 0..TEST_COUNT {
            assert_eq!(
                MIN_TIMEOUT,
                adjuster.adjust_timeout_impl(TXS_BLOCK_LIMIT * 2.)
            );
        }

        static TXS_TEST_DATA: &'static [f64] = &[
            0.,
            100.,
            200.,
            300.,
            400.,
            500.,
            1000.,
            1500.,
            2000.,
            2500.,
            3000.,
            4000.,
            4500.,
            5000.,
            5500.,
            6000.,
        ];

        // As the transaction number declines, timeout should increase until it reaches maximum.
        let mut previous_timeout = adjuster.adjust_timeout_impl(TXS_BLOCK_LIMIT);
        for transactions in TXS_TEST_DATA.iter().rev() {
            let timeout = adjuster.adjust_timeout_impl(*transactions);
            info!(
                "Timeout: current = {}, previous = {}",
                timeout,
                previous_timeout
            );
            assert!(timeout >= previous_timeout);
            previous_timeout = timeout;
        }

        // Timeout should stay maximal if there are no transactions for some time.
        for _ in 0..TEST_COUNT {
            assert_eq!(MAX_TIMEOUT, adjuster.adjust_timeout_impl(0.));
        }

        // As the transactions number increases, timeout should decrease until it reaches minimum.
        let mut previous_timeout = adjuster.adjust_timeout_impl(0.);
        for transactions in TXS_TEST_DATA {
            let timeout = adjuster.adjust_timeout_impl(*transactions);
            info!(
                "Timeout: current = {}, previous = {}",
                timeout,
                previous_timeout
            );
            assert!(timeout <= previous_timeout);
            previous_timeout = timeout;
        }
        assert_eq!(MIN_TIMEOUT, adjuster.adjust_timeout_impl(TXS_BLOCK_LIMIT));
    }
}
<commit_msg>Fix timeout adjuster doc-test<commit_after>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! `TimeoutAdjuster` is used to dynamically change propose timeout.

use std::fmt::Debug;

use events::Milliseconds;
use storage::Snapshot;
use blockchain::Schema;

/// `TimeoutAdjuster` trait is used to dynamically change propose timeout.
///
/// # Examples
///
/// Implementing `TimeoutAdjuster`:
///
/// ```
/// use exonum::node::State;
/// use exonum::node::timeout_adjuster::TimeoutAdjuster;
/// use exonum::events::Milliseconds;
/// use exonum::storage::Snapshot;
///
/// # #[allow(dead_code)]
/// struct CustomAdjuster {}
///
/// impl TimeoutAdjuster for CustomAdjuster {
///     fn adjust_timeout(&mut self, _: &Snapshot) -> Milliseconds {
///         let schema = Schema::new(snapshot);
///         let transactions = schema.last_block().map_or(0, |block| block.tx_count());
///         // Simply increase propose time after empty blocks.
///         if transactions == 0
///             1000
///         } else {
///             200
///         }
///     }
/// }
/// ```
/// For more examples see `Constant`, `Dynamic` and `MovingAverage` implementations.
pub trait TimeoutAdjuster: Send + Debug {
    /// Called during node initialization and after accepting a new height.
    fn adjust_timeout(&mut self, view: &Snapshot) -> Milliseconds;
}

/// `Adjuster` implementation that returns value of `propose_timeout` field from `ConsensusConfig`.
#[derive(Debug)]
pub struct Constant {
    timeout: Milliseconds,
}

impl Constant {
    /// Creates a new `Constant` timeout adjuster instance with the given timeout.
    ///
    /// # Examples
    ///
    /// ```
    /// use exonum::node::timeout_adjuster::Constant;
    ///
    /// let mut adjuster = Constant::new(10);
    /// ```
    pub fn new(timeout: Milliseconds) -> Self {
        Constant { timeout }
    }
}

impl TimeoutAdjuster for Constant {
    fn adjust_timeout(&mut self, _: &Snapshot) -> Milliseconds {
        self.timeout
    }
}

/// `Adjuster` implementation that returns minimal or maximal timeout value depending on the
/// transactions amount in the previous block.
#[derive(Debug, Default)]
pub struct Dynamic {
    min: Milliseconds,
    max: Milliseconds,
    threshold: u32,
}

impl Dynamic {
    /// Creates a new `Dynamic` timeout adjuster instance with given parameters.
    ///
    /// # Examples
    ///
    /// ```
    /// use exonum::node::timeout_adjuster::Dynamic;
    ///
    /// let mut adjuster = Dynamic::new(1, 10, 100);
    /// ```
    pub fn new(min: Milliseconds, max: Milliseconds, threshold: u32) -> Self {
        Dynamic {
            min,
            max,
            threshold,
        }
    }

    fn adjust_timeout_impl(&mut self, current_load: u32) -> Milliseconds {
        if current_load >= self.threshold {
            self.min
        } else {
            self.max
        }
    }
}

impl TimeoutAdjuster for Dynamic {
    fn adjust_timeout(&mut self, snapshot: &Snapshot) -> Milliseconds {
        let schema = Schema::new(snapshot);
        let threshold = self.threshold;
        self.adjust_timeout_impl(schema.last_block().map_or(
            threshold,
            |block| block.tx_count(),
        ))
    }
}

/// Moving average timeout calculation. Initial timeout is equal to `min_timeout`.
#[derive(Debug)]
pub struct MovingAverage {
    min: f64,
    max: f64,
    adjustment_speed: f64,
    txs_block_limit: f64,
    optimal_block_load: f64,
    previous_timeout: f64,
}

impl MovingAverage {
    /// Creates `MovingAverage` that generates values between `min_timeout` and `max_timeout`.
    ///
    /// # Examples
    ///
    /// ```
    /// use exonum::node::timeout_adjuster::MovingAverage;
    ///
    /// let mut adjuster = MovingAverage::new(1, 10, 0.5, 0.75);
    /// ```
    pub fn new(
        min: Milliseconds,
        max: Milliseconds,
        adjustment_speed: f64,
        txs_block_limit: u32,
        optimal_block_load: f64,
    ) -> Self {
        MovingAverage {
            min: min as f64,
            max: max as f64,
            adjustment_speed,
            txs_block_limit: txs_block_limit as f64,
            optimal_block_load,
            previous_timeout: min as f64,
        }
    }

    fn adjust_timeout_impl(&mut self, current_load: f64) -> Milliseconds {
        let optimal_load = self.txs_block_limit * self.optimal_block_load;
        let load_percent = current_load / optimal_load;

        let target_t = if current_load < optimal_load {
            self.max - (self.max - self.previous_timeout) * load_percent
        } else {
            self.previous_timeout -
                (self.previous_timeout - self.min) * (load_percent - 1.) /
                    (1. / self.optimal_block_load - 1.)
        };

        self.previous_timeout = target_t * self.adjustment_speed +
            self.previous_timeout * (1. - self.adjustment_speed);
        self.previous_timeout.round() as Milliseconds
    }
}

impl TimeoutAdjuster for MovingAverage {
    fn adjust_timeout(&mut self, snapshot: &Snapshot) -> Milliseconds {
        let schema = Schema::new(snapshot);
        self.adjust_timeout_impl(schema.last_block().map_or(
            0.,
            |block| block.tx_count() as f64,
        ))
    }
}

#[cfg(test)]
mod tests {
    use env_logger;

    use super::*;
    use events::Milliseconds;

    #[test]
    fn dynamic_timeout_adjuster() {
        static MIN_TIMEOUT: Milliseconds = 1;
        static MAX_TIMEOUT: Milliseconds = 10;
        static THRESHOLD: u32 = 2;

        let test_data = [
            (0, MAX_TIMEOUT),
            (1, MAX_TIMEOUT),
            (2, MIN_TIMEOUT),
            (3, MIN_TIMEOUT),
            (10, MIN_TIMEOUT),
            (100, MIN_TIMEOUT),
        ];

        let mut adjuster = Dynamic::new(MIN_TIMEOUT, MAX_TIMEOUT, THRESHOLD);

        for data in &test_data {
            assert_eq!(data.1, adjuster.adjust_timeout_impl(data.0));
        }
    }

    #[test]
    fn moving_average_timeout_adjuster() {
        let _ = env_logger::init();

        static MIN_TIMEOUT: Milliseconds = 1;
        static MAX_TIMEOUT: Milliseconds = 10000;
        static TXS_BLOCK_LIMIT: f64 = 5000.;
        static TEST_COUNT: usize = 10;

        let mut adjuster =
            MovingAverage::new(MIN_TIMEOUT, MAX_TIMEOUT, 0.75, TXS_BLOCK_LIMIT as u32, 0.7);

        // Timeout should stay minimal if there are `TXS_BLOCK_LIMIT` or more transactions.
        for _ in 0..TEST_COUNT {
            assert_eq!(MIN_TIMEOUT, adjuster.adjust_timeout_impl(TXS_BLOCK_LIMIT));
        }

        for _ in 0..TEST_COUNT {
            assert_eq!(
                MIN_TIMEOUT,
                adjuster.adjust_timeout_impl(TXS_BLOCK_LIMIT * 2.)
            );
        }

        static TXS_TEST_DATA: &'static [f64] = &[
            0.,
            100.,
            200.,
            300.,
            400.,
            500.,
            1000.,
            1500.,
            2000.,
            2500.,
            3000.,
            4000.,
            4500.,
            5000.,
            5500.,
            6000.,
        ];

        // As the transaction number declines, timeout should increase until it reaches maximum.
        let mut previous_timeout = adjuster.adjust_timeout_impl(TXS_BLOCK_LIMIT);
        for transactions in TXS_TEST_DATA.iter().rev() {
            let timeout = adjuster.adjust_timeout_impl(*transactions);
            info!(
                "Timeout: current = {}, previous = {}",
                timeout,
                previous_timeout
            );
            assert!(timeout >= previous_timeout);
            previous_timeout = timeout;
        }

        // Timeout should stay maximal if there are no transactions for some time.
        for _ in 0..TEST_COUNT {
            assert_eq!(MAX_TIMEOUT, adjuster.adjust_timeout_impl(0.));
        }

        // As the transactions number increases, timeout should decrease until it reaches minimum.
        let mut previous_timeout = adjuster.adjust_timeout_impl(0.);
        for transactions in TXS_TEST_DATA {
            let timeout = adjuster.adjust_timeout_impl(*transactions);
            info!(
                "Timeout: current = {}, previous = {}",
                timeout,
                previous_timeout
            );
            assert!(timeout <= previous_timeout);
            previous_timeout = timeout;
        }
        assert_eq!(MIN_TIMEOUT, adjuster.adjust_timeout_impl(TXS_BLOCK_LIMIT));
    }
}
<|endoftext|>


<commit_before>#![feature(path)]

extern crate graphics;
extern crate "freetype" as ft;
extern crate sdl2_window;
extern crate opengl_graphics;
extern crate piston;

use std::cell::RefCell;
use sdl2_window::Sdl2Window;
use opengl_graphics::{
    Gl,
    Texture,
    OpenGL
};
use graphics::{
    Context,
    Image,
    RelativeTransform,
    color
};
use piston::window::WindowSettings;
use piston::event::Event;

fn render_text(face: &mut ft::Face, gl: &mut Gl, c: &Context, text: &str) {
    let mut x = 0;
    let mut y = 0;
    for ch in text.chars() {
        face.load_char(ch as usize, ft::face::RENDER).unwrap();
        let g = face.glyph();

        let bitmap = g.bitmap();
        let texture = Texture::from_memory_alpha(bitmap.buffer(),
            bitmap.width() as u32, bitmap.rows() as u32).unwrap();
        Image::colored(color::BLACK).draw(
            &texture,
            &c.trans((x + g.bitmap_left()) as f64, (y - g.bitmap_top()) as f64),
            gl
        );

        x += (g.advance().x >> 6) as i32;
        y += (g.advance().y >> 6) as i32;
    }
}

fn main() {
    let opengl = OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: "Font with Piston".to_string(),
            size: [300, 300],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let freetype = ft::Library::init().unwrap();
    let font = Path::new("./examples/assets/Arial.ttf");
    let mut face = freetype.new_face(&font, 0).unwrap();
    face.set_pixel_sizes(0, 48).unwrap();

    let ref mut gl = Gl::new(opengl);

    let window = RefCell::new(window);
    for e in piston::events(&window) {
        match e {
            Event::Render(args) => {
                let c = Context::abs(args.width as f64, args.height as f64);
                graphics::clear([1.0, 1.0, 1.0, 1.0], gl);
                render_text(&mut face, gl, &c.trans(0.0, 100.0), "Hello Piston!");
            },
            _ => ()
        }
    }
}

<commit_msg>Fix example font_with_piston: enable alpha blending<commit_after>#![feature(path)]

extern crate graphics;
extern crate "freetype" as ft;
extern crate sdl2_window;
extern crate opengl_graphics;
extern crate piston;

use std::cell::RefCell;
use sdl2_window::Sdl2Window;
use opengl_graphics::{
    Gl,
    Texture,
    OpenGL
};
use graphics::{
    Context,
    Image,
    RelativeTransform,
    color
};
use piston::window::WindowSettings;
use piston::event::Event;

fn render_text(face: &mut ft::Face, gl: &mut Gl, c: &Context, text: &str) {
    let mut x = 0;
    let mut y = 0;
    for ch in text.chars() {
        face.load_char(ch as usize, ft::face::RENDER).unwrap();
        let g = face.glyph();

        let bitmap = g.bitmap();
        let texture = Texture::from_memory_alpha(bitmap.buffer(),
                                                 bitmap.width() as u32,
                                                 bitmap.rows() as u32).unwrap();
        Image::colored(color::BLACK).draw(
            &texture,
            &c.trans((x + g.bitmap_left()) as f64, (y - g.bitmap_top()) as f64),
            gl
        );

        x += (g.advance().x >> 6) as i32;
        y += (g.advance().y >> 6) as i32;
    }
}

fn main() {
    let opengl = OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: "Font with Piston".to_string(),
            size: [300, 300],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let freetype = ft::Library::init().unwrap();
    let font = Path::new("./examples/assets/Arial.ttf");
    let mut face = freetype.new_face(&font, 0).unwrap();
    face.set_pixel_sizes(0, 48).unwrap();

    let ref mut gl = Gl::new(opengl);

    let window = RefCell::new(window);
    for e in piston::events(&window) {
        match e {
            Event::Render(args) => {
                gl.draw([0, 0, args.width as i32, args.height as i32], |c, gl| {
                    graphics::clear(color::WHITE, gl);
                    render_text(&mut face, gl, &c.trans(0.0, 100.0), "Hello Piston!");
                });
            },
            _ => ()
        }
    }
}

<|endoftext|>


<commit_before>use crate::fmt;
use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map};
use crate::ops::Try;

/// An iterator that maps each element to an iterator, and yields the elements
/// of the produced iterators.
///
/// This `struct` is created by [`Iterator::flat_map`]. See its documentation
/// for more.
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct FlatMap<I, U: IntoIterator, F> {
    inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>,
}

impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
    pub(in crate::iter) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
        FlatMap { inner: FlattenCompat::new(iter.map(f)) }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Clone, U, F: Clone> Clone for FlatMap<I, U, F>
where
    U: Clone + IntoIterator<IntoIter: Clone>,
{
    fn clone(&self) -> Self {
        FlatMap { inner: self.inner.clone() }
    }
}

#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<I: fmt::Debug, U, F> fmt::Debug for FlatMap<I, U, F>
where
    U: IntoIterator<IntoIter: fmt::Debug>,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("FlatMap").field("inner", &self.inner).finish()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
where
    F: FnMut(I::Item) -> U,
{
    type Item = U::Item;

    #[inline]
    fn next(&mut self) -> Option<U::Item> {
        self.inner.next()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }

    #[inline]
    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        self.inner.try_fold(init, fold)
    }

    #[inline]
    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        self.inner.fold(init, fold)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
where
    F: FnMut(I::Item) -> U,
    U: IntoIterator<IntoIter: DoubleEndedIterator>,
{
    #[inline]
    fn next_back(&mut self) -> Option<U::Item> {
        self.inner.next_back()
    }

    #[inline]
    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        self.inner.try_rfold(init, fold)
    }

    #[inline]
    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        self.inner.rfold(init, fold)
    }
}

#[stable(feature = "fused", since = "1.26.0")]
impl<I, U, F> FusedIterator for FlatMap<I, U, F>
where
    I: FusedIterator,
    U: IntoIterator,
    F: FnMut(I::Item) -> U,
{
}

/// An iterator that flattens one level of nesting in an iterator of things
/// that can be turned into iterators.
///
/// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`flatten`]: Iterator::flatten()
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "iterator_flatten", since = "1.29.0")]
pub struct Flatten<I: Iterator<Item: IntoIterator>> {
    inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
}

impl<I: Iterator<Item: IntoIterator>> Flatten<I> {
    pub(in super::super) fn new(iter: I) -> Flatten<I> {
        Flatten { inner: FlattenCompat::new(iter) }
    }
}

#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> fmt::Debug for Flatten<I>
where
    I: fmt::Debug + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: fmt::Debug + Iterator,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Flatten").field("inner", &self.inner).finish()
    }
}

#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> Clone for Flatten<I>
where
    I: Clone + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: Clone + Iterator,
{
    fn clone(&self) -> Self {
        Flatten { inner: self.inner.clone() }
    }
}

#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> Iterator for Flatten<I>
where
    I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: Iterator,
{
    type Item = U::Item;

    #[inline]
    fn next(&mut self) -> Option<U::Item> {
        self.inner.next()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }

    #[inline]
    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        self.inner.try_fold(init, fold)
    }

    #[inline]
    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        self.inner.fold(init, fold)
    }
}

#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> DoubleEndedIterator for Flatten<I>
where
    I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: DoubleEndedIterator,
{
    #[inline]
    fn next_back(&mut self) -> Option<U::Item> {
        self.inner.next_back()
    }

    #[inline]
    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        self.inner.try_rfold(init, fold)
    }

    #[inline]
    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        self.inner.rfold(init, fold)
    }
}

#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> FusedIterator for Flatten<I>
where
    I: FusedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: Iterator,
{
}

/// Real logic of both `Flatten` and `FlatMap` which simply delegate to
/// this type.
#[derive(Clone, Debug)]
struct FlattenCompat<I, U> {
    iter: Fuse<I>,
    frontiter: Option<U>,
    backiter: Option<U>,
}
impl<I, U> FlattenCompat<I, U>
where
    I: Iterator,
{
    /// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
    fn new(iter: I) -> FlattenCompat<I, U> {
        FlattenCompat { iter: iter.fuse(), frontiter: None, backiter: None }
    }
}

impl<I, U> Iterator for FlattenCompat<I, U>
where
    I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: Iterator,
{
    type Item = U::Item;

    #[inline]
    fn next(&mut self) -> Option<U::Item> {
        loop {
            if let Some(ref mut inner) = self.frontiter {
                match inner.next() {
                    None => self.frontiter = None,
                    elt @ Some(_) => return elt,
                }
            }
            match self.iter.next() {
                None => match self.backiter.as_mut()?.next() {
                    None => {
                        self.backiter = None;
                        return None;
                    }
                    elt @ Some(_) => return elt,
                },
                Some(inner) => self.frontiter = Some(inner.into_iter()),
            }
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
        let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
        let lo = flo.saturating_add(blo);
        match (self.iter.size_hint(), fhi, bhi) {
            ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
            _ => (lo, None),
        }
    }

    #[inline]
    fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        #[inline]
        fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
            frontiter: &'a mut Option<T::IntoIter>,
            fold: &'a mut impl FnMut(Acc, T::Item) -> R,
        ) -> impl FnMut(Acc, T) -> R + 'a {
            move |acc, x| {
                let mut mid = x.into_iter();
                let r = mid.try_fold(acc, &mut *fold);
                *frontiter = Some(mid);
                r
            }
        }

        if let Some(ref mut front) = self.frontiter {
            init = front.try_fold(init, &mut fold)?;
        }
        self.frontiter = None;

        init = self.iter.try_fold(init, flatten(&mut self.frontiter, &mut fold))?;
        self.frontiter = None;

        if let Some(ref mut back) = self.backiter {
            init = back.try_fold(init, &mut fold)?;
        }
        self.backiter = None;

        try { init }
    }

    #[inline]
    fn fold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        #[inline]
        fn flatten<U: Iterator, Acc>(
            fold: &mut impl FnMut(Acc, U::Item) -> Acc,
        ) -> impl FnMut(Acc, U) -> Acc + '_ {
            move |acc, iter| iter.fold(acc, &mut *fold)
        }

        self.frontiter
            .into_iter()
            .chain(self.iter.map(IntoIterator::into_iter))
            .chain(self.backiter)
            .fold(init, flatten(fold))
    }
}

impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
where
    I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: DoubleEndedIterator,
{
    #[inline]
    fn next_back(&mut self) -> Option<U::Item> {
        loop {
            if let Some(ref mut inner) = self.backiter {
                match inner.next_back() {
                    None => self.backiter = None,
                    elt @ Some(_) => return elt,
                }
            }
            match self.iter.next_back() {
                None => match self.frontiter.as_mut()?.next_back() {
                    None => {
                        self.frontiter = None;
                        return None;
                    }
                    elt @ Some(_) => return elt,
                },
                next => self.backiter = next.map(IntoIterator::into_iter),
            }
        }
    }

    #[inline]
    fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        #[inline]
        fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
            backiter: &'a mut Option<T::IntoIter>,
            fold: &'a mut impl FnMut(Acc, T::Item) -> R,
        ) -> impl FnMut(Acc, T) -> R + 'a
        where
            T::IntoIter: DoubleEndedIterator,
        {
            move |acc, x| {
                let mut mid = x.into_iter();
                let r = mid.try_rfold(acc, &mut *fold);
                *backiter = Some(mid);
                r
            }
        }

        if let Some(ref mut back) = self.backiter {
            init = back.try_rfold(init, &mut fold)?;
        }
        self.backiter = None;

        init = self.iter.try_rfold(init, flatten(&mut self.backiter, &mut fold))?;
        self.backiter = None;

        if let Some(ref mut front) = self.frontiter {
            init = front.try_rfold(init, &mut fold)?;
        }
        self.frontiter = None;

        try { init }
    }

    #[inline]
    fn rfold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        #[inline]
        fn flatten<U: DoubleEndedIterator, Acc>(
            fold: &mut impl FnMut(Acc, U::Item) -> Acc,
        ) -> impl FnMut(Acc, U) -> Acc + '_ {
            move |acc, iter| iter.rfold(acc, &mut *fold)
        }

        self.frontiter
            .into_iter()
            .chain(self.iter.map(IntoIterator::into_iter))
            .chain(self.backiter)
            .rfold(init, flatten(fold))
    }
}
<commit_msg>Auto merge of #82162 - cuviper:flat-fold, r=Mark-Simulacrum<commit_after>use crate::fmt;
use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map};
use crate::ops::Try;

/// An iterator that maps each element to an iterator, and yields the elements
/// of the produced iterators.
///
/// This `struct` is created by [`Iterator::flat_map`]. See its documentation
/// for more.
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct FlatMap<I, U: IntoIterator, F> {
    inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>,
}

impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
    pub(in crate::iter) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
        FlatMap { inner: FlattenCompat::new(iter.map(f)) }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Clone, U, F: Clone> Clone for FlatMap<I, U, F>
where
    U: Clone + IntoIterator<IntoIter: Clone>,
{
    fn clone(&self) -> Self {
        FlatMap { inner: self.inner.clone() }
    }
}

#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<I: fmt::Debug, U, F> fmt::Debug for FlatMap<I, U, F>
where
    U: IntoIterator<IntoIter: fmt::Debug>,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("FlatMap").field("inner", &self.inner).finish()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
where
    F: FnMut(I::Item) -> U,
{
    type Item = U::Item;

    #[inline]
    fn next(&mut self) -> Option<U::Item> {
        self.inner.next()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }

    #[inline]
    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        self.inner.try_fold(init, fold)
    }

    #[inline]
    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        self.inner.fold(init, fold)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
where
    F: FnMut(I::Item) -> U,
    U: IntoIterator<IntoIter: DoubleEndedIterator>,
{
    #[inline]
    fn next_back(&mut self) -> Option<U::Item> {
        self.inner.next_back()
    }

    #[inline]
    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        self.inner.try_rfold(init, fold)
    }

    #[inline]
    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        self.inner.rfold(init, fold)
    }
}

#[stable(feature = "fused", since = "1.26.0")]
impl<I, U, F> FusedIterator for FlatMap<I, U, F>
where
    I: FusedIterator,
    U: IntoIterator,
    F: FnMut(I::Item) -> U,
{
}

/// An iterator that flattens one level of nesting in an iterator of things
/// that can be turned into iterators.
///
/// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`flatten`]: Iterator::flatten()
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "iterator_flatten", since = "1.29.0")]
pub struct Flatten<I: Iterator<Item: IntoIterator>> {
    inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
}

impl<I: Iterator<Item: IntoIterator>> Flatten<I> {
    pub(in super::super) fn new(iter: I) -> Flatten<I> {
        Flatten { inner: FlattenCompat::new(iter) }
    }
}

#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> fmt::Debug for Flatten<I>
where
    I: fmt::Debug + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: fmt::Debug + Iterator,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Flatten").field("inner", &self.inner).finish()
    }
}

#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> Clone for Flatten<I>
where
    I: Clone + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: Clone + Iterator,
{
    fn clone(&self) -> Self {
        Flatten { inner: self.inner.clone() }
    }
}

#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> Iterator for Flatten<I>
where
    I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: Iterator,
{
    type Item = U::Item;

    #[inline]
    fn next(&mut self) -> Option<U::Item> {
        self.inner.next()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }

    #[inline]
    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        self.inner.try_fold(init, fold)
    }

    #[inline]
    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        self.inner.fold(init, fold)
    }
}

#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> DoubleEndedIterator for Flatten<I>
where
    I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: DoubleEndedIterator,
{
    #[inline]
    fn next_back(&mut self) -> Option<U::Item> {
        self.inner.next_back()
    }

    #[inline]
    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        self.inner.try_rfold(init, fold)
    }

    #[inline]
    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        self.inner.rfold(init, fold)
    }
}

#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> FusedIterator for Flatten<I>
where
    I: FusedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: Iterator,
{
}

/// Real logic of both `Flatten` and `FlatMap` which simply delegate to
/// this type.
#[derive(Clone, Debug)]
struct FlattenCompat<I, U> {
    iter: Fuse<I>,
    frontiter: Option<U>,
    backiter: Option<U>,
}
impl<I, U> FlattenCompat<I, U>
where
    I: Iterator,
{
    /// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
    fn new(iter: I) -> FlattenCompat<I, U> {
        FlattenCompat { iter: iter.fuse(), frontiter: None, backiter: None }
    }
}

impl<I, U> Iterator for FlattenCompat<I, U>
where
    I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: Iterator,
{
    type Item = U::Item;

    #[inline]
    fn next(&mut self) -> Option<U::Item> {
        loop {
            if let Some(ref mut inner) = self.frontiter {
                match inner.next() {
                    None => self.frontiter = None,
                    elt @ Some(_) => return elt,
                }
            }
            match self.iter.next() {
                None => match self.backiter.as_mut()?.next() {
                    None => {
                        self.backiter = None;
                        return None;
                    }
                    elt @ Some(_) => return elt,
                },
                Some(inner) => self.frontiter = Some(inner.into_iter()),
            }
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
        let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
        let lo = flo.saturating_add(blo);
        match (self.iter.size_hint(), fhi, bhi) {
            ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
            _ => (lo, None),
        }
    }

    #[inline]
    fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        #[inline]
        fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
            frontiter: &'a mut Option<T::IntoIter>,
            fold: &'a mut impl FnMut(Acc, T::Item) -> R,
        ) -> impl FnMut(Acc, T) -> R + 'a {
            move |acc, x| {
                let mut mid = x.into_iter();
                let r = mid.try_fold(acc, &mut *fold);
                *frontiter = Some(mid);
                r
            }
        }

        if let Some(ref mut front) = self.frontiter {
            init = front.try_fold(init, &mut fold)?;
        }
        self.frontiter = None;

        init = self.iter.try_fold(init, flatten(&mut self.frontiter, &mut fold))?;
        self.frontiter = None;

        if let Some(ref mut back) = self.backiter {
            init = back.try_fold(init, &mut fold)?;
        }
        self.backiter = None;

        try { init }
    }

    #[inline]
    fn fold<Acc, Fold>(self, mut init: Acc, mut fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        #[inline]
        fn flatten<T: IntoIterator, Acc>(
            fold: &mut impl FnMut(Acc, T::Item) -> Acc,
        ) -> impl FnMut(Acc, T) -> Acc + '_ {
            move |acc, x| x.into_iter().fold(acc, &mut *fold)
        }

        if let Some(front) = self.frontiter {
            init = front.fold(init, &mut fold);
        }

        init = self.iter.fold(init, flatten(&mut fold));

        if let Some(back) = self.backiter {
            init = back.fold(init, &mut fold);
        }

        init
    }
}

impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
where
    I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: DoubleEndedIterator,
{
    #[inline]
    fn next_back(&mut self) -> Option<U::Item> {
        loop {
            if let Some(ref mut inner) = self.backiter {
                match inner.next_back() {
                    None => self.backiter = None,
                    elt @ Some(_) => return elt,
                }
            }
            match self.iter.next_back() {
                None => match self.frontiter.as_mut()?.next_back() {
                    None => {
                        self.frontiter = None;
                        return None;
                    }
                    elt @ Some(_) => return elt,
                },
                next => self.backiter = next.map(IntoIterator::into_iter),
            }
        }
    }

    #[inline]
    fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        #[inline]
        fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
            backiter: &'a mut Option<T::IntoIter>,
            fold: &'a mut impl FnMut(Acc, T::Item) -> R,
        ) -> impl FnMut(Acc, T) -> R + 'a
        where
            T::IntoIter: DoubleEndedIterator,
        {
            move |acc, x| {
                let mut mid = x.into_iter();
                let r = mid.try_rfold(acc, &mut *fold);
                *backiter = Some(mid);
                r
            }
        }

        if let Some(ref mut back) = self.backiter {
            init = back.try_rfold(init, &mut fold)?;
        }
        self.backiter = None;

        init = self.iter.try_rfold(init, flatten(&mut self.backiter, &mut fold))?;
        self.backiter = None;

        if let Some(ref mut front) = self.frontiter {
            init = front.try_rfold(init, &mut fold)?;
        }
        self.frontiter = None;

        try { init }
    }

    #[inline]
    fn rfold<Acc, Fold>(self, mut init: Acc, mut fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        #[inline]
        fn flatten<T: IntoIterator, Acc>(
            fold: &mut impl FnMut(Acc, T::Item) -> Acc,
        ) -> impl FnMut(Acc, T) -> Acc + '_
        where
            T::IntoIter: DoubleEndedIterator,
        {
            move |acc, x| x.into_iter().rfold(acc, &mut *fold)
        }

        if let Some(back) = self.backiter {
            init = back.rfold(init, &mut fold);
        }

        init = self.iter.rfold(init, flatten(&mut fold));

        if let Some(front) = self.frontiter {
            init = front.rfold(init, &mut fold);
        }

        init
    }
}
<|endoftext|>


<commit_before>use crate::ffi::OsString;
use crate::sys::windows::args::*;

fn chk(string: &str, parts: &[&str]) {
    let mut wide: Vec<u16> = OsString::from(string).encode_wide().collect();
    wide.push(0);
    let parsed =
        unsafe { parse_lp_cmd_line(wide.as_ptr() as *const u16, || OsString::from("TEST.EXE")) };
    let expected: Vec<OsString> = parts.iter().map(|k| OsString::from(k)).collect();
    assert_eq!(parsed.as_slice(), expected.as_slice());
}

#[test]
fn empty() {
    chk("", &["TEST.EXE"]);
    chk("\0", &["TEST.EXE"]);
}

#[test]
fn single_words() {
    chk("EXE one_word", &["EXE", "one_word"]);
    chk("EXE a", &["EXE", "a"]);
    chk("EXE 😅", &["EXE", "😅"]);
    chk("EXE 😅🤦", &["EXE", "😅🤦"]);
}

#[test]
fn official_examples() {
    chk(r#"EXE "abc" d e"#, &["EXE", "abc", "d", "e"]);
    chk(r#"EXE a\\\b d"e f"g h"#, &["EXE", r#"a\\\b"#, "de fg", "h"]);
    chk(r#"EXE a\\\"b c d"#, &["EXE", r#"a\"b"#, "c", "d"]);
    chk(r#"EXE a\\\\"b c" d e"#, &["EXE", r#"a\\b c"#, "d", "e"]);
}

#[test]
fn whitespace_behavior() {
    chk(r#" test"#, &["", "test"]);
    chk(r#"  test"#, &["", "test"]);
    chk(r#" test test2"#, &["", "test", "test2"]);
    chk(r#" test  test2"#, &["", "test", "test2"]);
    chk(r#"test test2 "#, &["test", "test2"]);
    chk(r#"test  test2 "#, &["test", "test2"]);
    chk(r#"test "#, &["test"]);
}

#[test]
fn genius_quotes() {
    chk(r#"EXE "" """#, &["EXE", "", ""]);
    chk(r#"EXE "" """"#, &["EXE", "", "\""]);
    chk(
        r#"EXE "this is """all""" in the same argument""#,
        &["EXE", "this is \"all\" in the same argument"],
    );
    chk(r#"EXE "a"""#, &["EXE", "a\""]);
    chk(r#"EXE "a"" a"#, &["EXE", "a\"", "a"]);
    // quotes cannot be escaped in command names
    chk(r#""EXE" check"#, &["EXE", "check"]);
    chk(r#""EXE check""#, &["EXE check"]);
    chk(r#""EXE """for""" check"#, &["EXE ", r#"for""#, "check"]);
    chk(r#""EXE \"for\" check"#, &[r#"EXE \"#, r#"for""#, "check"]);
}
<commit_msg>Update Windows arg parsing tests<commit_after>use crate::ffi::OsString;
use crate::sys::windows::args::*;

fn chk(string: &str, parts: &[&str]) {
    let mut wide: Vec<u16> = OsString::from(string).encode_wide().collect();
    wide.push(0);
    let parsed =
        unsafe { parse_lp_cmd_line(WStrUnits::new(wide.as_ptr()), || OsString::from("TEST.EXE")) };
    let expected: Vec<OsString> = parts.iter().map(|k| OsString::from(k)).collect();
    assert_eq!(parsed.as_slice(), expected.as_slice(), "{:?}", string);
}

#[test]
fn empty() {
    chk("", &["TEST.EXE"]);
    chk("\0", &["TEST.EXE"]);
}

#[test]
fn single_words() {
    chk("EXE one_word", &["EXE", "one_word"]);
    chk("EXE a", &["EXE", "a"]);
    chk("EXE 😅", &["EXE", "😅"]);
    chk("EXE 😅🤦", &["EXE", "😅🤦"]);
}

#[test]
fn official_examples() {
    chk(r#"EXE "abc" d e"#, &["EXE", "abc", "d", "e"]);
    chk(r#"EXE a\\\b d"e f"g h"#, &["EXE", r"a\\\b", "de fg", "h"]);
    chk(r#"EXE a\\\"b c d"#, &["EXE", r#"a\"b"#, "c", "d"]);
    chk(r#"EXE a\\\\"b c" d e"#, &["EXE", r"a\\b c", "d", "e"]);
}

#[test]
fn whitespace_behavior() {
    chk(" test", &["", "test"]);
    chk("  test", &["", "test"]);
    chk(" test test2", &["", "test", "test2"]);
    chk(" test  test2", &["", "test", "test2"]);
    chk("test test2 ", &["test", "test2"]);
    chk("test  test2 ", &["test", "test2"]);
    chk("test ", &["test"]);
}

#[test]
fn genius_quotes() {
    chk(r#"EXE "" """#, &["EXE", "", ""]);
    chk(r#"EXE "" """"#, &["EXE", "", r#"""#]);
    chk(
        r#"EXE "this is """all""" in the same argument""#,
        &["EXE", r#"this is "all" in the same argument"#],
    );
    chk(r#"EXE "a"""#, &["EXE", r#"a""#]);
    chk(r#"EXE "a"" a"#, &["EXE", r#"a" a"#]);
    // quotes cannot be escaped in command names
    chk(r#""EXE" check"#, &["EXE", "check"]);
    chk(r#""EXE check""#, &["EXE check"]);
    chk(r#""EXE """for""" check"#, &["EXE for check"]);
    chk(r#""EXE \"for\" check"#, &[r"EXE \for\ check"]);
    chk(r#""EXE \" for \" check"#, &[r"EXE \", "for", r#"""#, "check"]);
    chk(r#"E"X"E test"#, &["EXE", "test"]);
    chk(r#"EX""E test"#, &["EXE", "test"]);
}

// from https://daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESEX
#[test]
fn post_2008() {
    chk("EXE CallMeIshmael", &["EXE", "CallMeIshmael"]);
    chk(r#"EXE "Call Me Ishmael""#, &["EXE", "Call Me Ishmael"]);
    chk(r#"EXE Cal"l Me I"shmael"#, &["EXE", "Call Me Ishmael"]);
    chk(r#"EXE CallMe\"Ishmael"#, &["EXE", r#"CallMe"Ishmael"#]);
    chk(r#"EXE "CallMe\"Ishmael""#, &["EXE", r#"CallMe"Ishmael"#]);
    chk(r#"EXE "Call Me Ishmael\\""#, &["EXE", r"Call Me Ishmael\"]);
    chk(r#"EXE "CallMe\\\"Ishmael""#, &["EXE", r#"CallMe\"Ishmael"#]);
    chk(r#"EXE a\\\b"#, &["EXE", r"a\\\b"]);
    chk(r#"EXE "a\\\b""#, &["EXE", r"a\\\b"]);
    chk(r#"EXE "\"Call Me Ishmael\"""#, &["EXE", r#""Call Me Ishmael""#]);
    chk(r#"EXE "C:\TEST A\\""#, &["EXE", r"C:\TEST A\"]);
    chk(r#"EXE "\"C:\TEST A\\\"""#, &["EXE", r#""C:\TEST A\""#]);
    chk(r#"EXE "a b c"  d  e"#, &["EXE", "a b c", "d", "e"]);
    chk(r#"EXE "ab\"c"  "\\"  d"#, &["EXE", r#"ab"c"#, r"\", "d"]);
    chk(r#"EXE a\\\b d"e f"g h"#, &["EXE", r"a\\\b", "de fg", "h"]);
    chk(r#"EXE a\\\"b c d"#, &["EXE", r#"a\"b"#, "c", "d"]);
    chk(r#"EXE a\\\\"b c" d e"#, &["EXE", r"a\\b c", "d", "e"]);
    // Double Double Quotes
    chk(r#"EXE "a b c"""#, &["EXE", r#"a b c""#]);
    chk(r#"EXE """CallMeIshmael"""  b  c"#, &["EXE", r#""CallMeIshmael""#, "b", "c"]);
    chk(r#"EXE """Call Me Ishmael""""#, &["EXE", r#""Call Me Ishmael""#]);
    chk(r#"EXE """"Call Me Ishmael"" b c"#, &["EXE", r#""Call"#, "Me", "Ishmael", "b", "c"]);
}
<|endoftext|>