<commit_before>//! Issues interface

use std::fmt;
use std::collections::HashMap;

use futures::future;
use hyper::client::Connect;
use url::form_urlencoded;

use {Github, Future, SortDirection, serde_json};
use comments::Comments;
use users::User;
use labels::Label;

/// enum representation of github pull and issue state
#[derive(Clone, Debug, PartialEq)]
pub enum State {
    /// Only open issues
    Open,
    /// Only closed issues
    Closed,
    /// All issues, open or closed
    All,
}

impl fmt::Display for State {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            State::Open => "open",
            State::Closed => "closed",
            State::All => "all",
        }.fmt(f)
    }
}

impl Default for State {
    fn default() -> State {
        State::Open
    }
}

/// Sort options available for github issues
#[derive(Clone, Debug, PartialEq)]
pub enum Sort {
    /// sort by creation time of issue
    Created,
    /// sort by the last time issue was updated
    Updated,
    /// sort by number of comments
    Comments,
}

impl fmt::Display for Sort {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Sort::Created => "created",
            Sort::Updated => "updated",
            Sort::Comments => "comments",
        }.fmt(f)
    }
}

impl Default for Sort {
    fn default() -> Sort {
        Sort::Created
    }
}

/// Provides access to label operations available for an individual issues
pub struct IssueLabels<C: Clone + Connect> {
    github: Github<C>,
    owner: String,
    repo: String,
    number: u64,
}

impl<C: Clone + Connect> IssueLabels<C> {
    #[doc(hidden)]
    pub fn new<O, R>(github: Github<C>, owner: O, repo: R, number: u64) -> Self
    where
        O: Into<String>,
        R: Into<String>,
    {
        IssueLabels {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
            number: number,
        }
    }

    fn path(&self, more: &str) -> String {
        format!(
            "/repos/{}/{}/issues/{}/labels{}",
            self.owner,
            self.repo,
            self.number,
            more
        )
    }

    /// add a set of labels to this issue ref
    pub fn add(&self, labels: Vec<&str>) -> Future<Vec<Label>> {
        self.github.post(&self.path(""), json!(labels))
    }

    /// remove a label from this issue
    pub fn remove(&self, label: &str) -> Future<()> {
        self.github.delete(&self.path(&format!("/{}", label)))
    }

    /// replace all labels associated with this issue with a new set.
    /// providing an empty set of labels is the same as clearing the
    /// current labels
    pub fn set(&self, labels: Vec<&str>) -> Future<Vec<Label>> {
        self.github.put(&self.path(""), json!(labels))
    }

    /// remove all labels from an issue
    pub fn clear(&self) -> Future<()> {
        self.github.delete(&self.path(""))
    }
}

/// Provides access to operations available for a single issue
/// Typically accessed from `github.repo(.., ..).issues().get(number)`
pub struct IssueRef<C>
where
    C: Connect + Clone,
{
    github: Github<C>,
    owner: String,
    repo: String,
    number: u64,
}

impl<C: Clone + Connect> IssueRef<C> {
    /// create a new instance of a github repo issue ref
    pub fn new<O, R>(github: Github<C>, owner: O, repo: R, number: u64) -> Self
    where
        O: Into<String>,
        R: Into<String>,
    {
        IssueRef {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
            number: number,
        }
    }

    /// Request an issue's information
    pub fn get(&self) -> Result<Issue> {
        self.github.get::<Issue>(&self.path(""))
    }

    fn path(&self, more: &str) -> String {
        format!(
            "/repos/{}/{}/issues/{}{}",
            self.owner,
            self.repo,
            self.number,
            more
        )
    }

    pub fn labels(&self) -> IssueLabels<C> {
        IssueLabels::new(
            self.github.clone(),
            self.owner.as_str(),
            self.repo.as_str(),
            self.number,
        )
    }

    pub fn edit(&self, is: &IssueOptions) -> Future<Issue> {
        self.github.patch(&self.path(""), json!(is))
    }

    pub fn comments(&self) -> Comments<C> {
        Comments::new(
            self.github.clone(),
            self.owner.clone(),
            self.repo.clone(),
            self.number,
        )
    }
}

/// Provides access to operations available for a repository issues
/// Typically accessed via `github.repo(..., ...).issues()`
pub struct Issues<C>
where
    C: Clone + Connect,
{
    github: Github<C>,
    owner: String,
    repo: String,
}

impl<C: Clone + Connect> Issues<C> {
    /// create a new instance of a github repo issue ref
    pub fn new<O, R>(github: Github<C>, owner: O, repo: R) -> Self
    where
        O: Into<String>,
        R: Into<String>,
    {
        Issues {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
        }
    }

    fn path(&self, more: &str) -> String {
        format!("/repos/{}/{}/issues{}", self.owner, self.repo, more)
    }

    pub fn get(&self, number: u64) -> IssueRef<C> {
        IssueRef::new(
            self.github.clone(),
            self.owner.as_str(),
            self.repo.as_str(),
            number,
        )
    }

    pub fn create(&self, is: &IssueOptions) -> Future<Issue> {
        self.github.post(&self.path(""), json!(is))
    }

    pub fn list(&self, options: &IssueListOptions) -> Future<Vec<Issue>> {
        let mut uri = vec![self.path("")];
        if let Some(query) = options.serialize() {
            uri.push(query);
        }
        self.github.get(&uri.join("?"))
    }
}

// representations

// todo: simplify with param
#[derive(Default)]
pub struct IssueListOptions {
    params: HashMap<&'static str, String>,
}

impl IssueListOptions {
    pub fn builder() -> IssueListOptionsBuilder {
        IssueListOptionsBuilder::new()
    }

    pub fn serialize(&self) -> Option<String> {
        if self.params.is_empty() {
            None
        } else {
            let encoded: String = form_urlencoded::Serializer::new(String::new())
                .extend_pairs(&self.params)
                .finish();
            Some(encoded)
        }
    }
}

/// a mutable issue list builder
pub struct IssueListOptionsBuilder(IssueListOptions);

impl IssueListOptionsBuilder {
    pub fn new() -> IssueListOptionsBuilder {
        IssueListOptionsBuilder(IssueListOptions { ..Default::default() })
    }

    pub fn state(&mut self, state: State) -> &mut IssueListOptionsBuilder {
        self.0.params.insert("state", state.to_string());
        self
    }

    pub fn sort(&mut self, sort: Sort) -> &mut IssueListOptionsBuilder {
        self.0.params.insert("sort", sort.to_string());
        self
    }

    pub fn asc(&mut self) -> &mut IssueListOptionsBuilder {
        self.direction(SortDirection::Asc)
    }

    pub fn desc(&mut self) -> &mut IssueListOptionsBuilder {
        self.direction(SortDirection::Desc)
    }

    pub fn direction(&mut self, direction: SortDirection) -> &mut IssueListOptionsBuilder {
        self.0.params.insert("direction", direction.to_string());
        self
    }

    pub fn assignee<A>(&mut self, assignee: A) -> &mut IssueListOptionsBuilder
    where
        A: Into<String>,
    {
        self.0.params.insert("assignee", assignee.into());
        self
    }

    pub fn creator<C>(&mut self, creator: C) -> &mut IssueListOptionsBuilder
    where
        C: Into<String>,
    {
        self.0.params.insert("creator", creator.into());
        self
    }

    pub fn mentioned<M>(&mut self, mentioned: M) -> &mut IssueListOptionsBuilder
    where
        M: Into<String>,
    {
        self.0.params.insert("mentioned", mentioned.into());
        self
    }

    pub fn labels<L>(&mut self, labels: Vec<L>) -> &mut IssueListOptionsBuilder
    where
        L: Into<String>,
    {
        self.0.params.insert(
            "labels",
            labels
                .into_iter()
                .map(|l| l.into())
                .collect::<Vec<_>>()
                .join(","),
        );
        self
    }

    pub fn since<S>(&mut self, since: S) -> &mut IssueListOptionsBuilder
    where
        S: Into<String>,
    {
        self.0.params.insert("since", since.into());
        self
    }

    pub fn build(&self) -> IssueListOptions {
        IssueListOptions { params: self.0.params.clone() }
    }
}

#[derive(Debug, Serialize)]
pub struct IssueOptions {
    pub title: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub body: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub assignee: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub milestone: Option<u64>,
    pub labels: Vec<String>,
}

impl IssueOptions {
    pub fn new<T, B, A, L>(
        title: T,
        body: Option<B>,
        assignee: Option<A>,
        milestone: Option<u64>,
        labels: Vec<L>,
    ) -> IssueOptions
    where
        T: Into<String>,
        B: Into<String>,
        A: Into<String>,
        L: Into<String>,
    {
        IssueOptions {
            title: title.into(),
            body: body.map(|b| b.into()),
            assignee: assignee.map(|a| a.into()),
            milestone: milestone,
            labels: labels
                .into_iter()
                .map(|l| l.into())
                .collect::<Vec<String>>(),
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct Issue {
    pub id: u64,
    pub url: String,
    pub labels_url: String,
    pub comments_url: String,
    pub events_url: String,
    pub html_url: String,
    pub number: u64,
    pub state: String,
    pub title: String,
    pub body: String,
    pub user: User,
    pub labels: Vec<Label>,
    pub assignee: Option<User>,
    pub locked: bool,
    pub comments: u64,
    pub closed_at: Option<String>,
    pub created_at: String,
    pub updated_at: String,
}

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

    #[test]
    fn default_state() {
        let default: State = Default::default();
        assert_eq!(default, State::Open)
    }

    #[test]
    fn issue_list_reqs() {
        fn test_serialize(tests: Vec<(IssueListOptions, Option<String>)>) {
            for test in tests {
                match test {
                    (k, v) => assert_eq!(k.serialize(), v),
                }
            }
        }
        let tests = vec![
            (IssueListOptions::builder().build(), None),
            (
                IssueListOptions::builder().state(State::Closed).build(),
                Some("state=closed".to_owned())
            ),
            (
                IssueListOptions::builder()
                    .labels(vec!["foo", "bar"])
                    .build(),
                Some("labels=foo%2Cbar".to_owned())
            ),
        ];
        test_serialize(tests)
    }

    #[test]
    fn sort_default() {
        let default: Sort = Default::default();
        assert_eq!(default, Sort::Created)
    }

    #[test]
    fn sort_display() {
        for (k, v) in vec![
            (Sort::Created, "created"),
            (Sort::Updated, "updated"),
            (Sort::Comments, "comments"),
        ]
        {
            assert_eq!(k.to_string(), v)
        }
    }
}
<commit_msg>sync with master<commit_after>//! Issues interface

use std::fmt;
use std::collections::HashMap;

use futures::future;
use hyper::client::Connect;
use url::form_urlencoded;

use {Github, Future, SortDirection, serde_json};
use comments::Comments;
use users::User;
use labels::Label;

/// enum representation of github pull and issue state
#[derive(Clone, Debug, PartialEq)]
pub enum State {
    /// Only open issues
    Open,
    /// Only closed issues
    Closed,
    /// All issues, open or closed
    All,
}

impl fmt::Display for State {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            State::Open => "open",
            State::Closed => "closed",
            State::All => "all",
        }.fmt(f)
    }
}

impl Default for State {
    fn default() -> State {
        State::Open
    }
}

/// Sort options available for github issues
#[derive(Clone, Debug, PartialEq)]
pub enum Sort {
    /// sort by creation time of issue
    Created,
    /// sort by the last time issue was updated
    Updated,
    /// sort by number of comments
    Comments,
}

impl fmt::Display for Sort {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Sort::Created => "created",
            Sort::Updated => "updated",
            Sort::Comments => "comments",
        }.fmt(f)
    }
}

impl Default for Sort {
    fn default() -> Sort {
        Sort::Created
    }
}

/// Provides access to label operations available for an individual issues
pub struct IssueLabels<C: Clone + Connect> {
    github: Github<C>,
    owner: String,
    repo: String,
    number: u64,
}

impl<C: Clone + Connect> IssueLabels<C> {
    #[doc(hidden)]
    pub fn new<O, R>(github: Github<C>, owner: O, repo: R, number: u64) -> Self
    where
        O: Into<String>,
        R: Into<String>,
    {
        IssueLabels {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
            number: number,
        }
    }

    fn path(&self, more: &str) -> String {
        format!(
            "/repos/{}/{}/issues/{}/labels{}",
            self.owner,
            self.repo,
            self.number,
            more
        )
    }

    /// add a set of labels to this issue ref
    pub fn add(&self, labels: Vec<&str>) -> Future<Vec<Label>> {
        self.github.post(&self.path(""), json!(labels))
    }

    /// remove a label from this issue
    pub fn remove(&self, label: &str) -> Future<()> {
        self.github.delete(&self.path(&format!("/{}", label)))
    }

    /// replace all labels associated with this issue with a new set.
    /// providing an empty set of labels is the same as clearing the
    /// current labels
    pub fn set(&self, labels: Vec<&str>) -> Future<Vec<Label>> {
        self.github.put(&self.path(""), json!(labels))
    }

    /// remove all labels from an issue
    pub fn clear(&self) -> Future<()> {
        self.github.delete(&self.path(""))
    }
}

/// Provides access to operations available for a single issue
/// Typically accessed from `github.repo(.., ..).issues().get(number)`
pub struct IssueRef<C>
where
    C: Connect + Clone,
{
    github: Github<C>,
    owner: String,
    repo: String,
    number: u64,
}

impl<C: Clone + Connect> IssueRef<C> {
    #[doc(hidden)]
    pub fn new<O, R>(github: Github<C>, owner: O, repo: R, number: u64) -> Self
    where
        O: Into<String>,
        R: Into<String>,
    {
        IssueRef {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
            number: number,
        }
    }

    /// Request an issue's information
    pub fn get(&self) -> Future<Issue> {
        self.github.get(&self.path(""))
    }

    fn path(&self, more: &str) -> String {
        format!(
            "/repos/{}/{}/issues/{}{}",
            self.owner,
            self.repo,
            self.number,
            more
        )
    }

    /// Return a reference to labels operations available for this issue
    pub fn labels(&self) -> IssueLabels<C> {
        IssueLabels::new(
            self.github.clone(),
            self.owner.as_str(),
            self.repo.as_str(),
            self.number,
        )
    }

    /// Edit the issues options
    pub fn edit(&self, is: &IssueOptions) -> Future<Issue> {
        self.github.patch(&self.path(""), json!(is))
    }

    /// Return a reference to comment operations available for this issue
    pub fn comments(&self) -> Comments<C> {
        Comments::new(
            self.github.clone(),
            self.owner.clone(),
            self.repo.clone(),
            self.number,
        )
    }
}

/// Provides access to operations available for a repository issues
/// Typically accessed via `github.repo(..., ...).issues()`
pub struct Issues<C>
where
    C: Clone + Connect,
{
    github: Github<C>,
    owner: String,
    repo: String,
}

impl<C: Clone + Connect> Issues<C> {
    /// create a new instance of a github repo issue ref
    pub fn new<O, R>(github: Github<C>, owner: O, repo: R) -> Self
    where
        O: Into<String>,
        R: Into<String>,
    {
        Issues {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
        }
    }

    fn path(&self, more: &str) -> String {
        format!("/repos/{}/{}/issues{}", self.owner, self.repo, more)
    }

    pub fn get(&self, number: u64) -> IssueRef<C> {
        IssueRef::new(
            self.github.clone(),
            self.owner.as_str(),
            self.repo.as_str(),
            number,
        )
    }

    pub fn create(&self, is: &IssueOptions) -> Future<Issue> {
        self.github.post(&self.path(""), json!(is))
    }

    pub fn list(&self, options: &IssueListOptions) -> Future<Vec<Issue>> {
        let mut uri = vec![self.path("")];
        if let Some(query) = options.serialize() {
            uri.push(query);
        }
        self.github.get(&uri.join("?"))
    }
}

// representations

// todo: simplify with param
#[derive(Default)]
pub struct IssueListOptions {
    params: HashMap<&'static str, String>,
}

impl IssueListOptions {
    pub fn builder() -> IssueListOptionsBuilder {
        IssueListOptionsBuilder::new()
    }

    pub fn serialize(&self) -> Option<String> {
        if self.params.is_empty() {
            None
        } else {
            let encoded: String = form_urlencoded::Serializer::new(String::new())
                .extend_pairs(&self.params)
                .finish();
            Some(encoded)
        }
    }
}

/// a mutable issue list builder
pub struct IssueListOptionsBuilder(IssueListOptions);

impl IssueListOptionsBuilder {
    pub fn new() -> IssueListOptionsBuilder {
        IssueListOptionsBuilder(IssueListOptions { ..Default::default() })
    }

    pub fn state(&mut self, state: State) -> &mut IssueListOptionsBuilder {
        self.0.params.insert("state", state.to_string());
        self
    }

    pub fn sort(&mut self, sort: Sort) -> &mut IssueListOptionsBuilder {
        self.0.params.insert("sort", sort.to_string());
        self
    }

    pub fn asc(&mut self) -> &mut IssueListOptionsBuilder {
        self.direction(SortDirection::Asc)
    }

    pub fn desc(&mut self) -> &mut IssueListOptionsBuilder {
        self.direction(SortDirection::Desc)
    }

    pub fn direction(&mut self, direction: SortDirection) -> &mut IssueListOptionsBuilder {
        self.0.params.insert("direction", direction.to_string());
        self
    }

    pub fn assignee<A>(&mut self, assignee: A) -> &mut IssueListOptionsBuilder
    where
        A: Into<String>,
    {
        self.0.params.insert("assignee", assignee.into());
        self
    }

    pub fn creator<C>(&mut self, creator: C) -> &mut IssueListOptionsBuilder
    where
        C: Into<String>,
    {
        self.0.params.insert("creator", creator.into());
        self
    }

    pub fn mentioned<M>(&mut self, mentioned: M) -> &mut IssueListOptionsBuilder
    where
        M: Into<String>,
    {
        self.0.params.insert("mentioned", mentioned.into());
        self
    }

    pub fn labels<L>(&mut self, labels: Vec<L>) -> &mut IssueListOptionsBuilder
    where
        L: Into<String>,
    {
        self.0.params.insert(
            "labels",
            labels
                .into_iter()
                .map(|l| l.into())
                .collect::<Vec<_>>()
                .join(","),
        );
        self
    }

    pub fn since<S>(&mut self, since: S) -> &mut IssueListOptionsBuilder
    where
        S: Into<String>,
    {
        self.0.params.insert("since", since.into());
        self
    }

    pub fn build(&self) -> IssueListOptions {
        IssueListOptions { params: self.0.params.clone() }
    }
}

#[derive(Debug, Serialize)]
pub struct IssueOptions {
    pub title: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub body: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub assignee: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub milestone: Option<u64>,
    pub labels: Vec<String>,
}

impl IssueOptions {
    pub fn new<T, B, A, L>(
        title: T,
        body: Option<B>,
        assignee: Option<A>,
        milestone: Option<u64>,
        labels: Vec<L>,
    ) -> IssueOptions
    where
        T: Into<String>,
        B: Into<String>,
        A: Into<String>,
        L: Into<String>,
    {
        IssueOptions {
            title: title.into(),
            body: body.map(|b| b.into()),
            assignee: assignee.map(|a| a.into()),
            milestone: milestone,
            labels: labels
                .into_iter()
                .map(|l| l.into())
                .collect::<Vec<String>>(),
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct Issue {
    pub id: u64,
    pub url: String,
    pub labels_url: String,
    pub comments_url: String,
    pub events_url: String,
    pub html_url: String,
    pub number: u64,
    pub state: String,
    pub title: String,
    pub body: String,
    pub user: User,
    pub labels: Vec<Label>,
    pub assignee: Option<User>,
    pub locked: bool,
    pub comments: u64,
    pub closed_at: Option<String>,
    pub created_at: String,
    pub updated_at: String,
}

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

    #[test]
    fn default_state() {
        let default: State = Default::default();
        assert_eq!(default, State::Open)
    }

    #[test]
    fn issue_list_reqs() {
        fn test_serialize(tests: Vec<(IssueListOptions, Option<String>)>) {
            for test in tests {
                match test {
                    (k, v) => assert_eq!(k.serialize(), v),
                }
            }
        }
        let tests = vec![
            (IssueListOptions::builder().build(), None),
            (
                IssueListOptions::builder().state(State::Closed).build(),
                Some("state=closed".to_owned())
            ),
            (
                IssueListOptions::builder()
                    .labels(vec!["foo", "bar"])
                    .build(),
                Some("labels=foo%2Cbar".to_owned())
            ),
        ];
        test_serialize(tests)
    }

    #[test]
    fn sort_default() {
        let default: Sort = Default::default();
        assert_eq!(default, Sort::Created)
    }

    #[test]
    fn sort_display() {
        for (k, v) in vec![
            (Sort::Created, "created"),
            (Sort::Updated, "updated"),
            (Sort::Comments, "comments"),
        ]
        {
            assert_eq!(k.to_string(), v)
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The GLFW-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// 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.

extern crate glfw;

use glfw::{Action, Context, Key, WindowEvent, RenderContext};

fn main() {
    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    let (mut window, events) = glfw.create_window(300, 300, "Hello this is window", glfw::WindowMode::Windowed)
        .expect("Failed to create GLFW window.");

    window.set_all_polling(true);
    let mut render_context = window.render_context();

    // Render asynchronously from the main event loop. This prevents a pause in rendering
    // during some window interactions (e.g. resizing) on platforms like Windows.
    let thread = std::thread::spawn(move || {
        render_context.make_current();
        while !render_context.should_close() {
            for (_, event) in glfw::flush_messages(&events) {
                handle_window_event(&mut render_context, event);
            }
            render_context.swap_buffers();
        }
    });

    while !window.should_close() {
        glfw.wait_events_unbuffered(|window_id, event| {
            // Multiple windows may be identified by their `window_id`
            assert_eq!(window.window_id(), window_id);

            // Intercept the close request and reset the flag
            if let (_, WindowEvent::Close) = event {
                window.set_should_close(false);
            };

            // Forward the event to the render thread via the `events` receiver
            // to be processed asynchronously from the main event loop thread.
            // Returning `None` here would consume the event.
            Some(event)
        });
    }

    thread.join().unwrap();
}

fn handle_window_event(render_context: &mut RenderContext, event: glfw::WindowEvent) {
    match event {
        glfw::WindowEvent::Close | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => {
            render_context.set_should_close(true);
        }
        _ => {}
    }
}
<commit_msg>Fix the delayed close in the unbuffered events example<commit_after>// Copyright 2013 The GLFW-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// 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.

extern crate glfw;

use glfw::{Action, Context, Key, WindowEvent, RenderContext};

fn main() {
    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    let (mut window, events) = glfw.create_window(300, 300, "Hello this is window", glfw::WindowMode::Windowed)
        .expect("Failed to create GLFW window.");

    window.set_all_polling(true);
    let mut render_context = window.render_context();

    // Render asynchronously from the main event loop. This prevents a pause in rendering
    // during some window interactions (e.g. resizing) on platforms like Windows.
    let thread = std::thread::spawn(move || {
        render_context.make_current();
        while !render_context.should_close() {
            for (_, event) in glfw::flush_messages(&events) {
                handle_window_event(&mut render_context, event);
            }
            render_context.swap_buffers();
        }
    });

    while !window.should_close() {
        glfw.wait_events_unbuffered(|window_id, event| {
            // Multiple windows may be identified by their `window_id`
            assert_eq!(window.window_id(), window_id);

            // Intercept the close request and reset the flag
            if let (_, WindowEvent::Close) = event {
                window.set_should_close(false);
            };

            // Forward the event to the render thread via the `events` receiver
            // to be processed asynchronously from the main event loop thread.
            // Returning `None` here would consume the event.
            Some(event)
        });
    }

    thread.join().unwrap();
}

fn handle_window_event(render_context: &mut RenderContext, event: glfw::WindowEvent) {
    match event {
        glfw::WindowEvent::Close | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => {
            render_context.set_should_close(true);
            render_context.post_empty_event();
        }
        _ => {}
    }
}
<|endoftext|>


<commit_before>use fnv::FnvHashMap;
use std::u16;

lazy_static! {
    static ref ATTRIBUTES: FnvHashMap<&'static str, &'static str> = {
        let mut map = FnvHashMap::default();
        map.insert("bold", "1");
        map.insert("dim", "2");
        map.insert("underlined", "4");
        map.insert("blink", "5");
        map.insert("reverse", "7");
        map.insert("hidden", "8");
        map
    };
}

lazy_static! {
    static ref COLORS: FnvHashMap<&'static str, &'static str> = {
        let mut map = FnvHashMap::default();
        map.insert("black", "30");
        map.insert("red", "31");
        map.insert("green", "32");
        map.insert("yellow", "33");
        map.insert("blue", "34");
        map.insert("magenta", "35");
        map.insert("cyan", "36");
        map.insert("light_gray", "37");
        map.insert("default", "39");
        map.insert("blackbg", "40");
        map.insert("dark_gray", "90");
        map.insert("light_red", "91");
        map.insert("light_green", "92");
        map.insert("light_yellow", "93");
        map.insert("light_blue", "94");
        map.insert("light_magenta", "95");
        map.insert("light_cyan", "96");
        map
    };
}

lazy_static! {
    static ref BG_COLORS: FnvHashMap<&'static str, &'static str> = {
        let mut map = FnvHashMap::default();
        map.insert("redbg", "41");
        map.insert("greenbg", "42");
        map.insert("yellowbg", "43");
        map.insert("bluebg", "44");
        map.insert("magentabg", "45");
        map.insert("cyanbg", "46");
        map.insert("light_graybg", "47");
        map.insert("defaultbg", "49");
        map.insert("dark_graybg", "100");
        map.insert("light_redbg", "101");
        map.insert("light_greenbg", "102");
        map.insert("light_yellowbg",  "103");
        map.insert("light_bluebg", "104");
        map.insert("light_magentabg", "105");
        map.insert("light_cyanbg", "106");
        map.insert("whitebg", "107");
        map
    };
}

enum Mode {
    Name(&'static str),
    bits256(u16),
}

pub struct Colors {
    foreground: Option<Mode>,
    background: Option<Mode>,
    attribute: Option<Vec<&'static str>>
}

impl Colors {
    pub fn collect(input: &str) -> Colors {
        let mut colors = Colors { foreground: None, background: None, attribute: None };
        for variable in input.split(",") {
            if variable == "reset" {
                return Colors { foreground: None, background: None, attribute: Some(vec!["0"]) };
            } else if let Some(color) = ATTRIBUTES.get(&variable) {
                let vec_exists = match colors.attribute.as_mut() {
                    Some(vec) => { vec.push(color); true },
                    None => false
                };

                if !vec_exists {
                    colors.attribute = Some(vec![color]);
                }
            } else if let Some(color) = COLORS.get(&variable) {
                colors.foreground = Some(Mode::Name(*color))
            } else {
                match BG_COLORS.get(&variable) {
                    Some(color) => colors.background = Some(Mode::Name(*color)),
                    None => if let Ok(value) = u16::from_str_radix(&variable[0..2], 16) {
                        if variable.ends_with("bg") {
                            colors.background = Some(Mode::bits256(value));
                        } else {
                            colors.foreground = Some(Mode::bits256(value));
                        }
                    } else {
                        eprintln!("ion: {} is not a valid color", variable)
                    }
                }
            }
        }
        colors
    }

    pub fn into_string(self) -> Option<String> {
        let mut output = String::from("\x1b[");

        let foreground = match self.foreground {
            Some(Mode::Name(string)) => Some(string.to_owned()),
            Some(Mode::bits256(value)) => Some(format!("38;5;{}", value)),
            None => None
        };

        let background = match self.background {
            Some(Mode::Name(string)) => Some(string.to_owned()),
            Some(Mode::bits256(value)) => Some(format!("48;5;{}", value)),
            None => None
        };

        if let Some(attr) = self.attribute {
            output.push_str(&attr.join(";"));
            match (foreground, background) {
                (Some(c), None) | (None, Some(c)) => Some([&output, ";", &c, "m"].concat()),
                (None, None) => Some([&output, "m"].concat()),
                (Some(fg), Some(bg)) => Some([&output, ";", &fg, ";", &bg, "m"].concat())
            }
        } else {
            match (foreground, background) {
                (Some(c), None) | (None, Some(c)) => Some([&output, &c, "m"].concat()),
                (None, None) => None,
                (Some(fg), Some(bg)) => Some([&output, &fg, ";", &bg, "m"].concat())
            }
        }
    }
}
<commit_msg>Quick Fix<commit_after>use fnv::FnvHashMap;
use std::u16;

lazy_static! {
    static ref ATTRIBUTES: FnvHashMap<&'static str, &'static str> = {
        let mut map = FnvHashMap::default();
        map.insert("bold", "1");
        map.insert("dim", "2");
        map.insert("underlined", "4");
        map.insert("blink", "5");
        map.insert("reverse", "7");
        map.insert("hidden", "8");
        map
    };
}

lazy_static! {
    static ref COLORS: FnvHashMap<&'static str, &'static str> = {
        let mut map = FnvHashMap::default();
        map.insert("black", "30");
        map.insert("red", "31");
        map.insert("green", "32");
        map.insert("yellow", "33");
        map.insert("blue", "34");
        map.insert("magenta", "35");
        map.insert("cyan", "36");
        map.insert("light_gray", "37");
        map.insert("default", "39");
        map.insert("dark_gray", "90");
        map.insert("light_red", "91");
        map.insert("light_green", "92");
        map.insert("light_yellow", "93");
        map.insert("light_blue", "94");
        map.insert("light_magenta", "95");
        map.insert("light_cyan", "96");
        map
    };
}

lazy_static! {
    static ref BG_COLORS: FnvHashMap<&'static str, &'static str> = {
        let mut map = FnvHashMap::default();
        map.insert("blackbg", "40");
        map.insert("redbg", "41");
        map.insert("greenbg", "42");
        map.insert("yellowbg", "43");
        map.insert("bluebg", "44");
        map.insert("magentabg", "45");
        map.insert("cyanbg", "46");
        map.insert("light_graybg", "47");
        map.insert("defaultbg", "49");
        map.insert("dark_graybg", "100");
        map.insert("light_redbg", "101");
        map.insert("light_greenbg", "102");
        map.insert("light_yellowbg",  "103");
        map.insert("light_bluebg", "104");
        map.insert("light_magentabg", "105");
        map.insert("light_cyanbg", "106");
        map.insert("whitebg", "107");
        map
    };
}

enum Mode {
    Name(&'static str),
    bits256(u16),
}

pub struct Colors {
    foreground: Option<Mode>,
    background: Option<Mode>,
    attribute: Option<Vec<&'static str>>
}

impl Colors {
    pub fn collect(input: &str) -> Colors {
        let mut colors = Colors { foreground: None, background: None, attribute: None };
        for variable in input.split(",") {
            if variable == "reset" {
                return Colors { foreground: None, background: None, attribute: Some(vec!["0"]) };
            } else if let Some(color) = ATTRIBUTES.get(&variable) {
                let vec_exists = match colors.attribute.as_mut() {
                    Some(vec) => { vec.push(color); true },
                    None => false
                };

                if !vec_exists {
                    colors.attribute = Some(vec![color]);
                }
            } else if let Some(color) = COLORS.get(&variable) {
                colors.foreground = Some(Mode::Name(*color))
            } else {
                match BG_COLORS.get(&variable) {
                    Some(color) => colors.background = Some(Mode::Name(*color)),
                    None => if let Ok(value) = u16::from_str_radix(&variable[0..2], 16) {
                        if variable.ends_with("bg") {
                            colors.background = Some(Mode::bits256(value));
                        } else {
                            colors.foreground = Some(Mode::bits256(value));
                        }
                    } else {
                        eprintln!("ion: {} is not a valid color", variable)
                    }
                }
            }
        }
        colors
    }

    pub fn into_string(self) -> Option<String> {
        let mut output = String::from("\x1b[");

        let foreground = match self.foreground {
            Some(Mode::Name(string)) => Some(string.to_owned()),
            Some(Mode::bits256(value)) => Some(format!("38;5;{}", value)),
            None => None
        };

        let background = match self.background {
            Some(Mode::Name(string)) => Some(string.to_owned()),
            Some(Mode::bits256(value)) => Some(format!("48;5;{}", value)),
            None => None
        };

        if let Some(attr) = self.attribute {
            output.push_str(&attr.join(";"));
            match (foreground, background) {
                (Some(c), None) | (None, Some(c)) => Some([&output, ";", &c, "m"].concat()),
                (None, None) => Some([&output, "m"].concat()),
                (Some(fg), Some(bg)) => Some([&output, ";", &fg, ";", &bg, "m"].concat())
            }
        } else {
            match (foreground, background) {
                (Some(c), None) | (None, Some(c)) => Some([&output, &c, "m"].concat()),
                (None, None) => None,
                (Some(fg), Some(bg)) => Some([&output, &fg, ";", &bg, "m"].concat())
            }
        }
    }
}
<|endoftext|>


<commit_before>/*!
 * Bounded package merge algorithm, based on the paper
 * "A Fast and Space-Economical Algorithm for Length-Limited Coding
 * Jyrki Katajainen, Alistair Moffat, Andrew Turpin".
 */

use std::mem;
use std::ptr::{null, null_mut};

use libc::{c_void, size_t};
use libc::funcs::c95::stdlib::{free, malloc};

/// Nodes forming chains. Also used to represent leaves.
struct Node {
    /// Total weight (symbol count) of this chain.
    weight: usize,
    /// Previous node(s) of this chain, or 0 if none.
    tail: *mut Node,
    /// Leaf symbol index, or number of leaves before this chain.
    count: i32,
    /// Tracking for garbage collection.
    in_use: bool,
}

/// Memory pool for nodes.
struct NodePool {
    /// The pool.
    nodes: *mut Node,
    /// Pointer to a possibly free node in the pool.
    next: *mut Node,
    /// Size of the memory pool.
    size: u32,
}

/// Initializes a chain node with the given values and marks it as in use.
unsafe fn init_node(weight: usize, count: i32, tail: *mut Node, node: *mut Node) {
    (*node).weight = weight;
    (*node).count = count;
    (*node).tail = tail;
    (*node).in_use = true;
}

/**
 * Finds a free location in the memory pool. Performs garbage collection if needed.
 * lists: If given, used to mark in-use nodes during garbage collection.
 * maxbits: Size of lists.
 * pool: Memory pool to get free node from.
 */
unsafe fn get_free_node(lists: *const *mut *mut Node, maxbits: i32, pool: *mut NodePool) -> *mut Node {
    loop {
        if (*pool).next >= (*pool).nodes.offset((*pool).size as isize) {
            // Garbage collection
            for i in 0..(*pool).size {
                (*(*pool).nodes.offset(i as isize)).in_use = false;
            }
            if !lists.is_null() {
                for i in 0..maxbits*2 {
                    let mut node = *(*lists.offset((i / 2) as isize)).offset((i % 2) as isize);
                    while !node.is_null() {
                        (*node).in_use = true;
                        node = (*node).tail;
                    }
                }
            }
            (*pool).next = (*pool).nodes;
        }
        if (*(*pool).next).in_use {
            break;
        }
        (*pool).next = (*pool).next.offset(1);
    }
    let free_node = (*pool).next;
    (*pool).next = (*pool).next.offset(1);
    free_node
}

/**
 * Performs a Boundary Package-Merge step. Puts a new chain in the given list. The
 * new chain is, depending on the weights, a leaf or a combination of two chains
 * from the previous list.
 * lists: The lists of chains.
 * maxbits: Number of lists.
 * leaves: The leaves, one per symbol.
 * numsymbols: Number of leaves.
 * pool: the node memory pool.
 * index: The index of the list in which a new chain or leaf is required.
 * final: Whether this is the last time this function is called. If it is then it
 *   is no more needed to recursively call self.
 */
unsafe fn boundary_pm(lists: *const *mut *mut Node, maxbits: i32, leaves: *const Node, numsymbols: i32, pool: *mut NodePool,
                      index: i32, is_final: bool) {
    let lastcount = (**(*lists.offset(index as isize)).offset(1)).count; // Count of last chain of list.

    if index == 0 && lastcount >= numsymbols {
        return;
    }

    let newchain = get_free_node(lists, maxbits, pool);
    let oldchain = *(*lists.offset(index as isize)).offset(1);

    // These are set up before the recursive calls below, so that there is a list
    // pointing to the new node, to let the garbage collection know it's in use.
    *(*lists.offset(index as isize)).offset(0) = oldchain;
    *(*lists.offset(index as isize)).offset(1) = newchain;

    if index == 0 {
        //New leaf node in list 0.
        init_node((*leaves.offset(lastcount as isize)).weight, lastcount + 1, null_mut(), newchain);
    } else {
        let sum = (**(*lists.offset((index - 1) as isize)).offset(0)).weight + (**(*lists.offset((index - 1) as isize)).offset(0)).weight;
        if lastcount < numsymbols && sum > (*leaves.offset(lastcount as isize)).weight {
            // New leaf inserted in list, so count is incremented.
            init_node((*leaves.offset(lastcount as isize)).weight, lastcount + 1, (*oldchain).tail, newchain);
        } else {
            init_node(sum, lastcount, *(*lists.offset((index - 1) as isize)).offset(1), newchain);
            if !is_final {
                // Two lookahead chains of previous list used up, create new ones.
                boundary_pm(lists, maxbits, leaves, numsymbols, pool, index - 1, false);
                boundary_pm(lists, maxbits, leaves, numsymbols, pool, index - 1, false);
            }
        }
    }
}

/// Initializes each list with as lookahead chains the two leaves with lowest weights.
unsafe fn init_lists(pool: *mut NodePool, leaves: *const Node, maxbits: i32, lists: *const *mut *mut Node) {
    let node0 = get_free_node(null(), maxbits, pool);
    let node1 = get_free_node(null(), maxbits, pool);
    init_node((*leaves.offset(0)).weight, 1, null_mut(), node0);
    init_node((*leaves.offset(1)).weight, 2, null_mut(), node1);
    for i in 0..maxbits {
        *(*lists.offset(i as isize)).offset(0) = node0;
        *(*lists.offset(i as isize)).offset(1) = node1;
    }
}

/**
 * Converts result of boundary package-merge to the bitlengths. The result in the
 * last chain of the last list contains the amount of active leaves in each list.
 * chain: Chain to extract the bit length from (last chain from last list).
 */
unsafe fn extract_bit_lengths(chain: *const Node, leaves: *const Node, bitlengths: *mut u32) {
    let mut node = chain;
    while node != null() {
        for i in 0..(*node).count {
            *bitlengths.offset((*leaves.offset(i as isize)).count as isize) = *bitlengths.offset((*leaves.offset(i as isize)).count as isize) + 1;
        }
        node = (*node).tail;
    }
}

/// Comparator for sorting the leaves. Has the function signature for qsort.
extern fn leaf_comparator(a: *const c_void, b: *const c_void) -> i32 {
    unsafe {
        let node_a: *const Node = a as *const Node;
        let node_b: *const Node = b as *const Node;
        (*node_a).weight as i32 - (*node_b).weight as i32
    }
}

#[link(name="c")]
extern {
    fn qsort(base: *mut c_void, nmemb: size_t, size: size_t, compar: extern fn(*const c_void, *const c_void) -> i32);
}

pub unsafe fn length_limited_code_lengths(frequencies: *const usize, n: i32, maxbits: i32, bitlengths: *mut u32) -> bool {
    // Amount of symbols with frequency > 0.
    let mut numsymbols = 0;

    // One leaf per symbol. Only numsymbols leaves will be used.
    let leaves: *mut Node = malloc((n as usize * mem::size_of::<Node>()) as size_t) as *mut Node;

    // Initialize all bitlengths at 0.
    for i in 0..n {
        *bitlengths.offset(i as isize) = 0;
    }

    // Count used symbols and place them in the leaves.
    for i in 0..n {
        if *frequencies.offset(i as isize) != 0 {
            (*leaves.offset(numsymbols)).weight = *frequencies.offset(i as isize);
            (*leaves.offset(numsymbols)).count = i;
            numsymbols = numsymbols + 1;
        }
    }

    // Check special cases and error conditions.
    if (1 << maxbits) < numsymbols {
        free(leaves as *mut c_void);
        return true; // Error, too few maxbits to represent symbols.
    }
    if numsymbols == 0 {
        free(leaves as *mut c_void);
        return false; // No symbols at all. OK.
    }
    if numsymbols == 1 {
        *bitlengths.offset((*leaves.offset(0)).count as isize) = 1;
        free(leaves as *mut c_void);
        return false; // Only one symbol, give it bitlength 1, not 0. OK.
    }

    // Sort the leaves from lightest to heaviest.
    qsort(leaves as *mut c_void, numsymbols as size_t, mem::size_of::<Node>() as size_t, leaf_comparator);

    // Initialize node memory pool.
    let pool_size = 2 * maxbits * (maxbits + 1);
    let pool_nodes = malloc((pool_size as usize * mem::size_of::<Node>()) as size_t) as *mut Node;
    let mut pool = NodePool { size: pool_size as u32, nodes: pool_nodes, next: pool_nodes };
    for i in 0..pool.size {
        (*pool.nodes.offset(i as isize)).in_use = false;
    }

    // Array of lists of chains. Each list requires only two lookahead chains at
    // a time, so each list is a array of two Node*'s.
    let lists: *const *mut *mut Node = malloc((maxbits as usize * mem::size_of::<*const *const Node>()) as size_t) as *const *mut *mut Node;
    init_lists(&mut pool, leaves, maxbits, lists);

    // In the last list, 2 * numsymbols - 2 active chains need to be created. Two
    // are already created in the initialization. Each BoundaryPM run creates one.
    let num_boundary_pm_runs = 2 * numsymbols - 4;
    for i in 0..num_boundary_pm_runs {
        let is_final = i == num_boundary_pm_runs - 1;
        boundary_pm(lists, maxbits, leaves, numsymbols as i32, &mut pool, maxbits - 1, is_final);
    }

    extract_bit_lengths(*(*lists.offset(maxbits as isize - 1)).offset(1), leaves, bitlengths);

    free(lists as *mut c_void);
    free(leaves as *mut c_void);
    free(pool.nodes as *mut c_void);
    false
}

#[cfg(test)]
mod tests {
    use std::mem::size_of;
    use libc::{c_void, size_t};

    use super::qsort;

    extern fn comparator(a: *const c_void, b: *const c_void) -> i32 {
        unsafe {
            *(a as *const i32) - *(b as *const i32)
        }
    }

    #[test]
    fn test_qsort() {
        unsafe {
            let mut a: [i32; 5] = [3, 2, 4, 1, 5];
            qsort(a.as_mut_ptr() as *mut c_void, a.len() as size_t, size_of::<i32>() as size_t, comparator);
            assert_eq!(a, [1, 2, 3, 4, 5]);
        }
    }
}
<commit_msg>Missed this predicate negation<commit_after>/*!
 * Bounded package merge algorithm, based on the paper
 * "A Fast and Space-Economical Algorithm for Length-Limited Coding
 * Jyrki Katajainen, Alistair Moffat, Andrew Turpin".
 */

use std::mem;
use std::ptr::{null, null_mut};

use libc::{c_void, size_t};
use libc::funcs::c95::stdlib::{free, malloc};

/// Nodes forming chains. Also used to represent leaves.
struct Node {
    /// Total weight (symbol count) of this chain.
    weight: usize,
    /// Previous node(s) of this chain, or 0 if none.
    tail: *mut Node,
    /// Leaf symbol index, or number of leaves before this chain.
    count: i32,
    /// Tracking for garbage collection.
    in_use: bool,
}

/// Memory pool for nodes.
struct NodePool {
    /// The pool.
    nodes: *mut Node,
    /// Pointer to a possibly free node in the pool.
    next: *mut Node,
    /// Size of the memory pool.
    size: u32,
}

/// Initializes a chain node with the given values and marks it as in use.
unsafe fn init_node(weight: usize, count: i32, tail: *mut Node, node: *mut Node) {
    (*node).weight = weight;
    (*node).count = count;
    (*node).tail = tail;
    (*node).in_use = true;
}

/**
 * Finds a free location in the memory pool. Performs garbage collection if needed.
 * lists: If given, used to mark in-use nodes during garbage collection.
 * maxbits: Size of lists.
 * pool: Memory pool to get free node from.
 */
unsafe fn get_free_node(lists: *const *mut *mut Node, maxbits: i32, pool: *mut NodePool) -> *mut Node {
    loop {
        if (*pool).next >= (*pool).nodes.offset((*pool).size as isize) {
            // Garbage collection
            for i in 0..(*pool).size {
                (*(*pool).nodes.offset(i as isize)).in_use = false;
            }
            if !lists.is_null() {
                for i in 0..maxbits*2 {
                    let mut node = *(*lists.offset((i / 2) as isize)).offset((i % 2) as isize);
                    while !node.is_null() {
                        (*node).in_use = true;
                        node = (*node).tail;
                    }
                }
            }
            (*pool).next = (*pool).nodes;
        }
        if !(*(*pool).next).in_use {
            break;
        }
        (*pool).next = (*pool).next.offset(1);
    }
    let free_node = (*pool).next;
    (*pool).next = (*pool).next.offset(1);
    free_node
}

/**
 * Performs a Boundary Package-Merge step. Puts a new chain in the given list. The
 * new chain is, depending on the weights, a leaf or a combination of two chains
 * from the previous list.
 * lists: The lists of chains.
 * maxbits: Number of lists.
 * leaves: The leaves, one per symbol.
 * numsymbols: Number of leaves.
 * pool: the node memory pool.
 * index: The index of the list in which a new chain or leaf is required.
 * final: Whether this is the last time this function is called. If it is then it
 *   is no more needed to recursively call self.
 */
unsafe fn boundary_pm(lists: *const *mut *mut Node, maxbits: i32, leaves: *const Node, numsymbols: i32, pool: *mut NodePool,
                      index: i32, is_final: bool) {
    let lastcount = (**(*lists.offset(index as isize)).offset(1)).count; // Count of last chain of list.

    if index == 0 && lastcount >= numsymbols {
        return;
    }

    let newchain = get_free_node(lists, maxbits, pool);
    let oldchain = *(*lists.offset(index as isize)).offset(1);

    // These are set up before the recursive calls below, so that there is a list
    // pointing to the new node, to let the garbage collection know it's in use.
    *(*lists.offset(index as isize)).offset(0) = oldchain;
    *(*lists.offset(index as isize)).offset(1) = newchain;

    if index == 0 {
        //New leaf node in list 0.
        init_node((*leaves.offset(lastcount as isize)).weight, lastcount + 1, null_mut(), newchain);
    } else {
        let sum = (**(*lists.offset((index - 1) as isize)).offset(0)).weight + (**(*lists.offset((index - 1) as isize)).offset(0)).weight;
        if lastcount < numsymbols && sum > (*leaves.offset(lastcount as isize)).weight {
            // New leaf inserted in list, so count is incremented.
            init_node((*leaves.offset(lastcount as isize)).weight, lastcount + 1, (*oldchain).tail, newchain);
        } else {
            init_node(sum, lastcount, *(*lists.offset((index - 1) as isize)).offset(1), newchain);
            if !is_final {
                // Two lookahead chains of previous list used up, create new ones.
                boundary_pm(lists, maxbits, leaves, numsymbols, pool, index - 1, false);
                boundary_pm(lists, maxbits, leaves, numsymbols, pool, index - 1, false);
            }
        }
    }
}

/// Initializes each list with as lookahead chains the two leaves with lowest weights.
unsafe fn init_lists(pool: *mut NodePool, leaves: *const Node, maxbits: i32, lists: *const *mut *mut Node) {
    let node0 = get_free_node(null(), maxbits, pool);
    let node1 = get_free_node(null(), maxbits, pool);
    init_node((*leaves.offset(0)).weight, 1, null_mut(), node0);
    init_node((*leaves.offset(1)).weight, 2, null_mut(), node1);
    for i in 0..maxbits {
        *(*lists.offset(i as isize)).offset(0) = node0;
        *(*lists.offset(i as isize)).offset(1) = node1;
    }
}

/**
 * Converts result of boundary package-merge to the bitlengths. The result in the
 * last chain of the last list contains the amount of active leaves in each list.
 * chain: Chain to extract the bit length from (last chain from last list).
 */
unsafe fn extract_bit_lengths(chain: *const Node, leaves: *const Node, bitlengths: *mut u32) {
    let mut node = chain;
    while node != null() {
        for i in 0..(*node).count {
            *bitlengths.offset((*leaves.offset(i as isize)).count as isize) = *bitlengths.offset((*leaves.offset(i as isize)).count as isize) + 1;
        }
        node = (*node).tail;
    }
}

/// Comparator for sorting the leaves. Has the function signature for qsort.
extern fn leaf_comparator(a: *const c_void, b: *const c_void) -> i32 {
    unsafe {
        let node_a: *const Node = a as *const Node;
        let node_b: *const Node = b as *const Node;
        (*node_a).weight as i32 - (*node_b).weight as i32
    }
}

#[link(name="c")]
extern {
    fn qsort(base: *mut c_void, nmemb: size_t, size: size_t, compar: extern fn(*const c_void, *const c_void) -> i32);
}

pub unsafe fn length_limited_code_lengths(frequencies: *const usize, n: i32, maxbits: i32, bitlengths: *mut u32) -> bool {
    // Amount of symbols with frequency > 0.
    let mut numsymbols = 0;

    // One leaf per symbol. Only numsymbols leaves will be used.
    let leaves: *mut Node = malloc((n as usize * mem::size_of::<Node>()) as size_t) as *mut Node;

    // Initialize all bitlengths at 0.
    for i in 0..n {
        *bitlengths.offset(i as isize) = 0;
    }

    // Count used symbols and place them in the leaves.
    for i in 0..n {
        if *frequencies.offset(i as isize) != 0 {
            (*leaves.offset(numsymbols)).weight = *frequencies.offset(i as isize);
            (*leaves.offset(numsymbols)).count = i;
            numsymbols = numsymbols + 1;
        }
    }

    // Check special cases and error conditions.
    if (1 << maxbits) < numsymbols {
        free(leaves as *mut c_void);
        return true; // Error, too few maxbits to represent symbols.
    }
    if numsymbols == 0 {
        free(leaves as *mut c_void);
        return false; // No symbols at all. OK.
    }
    if numsymbols == 1 {
        *bitlengths.offset((*leaves.offset(0)).count as isize) = 1;
        free(leaves as *mut c_void);
        return false; // Only one symbol, give it bitlength 1, not 0. OK.
    }

    // Sort the leaves from lightest to heaviest.
    qsort(leaves as *mut c_void, numsymbols as size_t, mem::size_of::<Node>() as size_t, leaf_comparator);

    // Initialize node memory pool.
    let pool_size = 2 * maxbits * (maxbits + 1);
    let pool_nodes = malloc((pool_size as usize * mem::size_of::<Node>()) as size_t) as *mut Node;
    let mut pool = NodePool { size: pool_size as u32, nodes: pool_nodes, next: pool_nodes };
    for i in 0..pool.size {
        (*pool.nodes.offset(i as isize)).in_use = false;
    }

    // Array of lists of chains. Each list requires only two lookahead chains at
    // a time, so each list is a array of two Node*'s.
    let lists: *const *mut *mut Node = malloc((maxbits as usize * mem::size_of::<*const *const Node>()) as size_t) as *const *mut *mut Node;
    init_lists(&mut pool, leaves, maxbits, lists);

    // In the last list, 2 * numsymbols - 2 active chains need to be created. Two
    // are already created in the initialization. Each BoundaryPM run creates one.
    let num_boundary_pm_runs = 2 * numsymbols - 4;
    for i in 0..num_boundary_pm_runs {
        let is_final = i == num_boundary_pm_runs - 1;
        boundary_pm(lists, maxbits, leaves, numsymbols as i32, &mut pool, maxbits - 1, is_final);
    }

    extract_bit_lengths(*(*lists.offset(maxbits as isize - 1)).offset(1), leaves, bitlengths);

    free(lists as *mut c_void);
    free(leaves as *mut c_void);
    free(pool.nodes as *mut c_void);
    false
}

#[cfg(test)]
mod tests {
    use std::mem::size_of;
    use libc::{c_void, size_t};

    use super::qsort;

    extern fn comparator(a: *const c_void, b: *const c_void) -> i32 {
        unsafe {
            *(a as *const i32) - *(b as *const i32)
        }
    }

    #[test]
    fn test_qsort() {
        unsafe {
            let mut a: [i32; 5] = [3, 2, 4, 1, 5];
            qsort(a.as_mut_ptr() as *mut c_void, a.len() as size_t, size_of::<i32>() as size_t, comparator);
            assert_eq!(a, [1, 2, 3, 4, 5]);
        }
    }
}
<|endoftext|>


<commit_before>//! Layout handling

// remove
#![allow(unused)]

use rustwlc::handle::{WlcView, WlcOutput};
use rustwlc::types::VIEW_MAXIMIZED;
use std::rc::{Rc, Weak};
use std::fmt::{Debug, Formatter};
use std::fmt::Result as FmtResult;
use std::cell::RefCell;

pub type Node = Rc<RefCell<Container>>;

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Handle {
    View(WlcView),
    Output(WlcOutput)
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ContainerType {
    /// Root container, only one exists
    Root,
    /// WlcOutput/Monitor
    Output,
    /// A workspace
    Workspace,
    /// A Container, houses views and other containers
    Container,
    /// A view (window)
    View
}

/// Layout mode for a container
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Layout {
    Horizontal,
    Vertical,
    Stacked,
    Tabbed,
    Floating
}

#[derive(Clone)]
pub struct Container {
    handle: Option<Handle>,
    parent: Option<Weak<RefCell<Container>>>,
    children: Vec<Node>,
    container_type: ContainerType,
    layout: Option<Layout>,
    visible: bool,
    is_focused: bool,
    is_floating: bool,
}

/// Like i3, everything (workspaces, containers, views) are containable.
impl Container {

    /// Makes the root container. There should be only one of these
    /// Does not ensure that this is the only root container
    pub fn new_root() -> Node {
        trace!("Root created");
        Rc::new(RefCell::new(Container {
            handle: None,
            parent: None,
            children: vec!(),
            container_type: ContainerType::Root,
            layout: None,
            visible: false,
            is_focused: false,
            is_floating: false
        }))
    }

    /// Makes a new output. These can only be children of the root node. They
    /// contain information about which monitor (output) its children are being
    /// displayed on.
    pub fn new_output(root: &mut Node, wlc_output: WlcOutput) -> Node {
        if ! root.borrow().is_root() {
            panic!("Output containers can only be children of the root, not {:?}", root.borrow().get_type());
        }

        let size = wlc_output.get_resolution();
        let output = Rc::new(RefCell::new(Container {
            handle: Some(Handle::Output(wlc_output.clone())),
            parent: Some(Rc::downgrade(&root)),
            children: vec!(),
            container_type: ContainerType::Output,
            layout: None,
            visible: false,
            is_focused: false,
            is_floating: false
        }));
        // NOTE Should automatically add a new workspace here, there are edge
        // cases to worry about though so leaving that out for now
        add_child(root.clone(), output.clone());
        output
    }

    /// Makes a new workspace container. These can only be attached to output
    /// containers. They will inherit the output of the parent container.
    pub fn new_workspace(parent_: &mut Node) -> Node {
        let parent = parent_.borrow();
        if parent.get_type() != ContainerType::Output {
            panic!("Workspaces can only be children of an output container, not {:?}", parent.get_type());
        }
        let workspace: Node =
            Rc::new(RefCell::new(Container {
                handle: Some(parent.get_handle().expect("Workspace could not get handle from output parent")),
                parent: Some(Rc::downgrade(&parent_)),
                children: vec!(),
                container_type: ContainerType::Workspace,
                layout: Some(Layout::Horizontal),
                visible: false,
                is_focused: false,
                is_floating: false,
                }));
        drop(parent);
        add_child(parent_.clone(), workspace.clone());
        trace!("Workspace created");
        workspace
    }

    /// Makes a new container. These hold views and other containers.
    /// Container hold information about specific parts of the tree in some
    /// workspace and the layout of the views within.
    pub fn new_container(parent_: &mut Node, mut layout: Layout) -> Node {
        let mut parent = parent_.borrow_mut();
        if ! (parent.get_type() == ContainerType::Container
            || parent.get_type() == ContainerType::Workspace) {
            panic!("Container can only be child of container or workspace, not {:?}", parent.get_type());
        }
        let output = parent.get_handle().expect("Container could not get handle from parent");
        // NOTE Make sure we do all of the Container specific init stuff
        let container = Rc::new(RefCell::new(Container {
            handle: Some(output),
            parent: Some(Rc::downgrade(&parent_)),
            children: vec!(),
            container_type: ContainerType::Container,
            layout: Some(layout),
            visible: false,
            is_focused: false,
            is_floating: false,
        }));
        if parent.get_type() == ContainerType::Workspace {
            let mut workspace = parent;
            if let Some(layout) = workspace.get_layout() {
                container.borrow_mut().set_layout(layout);
            }
            drop(workspace);
            add_child(parent_.clone(), container.clone());
        } else {
            // Need to add the "parent" as the child of the container we just made.
            drop(parent);
            let child_ = parent_.clone();
            let child = child_.borrow();
            let parent_of_child = child.get_parent().expect("Parent container has no parent");
            let child_clone = Rc::make_mut(&mut child_.clone()).clone().into_inner();
            // Need to remove the child from their parent
            parent_of_child.borrow_mut().remove_child(&child_clone.clone());
            // Add the container we just made as a child, replacing the one we removed
            add_child(parent_of_child.clone(), container.clone());
            // The new container is now a child of the old child's parent
            drop(child);
            add_child(container.clone(), child_.clone());
        }
        trace!("Container created");
        container
    }

    /// Makes a new view. A view holds either a Wayland or an X Wayland window.
    pub fn new_view(parent_: &mut Node, wlc_view: WlcView) -> Node {
        let parent = parent_.borrow();
        if parent.is_root() {
            panic!("View cannot be a direct child of root, not {:?}", parent.get_type());
        }
        let view = Rc::new(RefCell::new(Container {
            handle: Some(Handle::View(wlc_view.clone())),
            parent: Some(Rc::downgrade(&parent_)),
            children: vec!(),
            container_type: ContainerType::View,
            layout: None,
            visible: false,
            is_focused: false,
            is_floating: false
        }));
        if parent.get_type() == ContainerType::Workspace {
            drop(parent);
            // Case of focused workspace, just create a child of it
            add_child(parent_.clone(), view.clone());
        } else {
            drop(parent);
            // Case of focused workspace, just create a child of it
            // Regular case, create as sibling of current container
            add_sibling(parent_.clone(), view.clone()).unwrap();
        }
        trace!("View created");
        view
    }

    /// Gets the parent that this container sits in.
    ///
    /// If the container is the root, it returns None
    pub fn get_parent(&self) -> Option<Node> {
        if self.is_root() {
            None
        } else {
            if let Some(parent) = self.parent.clone() {
                parent.upgrade()
            } else {
                None
            }
        }
    }

    /// Sets the parent of this container
    pub fn set_parent(&mut self, parent: Weak<RefCell<Container>>) -> Result<(), &'static str> {
        if self.is_root() {
            return Err("Root does not have a parent");
        }
        self.parent = Some(parent);
        Ok(())
    }

    /// Removes this container and all of its children.
    /// You MUST call this function while `borrow`ing, a mutable borrow will
    /// cause it to panic at run time
    pub fn remove_container(&self) -> Result<(), &'static str> {
        if self.is_root() {
            return Err("Cannot remove root container");
        } else if self.get_type() == ContainerType::Workspace  {
            return Err("Cannot remove workspace container");
        }
        if let Some(parent) = self.get_parent() {
            trace!("Borrowing container {:?} (parent of {:?}) as mutable", parent, self);
            parent.borrow_mut().remove_child(self);
        }
        Ok(())
    }

    /// Gets the children of this container.
    ///
    /// Views never have children
    pub fn get_children(&self) -> Option<&[Node]> {
        if self.get_type() == ContainerType::View {
            None
        }
        else {
            Some(self.children.as_slice())
        }
    }

    /// Gets the type of the container
    pub fn get_type(&self) -> ContainerType {
        self.container_type
    }

    /// Gets the handle of the container. This could either be an output (a
    /// monitor), or a view (a Wayland or X Wayland Window)
    pub fn get_handle(&self) -> Option<Handle> {
        self.handle.clone()
    }

    /// Gets the layout of the container, if there is one.
    pub fn get_layout(&self) -> Option<Layout> {
        self.layout
    }

    /// Returns true if this container is focused.
    pub fn is_focused(&self) -> bool {
        self.is_focused
    }

    /// Removes the child at the specified index
    pub fn remove_child_at(&mut self, index: usize) -> Result<Node, &'static str> {
        if self.children[index].borrow().get_type() == ContainerType::Workspace {
            return Err("Cannot remove workspace")
        }
        Ok(self.children.remove(index))
    }

    /// Removes the given child from this container's children.
    /// If the child is not present, then an error is returned
    pub fn remove_child(&mut self, node: &Container) -> Result<Node, &'static str> {
        for (index, child) in self.children.clone().iter().enumerate() {
            if *child.borrow() == *node {
                if child.borrow().get_type() == ContainerType::Workspace {
                    return Err("Can not remove workspace");
                }
                return Ok(self.children.remove(index));
            }
        }
        return Err("Could not find child in container");//format!("Could not find child {:?} in {:?}", node, self));
    }

    /// Sets this container (and everything in it) to given visibility
    pub fn set_visibility(&mut self, visibility: bool) {
        self.visible = visibility
    }

    /// Sets the layout of the container.
    pub fn set_layout(&mut self, layout: Layout) {
        self.layout = Some(layout)
    }

    /// Gets the visibility of the container
    pub fn get_visibility(&self) -> bool {
        self.visible
    }

    /// Gets the X and Y dimensions of the container. Width is the first
    /// value, height is the second.
    pub fn get_dimensions(&self) -> Option<(u32, u32)> {
        if let Some(ref handle) = self.handle {
            match handle {
                &Handle::Output(ref output) => {
                    let size = output.get_resolution();
                    Some((size.w, size.h))
                }
                &Handle::View(ref view) => {
                    let ref size = view.get_geometry().expect("View did not have a geometry").size;
                    Some((size.w, size.h))
                }
            }
        } else {
            None
        }
    }

    /// Gets the position of this container on the screen.
    pub fn get_position(&self) -> Option<(i32, i32)> {
        if let Some(ref handle) = self.handle {
            match handle {
                &Handle::Output(ref output) => None,
                &Handle::View(ref view) => {
                    let ref origin = view.get_geometry().expect("View did not have a geometry").origin;
                    Some((origin.x, origin.y))
                }
            }
        } else {
            None
        }
    }

    /// Returns true if this container is a parent of the child
    pub fn is_parent_of(&self, child: Node) -> bool {
        if self.is_root() {
            true
        } else {
            while ! child.borrow().is_root() {
                let parent = child.borrow().get_parent().expect("Could not get parent, was removed from tree");
                if child == parent {
                    return true
                }
            }
            return false;
        }
    }

    /// Returns true if this container is a child is an decedent of the parent
    pub fn is_child_of(&self, parent: Node) -> bool {
        parent.borrow().is_parent_of(Rc::new(RefCell::new(self.clone())))
    }

    pub fn is_root(&self) -> bool {
        self.get_type() == ContainerType::Root
    }

    /// Finds a parent container with the given type, if there is any
    pub fn get_parent_by_type(&self, container_type: ContainerType) -> Option<Node> {
        let mut container = self.get_parent();
        loop {
            if let Some(parent) = container {
                if parent.borrow().get_type() == container_type {
                    return Some(parent);
                }
                container = parent.borrow().get_parent();
            } else {
                return None;
            }
        }
    }
}

pub fn add_child(parent: Node, child: Node) -> Result<(), &'static str> {
    if parent.borrow().get_type() == ContainerType::Workspace
        && child.borrow().get_type() == ContainerType::Workspace {
        return Err("Only containers can be children of a workspace");
    } else if parent.borrow().get_type() == ContainerType::View {
        return Err("Cannot add child to a view");
    }
    child.borrow_mut().set_parent(Rc::downgrade(&parent.clone()));
    parent.borrow_mut().children.push(child);
    Ok(())
}

pub fn add_sibling(current_node: Node, new_sibling: Node) -> Result<(), &'static str> {
    if current_node.borrow().is_root() {
        return Err("Root has no sibling, cannot add sibling to root");
    }
    let parent = current_node.borrow().get_parent().expect("Could not get parent, was removed from tree");
    trace!("Borrowing container {:?} (parent of {:?}) as mutable", parent, current_node);
    drop(current_node);
    add_child(parent.clone(), new_sibling);
    Ok(())
}

impl PartialEq for Container {
    fn eq(&self, other: &Container) -> bool {
        if self.get_type() == other.get_type() {
            if let Some(self_handle) = self.get_handle() {
                if let Some(other_handle) = other.get_handle() {
                    if self_handle == other_handle {
                        return true
                    }
                }
            } else {
                return self.get_handle().is_none() && other.get_handle().is_none()
            }
        }
        return false
    }
}

impl Eq for Container { }

impl Debug for Container {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        f.debug_struct("Containable")
            .field("type", &self.get_type())
            //.field("parent", &self.get_parent())
            .field("children", &self.get_children())
            .field("focused", &self.is_focused())
            .finish()
    }
}
<commit_msg>Removed old.rs<commit_after><|endoftext|>


<commit_before>use core::ops::{Div, Rem};
pub trait DivEuclid: Sized + Div<Self, Output = Self> {
    /// Calculates Euclidean division, the matching method for `rem_euclid`.
    ///
    /// This computes the integer `n` such that
    /// `self = n * v + self.rem_euclid(v)`.
    /// In other words, the result is `self / v` rounded to the integer `n`
    /// such that `self >= n * v`.
    ///
    /// # Examples
    ///
    /// ```
    /// use num_traits::DivEuclid;
    ///
    /// let a: i32 = 7;
    /// let b: i32 = 4;
    /// assert_eq!(DivEuclid::div_euclid(a,b), 1); // 7 > 4 * 1
    /// assert_eq!(DivEuclid::div_euclid(-a,b), -2); // -7 >= 4 * -2
    /// assert_eq!(DivEuclid::div_euclid(a,-b), -1); // 7 >= -4 * -1
    /// assert_eq!(DivEuclid::div_euclid(-a,-b), 2); // -7 >= -4 * 2
    /// ```
    fn div_euclid(self, v: Self) -> Self;
}
pub trait RemEuclid: Sized + Rem<Self, Output = Self> {
    /// Calculates the least nonnegative remainder of `self (mod v)`.
    ///
    /// In particular, the return value `r` satisfies `0.0 <= r < v.abs()` in
    /// most cases. However, due to a floating point round-off error it can
    /// result in `r == v.abs()`, violating the mathematical definition, if
    /// `self` is much smaller than `v.abs()` in magnitude and `self < 0.0`.
    /// This result is not an element of the function's codomain, but it is the
    /// closest floating point number in the real numbers and thus fulfills the
    /// property `self == self.div_euclid(v) * v + self.rem_euclid(v)`
    /// approximatively.
    ///
    /// # Examples
    ///
    /// ```
    /// use num_traits::RemEuclid;
    ///
    /// let a: i32 = 7;
    /// let b: i32 = 4;
    /// assert_eq!(RemEuclid::rem_euclid(a,b), 3);
    /// assert_eq!(RemEuclid::rem_euclid(-a,b), 1);
    /// assert_eq!(RemEuclid::rem_euclid(a,-b), 3);
    /// assert_eq!(RemEuclid::rem_euclid(-a,-b), 1);
    /// ```
    fn rem_euclid(self, v: Self) -> Self;
}
macro_rules! div_euclid_int_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn div_euclid(self, v: $t) -> Self {
                let q = self / v;
                if self % v < 0 {
                    return if v > 0 { q - 1 } else { q + 1 }
                }
                q
            }
        }
    )*}
}
macro_rules! div_euclid_uint_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn div_euclid(self, v: $t) -> Self {
                self / v
            }
        }
    )*}
}
macro_rules! rem_euclid_int_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn rem_euclid(self, v: $t) -> Self {
                let r = self % v;
                if r < 0 {
                    if v < 0 {
                        r - v
                    } else {
                        r + v
                    }
                } else {
                    r
                }
            }
        }
    )*}
}
macro_rules! rem_euclid_uint_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn rem_euclid(self, v: $t) -> Self {
                self % v
            }
        }
    )*}
}
div_euclid_int_impl!(DivEuclid for i8 i16 i32 i64);
div_euclid_uint_impl!(DivEuclid for isize usize u8 u16 u32 u64);
rem_euclid_int_impl!(RemEuclid for i8 i16 i32 i64);
rem_euclid_uint_impl!(RemEuclid for isize usize u8 u16 u32 u64);
#[cfg(has_i128)]
div_euclid_int_impl!(DivEuclid for i128);
#[cfg(has_i128)]
div_euclid_uint_impl!(DivEuclid for u128);
#[cfg(has_i128)]
rem_euclid_int_impl!(RemEuclid for i128);
#[cfg(has_i128)]
rem_euclid_uint_impl!(RemEuclid for u128);

#[cfg(any(feature = "std", feature = "libm"))]
impl DivEuclid for f32 {
    fn div_euclid(self, v: f32) -> f32 {
        let q = <f32 as ::Float>::trunc(self / v);
        if self % v < 0.0 {
            return if v > 0.0 { q - 1.0 } else { q + 1.0 };
        }
        q
    }
}

#[cfg(any(feature = "std", feature = "libm"))]
impl RemEuclid for f32 {
    fn rem_euclid(self, v: f32) -> f32 {
        let r = self % v;
        if r < 0.0 {
            r + <f32 as ::Float>::abs(v)
        } else {
            r
        }
    }
}

#[cfg(any(feature = "std", feature = "libm"))]
impl DivEuclid for f64 {
    fn div_euclid(self, v: f64) -> f64 {
        let q = <f64 as ::Float>::trunc(self / v);
        if self % v < 0.0 {
            return if v > 0.0 { q - 1.0 } else { q + 1.0 };
        }
        q
    }
}
#[cfg(any(feature = "std", feature = "libm"))]
impl RemEuclid for f64 {
    fn rem_euclid(self, v: f64) -> f64 {
        let r = self % v;
        if r < 0.0 {
            r + <f64 as ::Float>::abs(v)
        } else {
            r
        }
    }
}

pub trait CheckedDivEuclid: DivEuclid {
    /// Performs euclid division that returns `None` instead of panicking on division by zero
    /// and instead of wrapping around on underflow and overflow.
    fn checked_div_euclid(self, v: Self) -> Option<Self>;
}
pub trait CheckedRemEuclid: RemEuclid {
    /// Finds the euclid remainder of dividing two numbers, checking for underflow, overflow and
    /// division by zero. If any of that happens, `None` is returned.
    fn checked_rem_euclid(self, v: Self) -> Option<Self>;
}
macro_rules! checked_div_euclid_int_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn checked_div_euclid(self, v: $t) -> Option<$t> {
                if v == 0 || (self == Self::min_value() && v == -1) {
                    None
                } else {
                    Some(DivEuclid::div_euclid(self,v))
                }
            }
        }
    )*}
}
macro_rules! checked_div_euclid_uint_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn checked_div_euclid(self, v: $t) -> Option<$t> {
                if v == 0{
                    None
                } else {
                    Some(DivEuclid::div_euclid(self,v))
                }
            }
        }
    )*}
}
macro_rules! checked_rem_euclid_int_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn checked_rem_euclid(self, v: $t) -> Option<$t> {
                if v == 0 || (self == Self::min_value() && v == -1) {
                    None
                } else {
                    Some(RemEuclid::rem_euclid(self,v))
                }
            }
        }
    )*}
}
macro_rules! checked_rem_euclid_uint_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn checked_rem_euclid(self, v: $t) -> Option<$t> {
                if v == 0{
                    None
                } else {
                    Some(RemEuclid::rem_euclid(self,v))
                }
            }
        }
    )*}
}
checked_div_euclid_int_impl!(CheckedDivEuclid for i8 i16 i32 i64);
checked_div_euclid_uint_impl!(CheckedDivEuclid for isize usize u8 u16 u32 u64);
checked_rem_euclid_int_impl!(CheckedRemEuclid for i8 i16 i32 i64);
checked_rem_euclid_uint_impl!(CheckedRemEuclid for isize usize u8 u16 u32 u64);
#[cfg(has_i128)]
checked_div_euclid_int_impl!(CheckedDivEuclid for i128);
#[cfg(has_i128)]
checked_div_euclid_uint_impl!(CheckedDivEuclid for u128);
#[cfg(has_i128)]
checked_rem_euclid_int_impl!(CheckedRemEuclid for i128);
#[cfg(has_i128)]
checked_rem_euclid_uint_impl!(CheckedRemEuclid for u128);

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

    #[test]
    fn euclid_unsigned() {
        macro_rules! test_euclid {
            ($($t:ident)+) => {
                $(
                    {
                        let x: $t = 10;
                        let y: $t = 3;
                        assert_eq!(DivEuclid::div_euclid(x,y),3);
                        assert_eq!(RemEuclid::rem_euclid(x,y),1);
                    }
                )+
            };
        }

        test_euclid!(usize u8 u16 u32 u64 isize);
    }

    #[test]
    fn euclid_signed() {
        macro_rules! test_euclid {
            ($($t:ident)+) => {
                $(
                    {
                        let x: $t = 10;
                        let y: $t = -3;
                        assert_eq!(DivEuclid::div_euclid(x,y),-3);
                        assert_eq!(DivEuclid::div_euclid(-x,y),4);
                        assert_eq!(RemEuclid::rem_euclid(x,y),1);
                        assert_eq!(RemEuclid::rem_euclid(-x,y),2);
                        let x: $t = $t::min_value()+1;
                        let y: $t = -1;
                        assert_eq!(DivEuclid::div_euclid(x,y),$t::MAX);
                    }
                )+
            };
        }

        test_euclid!(i8 i16 i32 i64);
    }

    #[test]
    #[cfg(any(feature = "std", feature = "libm"))]
    fn euclid_float() {
        macro_rules! test_euclid {
            ($($t:ident)+) => {
                $(
                    {
                        let x: $t = 12.1;
                        let y: $t = 3.2;
                        assert!(DivEuclid::div_euclid(x,y)*y+RemEuclid::rem_euclid(x,y)-x
                        <=46.4 * $t::EPSILON);
                        assert!(DivEuclid::div_euclid(x,-y)*-y+RemEuclid::rem_euclid(x,-y)-x
                        <= 46.4 * $t::EPSILON);
                        assert!(DivEuclid::div_euclid(-x,y)*y+RemEuclid::rem_euclid(-x,y)-(-x)
                        <= 46.4 * $t::EPSILON);
                        assert!(DivEuclid::div_euclid(-x,-y)*-y+RemEuclid::rem_euclid(-x,-y)-(-x)
                        <= 46.4 * $t::EPSILON);
                    }
                )+
            };
        }

        test_euclid!(f32 f64);
    }

    #[test]
    fn euclid_checked() {
        macro_rules! test_euclid_checked {
            ($($t:ident)+) => {
                $(
                    {
                        assert_eq!(CheckedDivEuclid::checked_div_euclid($t::min_value(),-1),None);
                        assert_eq!(CheckedRemEuclid::checked_rem_euclid($t::min_value(),-1),None);
                        assert_eq!(CheckedDivEuclid::checked_div_euclid(1,0),None);
                        assert_eq!(CheckedRemEuclid::checked_rem_euclid(1,0),None);
                    }
                )+
            };
        }

        test_euclid_checked!(i8 i16 i32 i64);
    }
}
<commit_msg>Fixes epsilon<commit_after>use core::ops::{Div, Rem};
pub trait DivEuclid: Sized + Div<Self, Output = Self> {
    /// Calculates Euclidean division, the matching method for `rem_euclid`.
    ///
    /// This computes the integer `n` such that
    /// `self = n * v + self.rem_euclid(v)`.
    /// In other words, the result is `self / v` rounded to the integer `n`
    /// such that `self >= n * v`.
    ///
    /// # Examples
    ///
    /// ```
    /// use num_traits::DivEuclid;
    ///
    /// let a: i32 = 7;
    /// let b: i32 = 4;
    /// assert_eq!(DivEuclid::div_euclid(a,b), 1); // 7 > 4 * 1
    /// assert_eq!(DivEuclid::div_euclid(-a,b), -2); // -7 >= 4 * -2
    /// assert_eq!(DivEuclid::div_euclid(a,-b), -1); // 7 >= -4 * -1
    /// assert_eq!(DivEuclid::div_euclid(-a,-b), 2); // -7 >= -4 * 2
    /// ```
    fn div_euclid(self, v: Self) -> Self;
}
pub trait RemEuclid: Sized + Rem<Self, Output = Self> {
    /// Calculates the least nonnegative remainder of `self (mod v)`.
    ///
    /// In particular, the return value `r` satisfies `0.0 <= r < v.abs()` in
    /// most cases. However, due to a floating point round-off error it can
    /// result in `r == v.abs()`, violating the mathematical definition, if
    /// `self` is much smaller than `v.abs()` in magnitude and `self < 0.0`.
    /// This result is not an element of the function's codomain, but it is the
    /// closest floating point number in the real numbers and thus fulfills the
    /// property `self == self.div_euclid(v) * v + self.rem_euclid(v)`
    /// approximatively.
    ///
    /// # Examples
    ///
    /// ```
    /// use num_traits::RemEuclid;
    ///
    /// let a: i32 = 7;
    /// let b: i32 = 4;
    /// assert_eq!(RemEuclid::rem_euclid(a,b), 3);
    /// assert_eq!(RemEuclid::rem_euclid(-a,b), 1);
    /// assert_eq!(RemEuclid::rem_euclid(a,-b), 3);
    /// assert_eq!(RemEuclid::rem_euclid(-a,-b), 1);
    /// ```
    fn rem_euclid(self, v: Self) -> Self;
}
macro_rules! div_euclid_int_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn div_euclid(self, v: $t) -> Self {
                let q = self / v;
                if self % v < 0 {
                    return if v > 0 { q - 1 } else { q + 1 }
                }
                q
            }
        }
    )*}
}
macro_rules! div_euclid_uint_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn div_euclid(self, v: $t) -> Self {
                self / v
            }
        }
    )*}
}
macro_rules! rem_euclid_int_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn rem_euclid(self, v: $t) -> Self {
                let r = self % v;
                if r < 0 {
                    if v < 0 {
                        r - v
                    } else {
                        r + v
                    }
                } else {
                    r
                }
            }
        }
    )*}
}
macro_rules! rem_euclid_uint_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn rem_euclid(self, v: $t) -> Self {
                self % v
            }
        }
    )*}
}
div_euclid_int_impl!(DivEuclid for i8 i16 i32 i64);
div_euclid_uint_impl!(DivEuclid for isize usize u8 u16 u32 u64);
rem_euclid_int_impl!(RemEuclid for i8 i16 i32 i64);
rem_euclid_uint_impl!(RemEuclid for isize usize u8 u16 u32 u64);
#[cfg(has_i128)]
div_euclid_int_impl!(DivEuclid for i128);
#[cfg(has_i128)]
div_euclid_uint_impl!(DivEuclid for u128);
#[cfg(has_i128)]
rem_euclid_int_impl!(RemEuclid for i128);
#[cfg(has_i128)]
rem_euclid_uint_impl!(RemEuclid for u128);

#[cfg(any(feature = "std", feature = "libm"))]
impl DivEuclid for f32 {
    fn div_euclid(self, v: f32) -> f32 {
        let q = <f32 as ::Float>::trunc(self / v);
        if self % v < 0.0 {
            return if v > 0.0 { q - 1.0 } else { q + 1.0 };
        }
        q
    }
}

#[cfg(any(feature = "std", feature = "libm"))]
impl RemEuclid for f32 {
    fn rem_euclid(self, v: f32) -> f32 {
        let r = self % v;
        if r < 0.0 {
            r + <f32 as ::Float>::abs(v)
        } else {
            r
        }
    }
}

#[cfg(any(feature = "std", feature = "libm"))]
impl DivEuclid for f64 {
    fn div_euclid(self, v: f64) -> f64 {
        let q = <f64 as ::Float>::trunc(self / v);
        if self % v < 0.0 {
            return if v > 0.0 { q - 1.0 } else { q + 1.0 };
        }
        q
    }
}
#[cfg(any(feature = "std", feature = "libm"))]
impl RemEuclid for f64 {
    fn rem_euclid(self, v: f64) -> f64 {
        let r = self % v;
        if r < 0.0 {
            r + <f64 as ::Float>::abs(v)
        } else {
            r
        }
    }
}

pub trait CheckedDivEuclid: DivEuclid {
    /// Performs euclid division that returns `None` instead of panicking on division by zero
    /// and instead of wrapping around on underflow and overflow.
    fn checked_div_euclid(self, v: Self) -> Option<Self>;
}
pub trait CheckedRemEuclid: RemEuclid {
    /// Finds the euclid remainder of dividing two numbers, checking for underflow, overflow and
    /// division by zero. If any of that happens, `None` is returned.
    fn checked_rem_euclid(self, v: Self) -> Option<Self>;
}
macro_rules! checked_div_euclid_int_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn checked_div_euclid(self, v: $t) -> Option<$t> {
                if v == 0 || (self == Self::min_value() && v == -1) {
                    None
                } else {
                    Some(DivEuclid::div_euclid(self,v))
                }
            }
        }
    )*}
}
macro_rules! checked_div_euclid_uint_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn checked_div_euclid(self, v: $t) -> Option<$t> {
                if v == 0{
                    None
                } else {
                    Some(DivEuclid::div_euclid(self,v))
                }
            }
        }
    )*}
}
macro_rules! checked_rem_euclid_int_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn checked_rem_euclid(self, v: $t) -> Option<$t> {
                if v == 0 || (self == Self::min_value() && v == -1) {
                    None
                } else {
                    Some(RemEuclid::rem_euclid(self,v))
                }
            }
        }
    )*}
}
macro_rules! checked_rem_euclid_uint_impl {
    ($trait_name:ident for $($t:ty)*) => {$(
        impl $trait_name for $t {
            #[inline]
            fn checked_rem_euclid(self, v: $t) -> Option<$t> {
                if v == 0{
                    None
                } else {
                    Some(RemEuclid::rem_euclid(self,v))
                }
            }
        }
    )*}
}
checked_div_euclid_int_impl!(CheckedDivEuclid for i8 i16 i32 i64);
checked_div_euclid_uint_impl!(CheckedDivEuclid for isize usize u8 u16 u32 u64);
checked_rem_euclid_int_impl!(CheckedRemEuclid for i8 i16 i32 i64);
checked_rem_euclid_uint_impl!(CheckedRemEuclid for isize usize u8 u16 u32 u64);
#[cfg(has_i128)]
checked_div_euclid_int_impl!(CheckedDivEuclid for i128);
#[cfg(has_i128)]
checked_div_euclid_uint_impl!(CheckedDivEuclid for u128);
#[cfg(has_i128)]
checked_rem_euclid_int_impl!(CheckedRemEuclid for i128);
#[cfg(has_i128)]
checked_rem_euclid_uint_impl!(CheckedRemEuclid for u128);

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

    #[test]
    fn euclid_unsigned() {
        macro_rules! test_euclid {
            ($($t:ident)+) => {
                $(
                    {
                        let x: $t = 10;
                        let y: $t = 3;
                        assert_eq!(DivEuclid::div_euclid(x,y),3);
                        assert_eq!(RemEuclid::rem_euclid(x,y),1);
                    }
                )+
            };
        }

        test_euclid!(usize u8 u16 u32 u64 isize);
    }

    #[test]
    fn euclid_signed() {
        macro_rules! test_euclid {
            ($($t:ident)+) => {
                $(
                    {
                        let x: $t = 10;
                        let y: $t = -3;
                        assert_eq!(DivEuclid::div_euclid(x,y),-3);
                        assert_eq!(DivEuclid::div_euclid(-x,y),4);
                        assert_eq!(RemEuclid::rem_euclid(x,y),1);
                        assert_eq!(RemEuclid::rem_euclid(-x,y),2);
                        let x: $t = $t::min_value()+1;
                        let y: $t = -1;
                        assert_eq!(DivEuclid::div_euclid(x,y),$t::max_value());
                    }
                )+
            };
        }

        test_euclid!(i8 i16 i32 i64);
    }

    #[test]
    #[cfg(any(feature = "std", feature = "libm"))]
    fn euclid_float() {
        macro_rules! test_euclid {
            ($($t:ident)+) => {
                $(
                    {
                        let x: $t = 12.1;
                        let y: $t = 3.2;
                        assert!(DivEuclid::div_euclid(x,y)*y+RemEuclid::rem_euclid(x,y)-x
                        <=46.4 * <$t as ::Float>::epsilon());
                        assert!(DivEuclid::div_euclid(x,-y)*-y+RemEuclid::rem_euclid(x,-y)-x
                        <= 46.4 * <$t as ::Float>::epsilon());
                        assert!(DivEuclid::div_euclid(-x,y)*y+RemEuclid::rem_euclid(-x,y)-(-x)
                        <= 46.4 * <$t as ::Float>::epsilon());
                        assert!(DivEuclid::div_euclid(-x,-y)*-y+RemEuclid::rem_euclid(-x,-y)-(-x)
                        <= 46.4 * <$t as ::Float>::epsilon());
                    }
                )+
            };
        }

        test_euclid!(f32 f64);
    }

    #[test]
    fn euclid_checked() {
        macro_rules! test_euclid_checked {
            ($($t:ident)+) => {
                $(
                    {
                        assert_eq!(CheckedDivEuclid::checked_div_euclid($t::min_value(),-1),None);
                        assert_eq!(CheckedRemEuclid::checked_rem_euclid($t::min_value(),-1),None);
                        assert_eq!(CheckedDivEuclid::checked_div_euclid(1,0),None);
                        assert_eq!(CheckedRemEuclid::checked_rem_euclid(1,0),None);
                    }
                )+
            };
        }

        test_euclid_checked!(i8 i16 i32 i64);
    }
}
<|endoftext|>


<commit_before>use term_painter::ToStyle;
use term_painter::Attr::*;
use std::fmt;

#[derive(Clone)]
pub struct SearchResult {
    pub title: String,
    pub score: String,
    pub number: String,
    pub genres: Vec<String>,
    pub year: String,
}

impl fmt::Display for SearchResult {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "{}",
               Bold.paint(format!("{} ({})\n", &self.title, &self.year)));
        let mut stars = String::new();
        let score: f32 = self.score.parse::<f32>().unwrap();
        for i in 0..10 {
            if i < (score + 0.5) as i32 {
                stars.push_str("\u{2605}");
            } else {
                stars.push_str("\u{2606}");
            }
        }
        write!(f, "{}", &self.genres[0]);
        for genre in self.genres.clone().into_iter().skip(1) {
            write!(f, ", {}", genre);
        }
        write!(f,
               "\n{}, ({} bei {} Bewertungen)",
               stars,
               &self.score,
               &self.number)
    }
}

impl fmt::Debug for SearchResult {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "{:?}\n{:?}\n{:?}\n{:?}\n{:?}\n******",
               self.title,
               self.year,
               self.genres,
               self.score,
               self.number)
    }
}

pub fn output_result(results: Vec<SearchResult>) {
    for res in results.into_iter().take(3) {
        println!("{}", res);
    }
}
<commit_msg>optimized output<commit_after>use term_painter::ToStyle;
use term_painter::Attr::*;
use std::fmt;
use std::io;
use std::process;

#[derive(Clone)]
pub struct SearchResult {
    pub title: String,
    pub score: String,
    pub number: String,
    pub genres: Vec<String>,
    pub year: String,
}

impl fmt::Display for SearchResult {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "{}",
               Bold.paint(format!("{} ({})\n", &self.title, &self.year)));
        let mut stars = String::new();
        let score: f32 = self.score.parse::<f32>().unwrap();
        for i in 0..10 {
            if i < (score + 0.5) as i32 {
                stars.push_str("\u{2605}");
            } else {
                stars.push_str("\u{2606}");
            }
        }
        write!(f, "{}", &self.genres[0]);
        for genre in self.genres.clone().into_iter().skip(1) {
            write!(f, ", {}", genre);
        }
        write!(f,
               "\n{}, ({} bei {} Bewertungen)",
               stars,
               &self.score,
               &self.number)
    }
}

impl fmt::Debug for SearchResult {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "{:?}\n{:?}\n{:?}\n{:?}\n{:?}\n******",
               self.title,
               self.year,
               self.genres,
               self.score,
               self.number)
    }
}

pub fn output_result(results: Vec<SearchResult>) {
    let further = results.clone();
    for res in results.into_iter().take(3) {
        println!("{}", res);
    }
    for output in further.into_iter().skip(3) {
        let mut buffer = String::new();
        io::stdin().read_line(&mut buffer);
        if buffer != "q\n" {
            println!("{}", output);
        } else {
            process::exit(0);
        }
        // solange nicht q gedrueckt wurde, lade bei enter naechsten eintrag
    }
}
<|endoftext|>