<commit_before>use std::iter;

use chrono::{DateTime, Utc};
use rand::Rng;

const DEFAULT_SLUG_LENGTH: usize = 8;

/// A code snippet
#[derive(Debug, Default, Eq, PartialEq)]
pub struct Snippet {
    /// Slug that uniquely identifies the snippet
    pub id: String,
    /// Snippet title. None means that the title was not specified at snippet
    /// creation time
    pub title: Option<String>,
    /// Snippet syntax. None means that the syntax was not specified at snippet
    /// creation time
    pub syntax: Option<String>,
    /// List of revisions. The snippet content is the content of the most recent
    /// revision. Revisions are sorted by the version number in the
    /// ascending order.
    pub changesets: Vec<Changeset>,
    /// List of tags attached to the snippet
    pub tags: Vec<String>,
    /// Timestamp of when the snippet was created
    pub created_at: Option<DateTime<Utc>>,
    /// Timestamp of when the snippet was last modified. Defaults to creation
    /// time
    pub updated_at: Option<DateTime<Utc>>,
}

impl Snippet {
    /// Create a new Snippet.
    pub fn new(
        title: Option<String>,
        syntax: Option<String>,
        changesets: Vec<Changeset>,
        tags: Vec<String>,
    ) -> Self {
        let mut snippet = Snippet::default();
        snippet.id = Snippet::random_id(DEFAULT_SLUG_LENGTH);
        snippet.title = title;
        snippet.syntax = syntax;
        snippet.changesets = changesets;
        snippet.tags = tags;

        snippet
    }

    /// Generate a random unique snippet identifier (slug).
    pub fn random_id(length: usize) -> String {
        let mut rng = rand::thread_rng();
        iter::repeat_with(|| rng.sample(rand::distributions::Alphanumeric))
            .take(length)
            .collect()
    }
}

/// A particular snippet revision
#[derive(Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
pub struct Changeset {
    /// Changeset index. Version numbers start from 0 and are incremented by 1
    pub version: usize,
    /// Changeset content
    pub content: String,
    /// Timestamp of when the changeset was created
    pub created_at: Option<DateTime<Utc>>,
    /// Timestamp of when the changeset was last modified. Defaults to creation
    /// time
    pub updated_at: Option<DateTime<Utc>>,
}

impl Changeset {
    /// Create a new Changeset.
    pub fn new(version: usize, content: String) -> Self {
        let mut changeset = Changeset::default();
        changeset.version = version;
        changeset.content = content;

        changeset
    }
}

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

    #[test]
    fn test_default_snippet() {
        let snippet = Snippet::default();

        assert_eq!(snippet.id, "");
        assert_eq!(snippet.title, None);
        assert_eq!(snippet.syntax, None);
        assert_eq!(snippet.changesets, vec![] as Vec<Changeset>);
        assert_eq!(snippet.tags, vec![] as Vec<String>);
        assert_eq!(snippet.created_at, None);
        assert_eq!(snippet.updated_at, None);
    }

    #[test]
    fn test_new_snippet() {
        let snippet = Snippet::new(
            Some("Hello".to_string()),
            Some("python".to_string()),
            vec![Changeset::new(0, "print('Hello, World!')".to_string())],
            vec!["#python".to_string()],
        );

        assert_eq!(snippet.id.len(), DEFAULT_SLUG_LENGTH);
        assert_eq!(snippet.title, Some("Hello".to_string()));
        assert_eq!(snippet.syntax, Some("python".to_string()));
        assert_eq!(
            snippet.changesets,
            vec![Changeset::new(0, "print('Hello, World!')".to_string())]
        );
        assert_eq!(snippet.tags, vec!["#python".to_string()]);
        assert_eq!(snippet.created_at, None);
        assert_eq!(snippet.updated_at, None);
    }

    #[test]
    fn test_snippet_equality() {
        let reference = Snippet {
            id: "spam".to_string(),
            title: Some("Hello".to_string()),
            syntax: Some("python".to_string()),
            changesets: vec![Changeset::new(0, "print('Hello, World!')".to_string())],
            tags: vec!["#python".to_string()],
            created_at: None,
            updated_at: None,
        };
        let equal = Snippet {
            id: "spam".to_string(),
            title: Some("Hello".to_string()),
            syntax: Some("python".to_string()),
            changesets: vec![Changeset::new(0, "print('Hello, World!')".to_string())],
            tags: vec!["#python".to_string()],
            created_at: None,
            updated_at: None,
        };
        let different_title = Snippet {
            id: "spam".to_string(),
            title: None,
            syntax: Some("python".to_string()),
            changesets: vec![Changeset::new(0, "print('Hello, World!')".to_string())],
            tags: vec!["#python".to_string()],
            created_at: None,
            updated_at: None,
        };
        let different_syntax = Snippet {
            id: "spam".to_string(),
            title: Some("Hello".to_string()),
            syntax: None,
            changesets: vec![Changeset::new(0, "print('Hello, World!')".to_string())],
            tags: vec!["#python".to_string()],
            created_at: None,
            updated_at: None,
        };
        let different_changesets = Snippet {
            id: "spam".to_string(),
            title: Some("Hello".to_string()),
            syntax: None,
            changesets: vec![Changeset::new(1, "print('Hello, World!')".to_string())],
            tags: vec!["#python".to_string()],
            created_at: None,
            updated_at: None,
        };
        let different_tags = Snippet {
            id: "spam".to_string(),
            title: Some("Hello".to_string()),
            syntax: Some("python".to_string()),
            changesets: vec![Changeset::new(0, "print('Hello, World!')".to_string())],
            tags: vec![],
            created_at: None,
            updated_at: None,
        };

        assert_eq!(reference, equal);
        assert_eq!(equal, reference);

        assert_ne!(reference, different_title);
        assert_ne!(reference, different_syntax);
        assert_ne!(reference, different_changesets);
        assert_ne!(reference, different_tags);
        assert_ne!(different_title, reference);
        assert_ne!(different_syntax, reference);
        assert_ne!(different_changesets, reference);
        assert_ne!(different_tags, reference);
    }

    #[test]
    fn test_random_id() {
        let iterations = 10000;
        let length = 7;

        // verify that ids are sufficiently random
        let generated_ids: std::collections::HashSet<_> =
            std::iter::repeat_with(|| Snippet::random_id(length))
                .take(iterations)
                .collect();
        assert_eq!(generated_ids.len(), iterations);

        // verify that ids are generated with the specified length and only
        // contain characters from the 'a'-'z', 'A'-'Z', '0'-'9' ranges
        for id in generated_ids.iter() {
            assert_eq!(id.len(), length);
            assert!(
                id.chars().all(|c| c.is_ascii_alphanumeric()),
                id.to_string()
            );
        }
    }

    #[test]
    fn test_default_changeset() {
        let changeset = Changeset::default();

        assert_eq!(changeset.version, 0);
        assert_eq!(changeset.content, "");
        assert_eq!(changeset.created_at, None);
        assert_eq!(changeset.updated_at, None);
    }

    #[test]
    fn test_new_changeset() {
        let changeset = Changeset::new(42, "print('Hello, World!')".to_string());

        assert_eq!(changeset.version, 42);
        assert_eq!(changeset.content, "print('Hello, World!')".to_string());
        assert_eq!(changeset.created_at, None);
        assert_eq!(changeset.updated_at, None);
    }

    #[test]
    fn test_changeset_ordering() {
        let changeset1 = Changeset::new(42, "print('Hello!')".to_string());
        let changeset2 = Changeset::new(43, "print('Hello, World!')".to_string());

        assert!(changeset1 < changeset2);
        assert!(changeset1 <= changeset2);
        assert!(changeset2 > changeset1);
        assert!(changeset2 >= changeset1);
    }

    #[test]
    fn test_changeset_equality() {
        let reference = Changeset::new(42, "print('Hello!')".to_string());
        let equal = Changeset::new(42, "print('Hello!')".to_string());
        let different_version = Changeset::new(43, "print('Hello!')".to_string());
        let different_content = Changeset::new(42, "print('Hello, World!')".to_string());

        assert_eq!(reference, equal);
        assert_eq!(equal, reference);

        assert_ne!(reference, different_version);
        assert_ne!(reference, different_content);
        assert_ne!(different_version, reference);
        assert_ne!(different_content, reference);
    }
}
<commit_msg>cargo clippy: fix existing lint errors<commit_after>use std::iter;

use chrono::{DateTime, Utc};
use rand::Rng;

const DEFAULT_SLUG_LENGTH: usize = 8;

/// A code snippet
#[derive(Debug, Default, Eq, PartialEq)]
pub struct Snippet {
    /// Slug that uniquely identifies the snippet
    pub id: String,
    /// Snippet title. None means that the title was not specified at snippet
    /// creation time
    pub title: Option<String>,
    /// Snippet syntax. None means that the syntax was not specified at snippet
    /// creation time
    pub syntax: Option<String>,
    /// List of revisions. The snippet content is the content of the most recent
    /// revision. Revisions are sorted by the version number in the
    /// ascending order.
    pub changesets: Vec<Changeset>,
    /// List of tags attached to the snippet
    pub tags: Vec<String>,
    /// Timestamp of when the snippet was created
    pub created_at: Option<DateTime<Utc>>,
    /// Timestamp of when the snippet was last modified. Defaults to creation
    /// time
    pub updated_at: Option<DateTime<Utc>>,
}

impl Snippet {
    /// Create a new Snippet.
    pub fn new(
        title: Option<String>,
        syntax: Option<String>,
        changesets: Vec<Changeset>,
        tags: Vec<String>,
    ) -> Self {
        Snippet {
            id: Snippet::random_id(DEFAULT_SLUG_LENGTH),
            title,
            syntax,
            changesets,
            tags,
            ..Default::default()
        }
    }

    /// Generate a random unique snippet identifier (slug).
    pub fn random_id(length: usize) -> String {
        let mut rng = rand::thread_rng();
        iter::repeat_with(|| rng.sample(rand::distributions::Alphanumeric))
            .take(length)
            .collect()
    }
}

/// A particular snippet revision
#[derive(Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
pub struct Changeset {
    /// Changeset index. Version numbers start from 0 and are incremented by 1
    pub version: usize,
    /// Changeset content
    pub content: String,
    /// Timestamp of when the changeset was created
    pub created_at: Option<DateTime<Utc>>,
    /// Timestamp of when the changeset was last modified. Defaults to creation
    /// time
    pub updated_at: Option<DateTime<Utc>>,
}

impl Changeset {
    /// Create a new Changeset.
    pub fn new(version: usize, content: String) -> Self {
        Changeset {
            version,
            content,
            ..Default::default()
        }
    }
}

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

    #[test]
    fn test_default_snippet() {
        let snippet = Snippet::default();

        assert_eq!(snippet.id, "");
        assert_eq!(snippet.title, None);
        assert_eq!(snippet.syntax, None);
        assert_eq!(snippet.changesets, vec![] as Vec<Changeset>);
        assert_eq!(snippet.tags, vec![] as Vec<String>);
        assert_eq!(snippet.created_at, None);
        assert_eq!(snippet.updated_at, None);
    }

    #[test]
    fn test_new_snippet() {
        let snippet = Snippet::new(
            Some("Hello".to_string()),
            Some("python".to_string()),
            vec![Changeset::new(0, "print('Hello, World!')".to_string())],
            vec!["#python".to_string()],
        );

        assert_eq!(snippet.id.len(), DEFAULT_SLUG_LENGTH);
        assert_eq!(snippet.title, Some("Hello".to_string()));
        assert_eq!(snippet.syntax, Some("python".to_string()));
        assert_eq!(
            snippet.changesets,
            vec![Changeset::new(0, "print('Hello, World!')".to_string())]
        );
        assert_eq!(snippet.tags, vec!["#python".to_string()]);
        assert_eq!(snippet.created_at, None);
        assert_eq!(snippet.updated_at, None);
    }

    #[test]
    fn test_snippet_equality() {
        let reference = Snippet {
            id: "spam".to_string(),
            title: Some("Hello".to_string()),
            syntax: Some("python".to_string()),
            changesets: vec![Changeset::new(0, "print('Hello, World!')".to_string())],
            tags: vec!["#python".to_string()],
            created_at: None,
            updated_at: None,
        };
        let equal = Snippet {
            id: "spam".to_string(),
            title: Some("Hello".to_string()),
            syntax: Some("python".to_string()),
            changesets: vec![Changeset::new(0, "print('Hello, World!')".to_string())],
            tags: vec!["#python".to_string()],
            created_at: None,
            updated_at: None,
        };
        let different_title = Snippet {
            id: "spam".to_string(),
            title: None,
            syntax: Some("python".to_string()),
            changesets: vec![Changeset::new(0, "print('Hello, World!')".to_string())],
            tags: vec!["#python".to_string()],
            created_at: None,
            updated_at: None,
        };
        let different_syntax = Snippet {
            id: "spam".to_string(),
            title: Some("Hello".to_string()),
            syntax: None,
            changesets: vec![Changeset::new(0, "print('Hello, World!')".to_string())],
            tags: vec!["#python".to_string()],
            created_at: None,
            updated_at: None,
        };
        let different_changesets = Snippet {
            id: "spam".to_string(),
            title: Some("Hello".to_string()),
            syntax: None,
            changesets: vec![Changeset::new(1, "print('Hello, World!')".to_string())],
            tags: vec!["#python".to_string()],
            created_at: None,
            updated_at: None,
        };
        let different_tags = Snippet {
            id: "spam".to_string(),
            title: Some("Hello".to_string()),
            syntax: Some("python".to_string()),
            changesets: vec![Changeset::new(0, "print('Hello, World!')".to_string())],
            tags: vec![],
            created_at: None,
            updated_at: None,
        };

        assert_eq!(reference, equal);
        assert_eq!(equal, reference);

        assert_ne!(reference, different_title);
        assert_ne!(reference, different_syntax);
        assert_ne!(reference, different_changesets);
        assert_ne!(reference, different_tags);
        assert_ne!(different_title, reference);
        assert_ne!(different_syntax, reference);
        assert_ne!(different_changesets, reference);
        assert_ne!(different_tags, reference);
    }

    #[test]
    fn test_random_id() {
        let iterations = 10000;
        let length = 7;

        // verify that ids are sufficiently random
        let generated_ids: std::collections::HashSet<_> =
            std::iter::repeat_with(|| Snippet::random_id(length))
                .take(iterations)
                .collect();
        assert_eq!(generated_ids.len(), iterations);

        // verify that ids are generated with the specified length and only
        // contain characters from the 'a'-'z', 'A'-'Z', '0'-'9' ranges
        for id in generated_ids.iter() {
            assert_eq!(id.len(), length);
            assert!(
                id.chars().all(|c| c.is_ascii_alphanumeric()),
                id.to_string()
            );
        }
    }

    #[test]
    fn test_default_changeset() {
        let changeset = Changeset::default();

        assert_eq!(changeset.version, 0);
        assert_eq!(changeset.content, "");
        assert_eq!(changeset.created_at, None);
        assert_eq!(changeset.updated_at, None);
    }

    #[test]
    fn test_new_changeset() {
        let changeset = Changeset::new(42, "print('Hello, World!')".to_string());

        assert_eq!(changeset.version, 42);
        assert_eq!(changeset.content, "print('Hello, World!')".to_string());
        assert_eq!(changeset.created_at, None);
        assert_eq!(changeset.updated_at, None);
    }

    #[test]
    fn test_changeset_ordering() {
        let changeset1 = Changeset::new(42, "print('Hello!')".to_string());
        let changeset2 = Changeset::new(43, "print('Hello, World!')".to_string());

        assert!(changeset1 < changeset2);
        assert!(changeset1 <= changeset2);
        assert!(changeset2 > changeset1);
        assert!(changeset2 >= changeset1);
    }

    #[test]
    fn test_changeset_equality() {
        let reference = Changeset::new(42, "print('Hello!')".to_string());
        let equal = Changeset::new(42, "print('Hello!')".to_string());
        let different_version = Changeset::new(43, "print('Hello!')".to_string());
        let different_content = Changeset::new(42, "print('Hello, World!')".to_string());

        assert_eq!(reference, equal);
        assert_eq!(equal, reference);

        assert_ne!(reference, different_version);
        assert_ne!(reference, different_content);
        assert_ne!(different_version, reference);
        assert_ne!(different_content, reference);
    }
}
<|endoftext|>


<commit_before>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Michael Gehring <mg@ebfe.org>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// spell-checker:ignore (ToDO) NPROCESSORS nprocs numstr threadstr sysconf

extern crate clap;
extern crate num_cpus;

#[cfg(unix)]
extern crate libc;

#[macro_use]
extern crate uucore;

use clap::{App, Arg};
use std::env;

#[cfg(target_os = "linux")]
pub const _SC_NPROCESSORS_CONF: libc::c_int = 83;
#[cfg(target_os = "macos")]
pub const _SC_NPROCESSORS_CONF: libc::c_int = libc::_SC_NPROCESSORS_CONF;
#[cfg(target_os = "freebsd")]
pub const _SC_NPROCESSORS_CONF: libc::c_int = 57;
#[cfg(target_os = "netbsd")]
pub const _SC_NPROCESSORS_CONF: libc::c_int = 1001;

static OPT_ALL: &str = "all";
static OPT_IGNORE: &str = "ignore";

static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Print the number of cores available to the current process.";

fn get_usage() -> String {
    format!("{0} [OPTIONS]...", executable!())
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = get_usage();
    let matches = App::new(executable!())
        .version(VERSION)
        .about(ABOUT)
        .usage(&usage[..])
        .arg(
            Arg::with_name(OPT_ALL)
                .short("")
                .long("all")
                .help("print the number of cores available to the system"),
        )
        .arg(
            Arg::with_name(OPT_IGNORE)
                .short("")
                .long("ignore")
                .takes_value(true)
                .help("ignore up to N cores"),
        )
        .get_matches_from(args);

    let mut ignore = match matches.value_of(OPT_IGNORE) {
        Some(numstr) => match numstr.parse() {
            Ok(num) => num,
            Err(e) => {
                show_error!("\"{}\" is not a valid number: {}", numstr, e);
                return 1;
            }
        },
        None => 0,
    };

    if !matches.is_present(OPT_ALL) {
        // OMP_NUM_THREADS doesn't have an impact on --all
        ignore += match env::var("OMP_NUM_THREADS") {
            Ok(threadstr) => match threadstr.parse() {
                Ok(num) => num,
                Err(_) => 0,
            },
            Err(_) => 0,
        };
    }

    let mut cores = if matches.is_present(OPT_ALL) {
        num_cpus_all()
    } else {
        num_cpus::get()
    };

    if cores <= ignore {
        cores = 1;
    } else {
        cores -= ignore;
    }
    println!("{}", cores);
    0
}

#[cfg(any(
    target_os = "linux",
    target_os = "macos",
    target_os = "freebsd",
    target_os = "netbsd"
))]
fn num_cpus_all() -> usize {
    let nprocs = unsafe { libc::sysconf(_SC_NPROCESSORS_CONF) };
    if nprocs == 1 {
        // In some situation, /proc and /sys are not mounted, and sysconf returns 1.
        // However, we want to guarantee that `nproc --all` >= `nproc`.
        num_cpus::get()
    } else if nprocs > 0 {
        nprocs as usize
    } else {
        1
    }
}

// Other platforms (e.g., windows), num_cpus::get() directly.
#[cfg(not(any(
    target_os = "linux",
    target_os = "macos",
    target_os = "freebsd",
    target_os = "netbsd"
)))]
fn num_cpus_all() -> usize {
    num_cpus::get()
}
<commit_msg>nproc: use the variable name<commit_after>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Michael Gehring <mg@ebfe.org>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// spell-checker:ignore (ToDO) NPROCESSORS nprocs numstr threadstr sysconf

extern crate clap;
extern crate num_cpus;

#[cfg(unix)]
extern crate libc;

#[macro_use]
extern crate uucore;

use clap::{App, Arg};
use std::env;

#[cfg(target_os = "linux")]
pub const _SC_NPROCESSORS_CONF: libc::c_int = 83;
#[cfg(target_os = "macos")]
pub const _SC_NPROCESSORS_CONF: libc::c_int = libc::_SC_NPROCESSORS_CONF;
#[cfg(target_os = "freebsd")]
pub const _SC_NPROCESSORS_CONF: libc::c_int = 57;
#[cfg(target_os = "netbsd")]
pub const _SC_NPROCESSORS_CONF: libc::c_int = 1001;

static OPT_ALL: &str = "all";
static OPT_IGNORE: &str = "ignore";

static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Print the number of cores available to the current process.";

fn get_usage() -> String {
    format!("{0} [OPTIONS]...", executable!())
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = get_usage();
    let matches = App::new(executable!())
        .version(VERSION)
        .about(ABOUT)
        .usage(&usage[..])
        .arg(
            Arg::with_name(OPT_ALL)
                .short("")
                .long(OPT_ALL)
                .help("print the number of cores available to the system"),
        )
        .arg(
            Arg::with_name(OPT_IGNORE)
                .short("")
                .long(OPT_IGNORE)
                .takes_value(true)
                .help("ignore up to N cores"),
        )
        .get_matches_from(args);

    let mut ignore = match matches.value_of(OPT_IGNORE) {
        Some(numstr) => match numstr.parse() {
            Ok(num) => num,
            Err(e) => {
                show_error!("\"{}\" is not a valid number: {}", numstr, e);
                return 1;
            }
        },
        None => 0,
    };

    if !matches.is_present(OPT_ALL) {
        // OMP_NUM_THREADS doesn't have an impact on --all
        ignore += match env::var("OMP_NUM_THREADS") {
            Ok(threadstr) => match threadstr.parse() {
                Ok(num) => num,
                Err(_) => 0,
            },
            Err(_) => 0,
        };
    }

    let mut cores = if matches.is_present(OPT_ALL) {
        num_cpus_all()
    } else {
        num_cpus::get()
    };

    if cores <= ignore {
        cores = 1;
    } else {
        cores -= ignore;
    }
    println!("{}", cores);
    0
}

#[cfg(any(
    target_os = "linux",
    target_os = "macos",
    target_os = "freebsd",
    target_os = "netbsd"
))]
fn num_cpus_all() -> usize {
    let nprocs = unsafe { libc::sysconf(_SC_NPROCESSORS_CONF) };
    if nprocs == 1 {
        // In some situation, /proc and /sys are not mounted, and sysconf returns 1.
        // However, we want to guarantee that `nproc --all` >= `nproc`.
        num_cpus::get()
    } else if nprocs > 0 {
        nprocs as usize
    } else {
        1
    }
}

// Other platforms (e.g., windows), num_cpus::get() directly.
#[cfg(not(any(
    target_os = "linux",
    target_os = "macos",
    target_os = "freebsd",
    target_os = "netbsd"
)))]
fn num_cpus_all() -> usize {
    num_cpus::get()
}
<|endoftext|>


<commit_before>use postgres::GenericConnection;
use conduit::{Handler, Request, Method};
use conduit_test::MockRequest;

use cargo_registry::db::RequestTransaction;
use cargo_registry::category::{Category, EncodableCategory, EncodableCategoryWithSubcategories};

#[derive(RustcDecodable)]
struct CategoryList { categories: Vec<EncodableCategory>, meta: CategoryMeta }
#[derive(RustcDecodable)]
struct CategoryMeta { total: i32 }
#[derive(RustcDecodable)]
struct GoodCategory { category: EncodableCategory }
#[derive(RustcDecodable)]
struct CategoryWithSubcategories {
    category: EncodableCategoryWithSubcategories
}

#[test]
fn index() {
    let (_b, app, middle) = ::app();
    let mut req = ::req(app, Method::Get, "/api/v1/categories");

    // List 0 categories if none exist
    let mut response = ok_resp!(middle.call(&mut req));
    let json: CategoryList = ::json(&mut response);
    assert_eq!(json.categories.len(), 0);
    assert_eq!(json.meta.total, 0);

    // Create a category and a subcategory
    ::mock_category(&mut req, "foo", "foo");
    ::mock_category(&mut req, "foo::bar", "foo::bar");

    let mut response = ok_resp!(middle.call(&mut req));
    let json: CategoryList = ::json(&mut response);

    // Only the top-level categories should be on the page
    assert_eq!(json.categories.len(), 1);
    assert_eq!(json.meta.total, 1);
    assert_eq!(json.categories[0].category, "foo");
}

#[test]
fn show() {
    let (_b, app, middle) = ::app();

    // Return not found if a category doesn't exist
    let mut req = ::req(app, Method::Get, "/api/v1/categories/foo-bar");
    let response = t_resp!(middle.call(&mut req));
    assert_eq!(response.status.0, 404);

    // Create a category and a subcategory
    ::mock_category(&mut req, "Foo Bar", "foo-bar");
    ::mock_category(&mut req, "Foo Bar::Baz", "foo-bar::baz");

    // The category and its subcategories should be in the json
    let mut response = ok_resp!(middle.call(&mut req));
    let json: CategoryWithSubcategories = ::json(&mut response);
    assert_eq!(json.category.category, "Foo Bar");
    assert_eq!(json.category.slug, "foo-bar");
    assert_eq!(json.category.subcategories.len(), 1);
    assert_eq!(json.category.subcategories[0].category, "Foo Bar::Baz");
}

fn tx(req: &Request) -> &GenericConnection { req.tx().unwrap() }

#[test]
fn update_crate() {
    let (_b, app, middle) = ::app();
    let mut req = ::req(app, Method::Get, "/api/v1/categories/foo");
    let cnt = |req: &mut MockRequest, cat: &str| {
        req.with_path(&format!("/api/v1/categories/{}", cat));
        let mut response = ok_resp!(middle.call(req));
        ::json::<GoodCategory>(&mut response).category.crates_cnt as usize
    };
    ::mock_user(&mut req, ::user("foo"));
    let (krate, _) = ::mock_crate(&mut req, ::krate("foo"));
    ::mock_category(&mut req, "cat1", "cat1");
    ::mock_category(&mut req, "Category 2", "category-2");

    // Updating with no categories has no effect
    Category::update_crate(tx(&req), &krate, &[]).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 0);
    assert_eq!(cnt(&mut req, "category-2"), 0);

    // Happy path adding one category
    Category::update_crate(tx(&req), &krate, &["cat1".to_string()]).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 1);
    assert_eq!(cnt(&mut req, "category-2"), 0);

    // Replacing one category with another
    Category::update_crate(
        tx(&req), &krate, &["category-2".to_string()]
    ).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 0);
    assert_eq!(cnt(&mut req, "category-2"), 1);

    // Removing one category
    Category::update_crate(tx(&req), &krate, &[]).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 0);
    assert_eq!(cnt(&mut req, "category-2"), 0);

    // Adding 2 categories
    Category::update_crate(
        tx(&req), &krate, &["cat1".to_string(),
                            "category-2".to_string()]).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 1);
    assert_eq!(cnt(&mut req, "category-2"), 1);

    // Removing all categories
    Category::update_crate(tx(&req), &krate, &[]).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 0);
    assert_eq!(cnt(&mut req, "category-2"), 0);

    // Attempting to add one valid category and one invalid category
    let invalid_categories = Category::update_crate(
        tx(&req), &krate, &["cat1".to_string(),
                            "catnope".to_string()]
    ).unwrap();
    assert_eq!(invalid_categories, vec!["catnope".to_string()]);
    assert_eq!(cnt(&mut req, "cat1"), 1);
    assert_eq!(cnt(&mut req, "category-2"), 0);

    // Does not add the invalid category to the category list
    // (unlike the behavior of keywords)
    req.with_path("/api/v1/categories");
    let mut response = ok_resp!(middle.call(&mut req));
    let json: CategoryList = ::json(&mut response);
    assert_eq!(json.categories.len(), 2);
    assert_eq!(json.meta.total, 2);

    // Attempting to add a category by display text; must use slug
    Category::update_crate(
        tx(&req), &krate, &["Category 2".to_string()]
    ).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 0);
    assert_eq!(cnt(&mut req, "category-2"), 0);

}
<commit_msg>Use a different crate name in a test to prevent deadlocks<commit_after>use postgres::GenericConnection;
use conduit::{Handler, Request, Method};
use conduit_test::MockRequest;

use cargo_registry::db::RequestTransaction;
use cargo_registry::category::{Category, EncodableCategory, EncodableCategoryWithSubcategories};

#[derive(RustcDecodable)]
struct CategoryList { categories: Vec<EncodableCategory>, meta: CategoryMeta }
#[derive(RustcDecodable)]
struct CategoryMeta { total: i32 }
#[derive(RustcDecodable)]
struct GoodCategory { category: EncodableCategory }
#[derive(RustcDecodable)]
struct CategoryWithSubcategories {
    category: EncodableCategoryWithSubcategories
}

#[test]
fn index() {
    let (_b, app, middle) = ::app();
    let mut req = ::req(app, Method::Get, "/api/v1/categories");

    // List 0 categories if none exist
    let mut response = ok_resp!(middle.call(&mut req));
    let json: CategoryList = ::json(&mut response);
    assert_eq!(json.categories.len(), 0);
    assert_eq!(json.meta.total, 0);

    // Create a category and a subcategory
    ::mock_category(&mut req, "foo", "foo");
    ::mock_category(&mut req, "foo::bar", "foo::bar");

    let mut response = ok_resp!(middle.call(&mut req));
    let json: CategoryList = ::json(&mut response);

    // Only the top-level categories should be on the page
    assert_eq!(json.categories.len(), 1);
    assert_eq!(json.meta.total, 1);
    assert_eq!(json.categories[0].category, "foo");
}

#[test]
fn show() {
    let (_b, app, middle) = ::app();

    // Return not found if a category doesn't exist
    let mut req = ::req(app, Method::Get, "/api/v1/categories/foo-bar");
    let response = t_resp!(middle.call(&mut req));
    assert_eq!(response.status.0, 404);

    // Create a category and a subcategory
    ::mock_category(&mut req, "Foo Bar", "foo-bar");
    ::mock_category(&mut req, "Foo Bar::Baz", "foo-bar::baz");

    // The category and its subcategories should be in the json
    let mut response = ok_resp!(middle.call(&mut req));
    let json: CategoryWithSubcategories = ::json(&mut response);
    assert_eq!(json.category.category, "Foo Bar");
    assert_eq!(json.category.slug, "foo-bar");
    assert_eq!(json.category.subcategories.len(), 1);
    assert_eq!(json.category.subcategories[0].category, "Foo Bar::Baz");
}

fn tx(req: &Request) -> &GenericConnection { req.tx().unwrap() }

#[test]
fn update_crate() {
    let (_b, app, middle) = ::app();
    let mut req = ::req(app, Method::Get, "/api/v1/categories/foo");
    let cnt = |req: &mut MockRequest, cat: &str| {
        req.with_path(&format!("/api/v1/categories/{}", cat));
        let mut response = ok_resp!(middle.call(req));
        ::json::<GoodCategory>(&mut response).category.crates_cnt as usize
    };
    ::mock_user(&mut req, ::user("foo"));
    let (krate, _) = ::mock_crate(&mut req, ::krate("foocat"));
    ::mock_category(&mut req, "cat1", "cat1");
    ::mock_category(&mut req, "Category 2", "category-2");

    // Updating with no categories has no effect
    Category::update_crate(tx(&req), &krate, &[]).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 0);
    assert_eq!(cnt(&mut req, "category-2"), 0);

    // Happy path adding one category
    Category::update_crate(tx(&req), &krate, &["cat1".to_string()]).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 1);
    assert_eq!(cnt(&mut req, "category-2"), 0);

    // Replacing one category with another
    Category::update_crate(
        tx(&req), &krate, &["category-2".to_string()]
    ).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 0);
    assert_eq!(cnt(&mut req, "category-2"), 1);

    // Removing one category
    Category::update_crate(tx(&req), &krate, &[]).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 0);
    assert_eq!(cnt(&mut req, "category-2"), 0);

    // Adding 2 categories
    Category::update_crate(
        tx(&req), &krate, &["cat1".to_string(),
                            "category-2".to_string()]).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 1);
    assert_eq!(cnt(&mut req, "category-2"), 1);

    // Removing all categories
    Category::update_crate(tx(&req), &krate, &[]).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 0);
    assert_eq!(cnt(&mut req, "category-2"), 0);

    // Attempting to add one valid category and one invalid category
    let invalid_categories = Category::update_crate(
        tx(&req), &krate, &["cat1".to_string(),
                            "catnope".to_string()]
    ).unwrap();
    assert_eq!(invalid_categories, vec!["catnope".to_string()]);
    assert_eq!(cnt(&mut req, "cat1"), 1);
    assert_eq!(cnt(&mut req, "category-2"), 0);

    // Does not add the invalid category to the category list
    // (unlike the behavior of keywords)
    req.with_path("/api/v1/categories");
    let mut response = ok_resp!(middle.call(&mut req));
    let json: CategoryList = ::json(&mut response);
    assert_eq!(json.categories.len(), 2);
    assert_eq!(json.meta.total, 2);

    // Attempting to add a category by display text; must use slug
    Category::update_crate(
        tx(&req), &krate, &["Category 2".to_string()]
    ).unwrap();
    assert_eq!(cnt(&mut req, "cat1"), 0);
    assert_eq!(cnt(&mut req, "category-2"), 0);

}
<|endoftext|>


<commit_before>use std::sync::Arc;
use std::sync::mpsc_queue::Queue;

pub struct TaskPool {
    free_tasks: Arc<Queue<Sender<proc():Send>>>,
}

impl TaskPool {
    pub fn new() -> TaskPool {
        let mut pool = TaskPool {
            free_tasks: Arc::new(Queue::new()),
        };

        // adding one thread per CPU
        {
            use std::os;
            use std::cmp;
            for _ in range(0, cmp::min(1u, os::num_cpus() - 1)) {
                pool.add_thread(None);
            }
        }

        pool
    }

    pub fn spawn(&mut self, mut code: proc():Send) {
        use std::task;
        use std::sync::mpsc_queue::{Data, Empty, Inconsistent};

        loop {
            match self.free_tasks.pop() {
                Data(sender) => {
                    match sender.send_opt(code) {
                        Ok(_) => return,
                        Err(org) => code = org
                    }
                },
                Inconsistent =>
                    task::deschedule(),
                Empty => {
                    self.add_thread(Some(code));
                    return
                }
            }
        }
    }

    fn add_thread(&mut self, initial_fn: Option<proc():Send>) {
        use std::io::timer::Timer;

        let queue = self.free_tasks.clone();

        spawn(proc() {
            let mut timer = Timer::new().unwrap();

            if initial_fn.is_some() {
                let f = initial_fn.unwrap();
                f();
            }

            loop {
                let (tx, rx) = channel();
                queue.push(tx);

                let timeout = timer.oneshot(5000);
                select! {
                    next_fn = rx.recv() => next_fn(),
                    _ = timeout.recv() => break
                }
            }
        })
    }
}
<commit_msg>Cleanup in task_pool.rs<commit_after>use std::sync::Arc;
use std::sync::mpsc_queue::Queue;

/// Manages a collection of threads.
///
/// A new thread is created every time all the existing threads are full.
/// Any idle thread will automatically die after 5 seconds.
pub struct TaskPool {
    free_tasks: Arc<Queue<Sender<proc():Send>>>,
}

/// Number of milliseconds after which an idle thread dies.
static THREAD_IDLE_DIEAFTER: u64 = 5000;

impl TaskPool {
    pub fn new() -> TaskPool {
        TaskPool {
            free_tasks: Arc::new(Queue::new()),
        }
    }

    /// Executes a function in a thread.
    /// If no thread is available, spawns a new one.
    pub fn spawn(&mut self, mut code: proc():Send) {
        use std::task;
        use std::sync::mpsc_queue::{Data, Empty, Inconsistent};

        loop {
            match self.free_tasks.pop() {
                Data(sender) => {
                    match sender.send_opt(code) {
                        Ok(_) => return,
                        Err(org) => code = org
                    }
                },
                Inconsistent =>
                    task::deschedule(),
                Empty => {
                    self.add_thread(Some(code));
                    return
                }
            }
        }
    }

    fn add_thread(&mut self, initial_fn: Option<proc():Send>) {
        use std::io::timer::Timer;

        let queue = self.free_tasks.clone();

        spawn(proc() {
            let mut timer = Timer::new().unwrap();

            if initial_fn.is_some() {
                let f = initial_fn.unwrap();
                f();
            }

            loop {
                let (tx, rx) = channel();
                queue.push(tx);

                let timeout = timer.oneshot(THREAD_IDLE_DIEAFTER);
                select! {
                    next_fn = rx.recv() => next_fn(),
                    _ = timeout.recv() => break
                }
            }
        })
    }
}
<|endoftext|>


<commit_before>use std::vec::Vec;

use chunk::{Chunk, Param, TupleMode};
use codegen::translate_from_glib::TranslateFromGlib;
use codegen::translate_to_glib::TranslateToGlib;
use env::Env;
use super::primitives::*;

pub trait ToCode {
    fn to_code(&self, env: &Env) -> Vec<String>;
}

impl ToCode for Chunk {
    fn to_code(&self, env: &Env) -> Vec<String> {
        use chunk::Chunk::*;
        match *self {
            Comment(ref chs) => comment_block(&chs.to_code(env)),
            Chunks(ref chs) => chs.to_code(env),
            BlockHalf(ref chs) => format_block("", "}", &chs.to_code(env)),
            UnsafeSmart(ref chs) => {
                format_block_smart("unsafe {", "}", &chs.to_code(env), " ", " ")
            }
            Unsafe(ref chs) => format_block("unsafe {", "}", &chs.to_code(env)),
            FfiCallTODO(ref name) => vec![format!("TODO: call ffi::{}()", name)],
            FfiCall {
                ref name,
                ref params,
            } => {
                let prefix = if name.find("::").is_some() {
                    format!("{}(", name)
                } else {
                    format!("ffi::{}(", name)
                };
                //TODO: change to format_block or format_block_smart
                let s = format_block_one_line(&prefix, ")", &params.to_code(env), "", ", ");
                vec![s]
            }
            FfiCallParameter {
                ref transformation_type,
            } => {
                let s = transformation_type.translate_to_glib();
                vec![s]
            }
            FfiCallOutParameter { ref par } => {
                let s = if par.caller_allocates {
                    format!("{}.to_glib_none_mut().0", par.name)
                } else {
                    format!("&mut {}", par.name)
                };
                vec![s]
            }
            FfiCallConversion {
                ref ret,
                ref array_length_name,
                ref call,
            } => {
                let call_strings = call.to_code(env);
                let (prefix, suffix) =
                    ret.translate_from_glib_as_function(env, array_length_name.as_ref());
                let s = format_block_one_line(&prefix, &suffix, &call_strings, "", "");
                vec![s]
            }
            Let {
                ref name,
                is_mut,
                ref value,
                ref type_,
            } => {
                let modif = if is_mut { "mut " } else { "" };
                let type_string = if let Some(ref type_) = *type_ {
                    let type_strings = type_.to_code(env);
                    format_block_one_line(": ", "", &type_strings, "", "")
                } else {
                    "".to_owned()
                };
                let value_strings = value.to_code(env);
                let prefix = format!("let {}{}{} = ", modif, name, type_string);
                let s = format_block_one_line(&prefix, ";", &value_strings, "", "");
                vec![s]
            }
            Uninitialized => vec!["mem::uninitialized()".into()],
            UninitializedNamed { ref name } => {
                let s = format!("{}::uninitialized()", name);
                vec![s]
            }
            NullPtr => vec!["ptr::null()".into()],
            NullMutPtr => vec!["ptr::null_mut()".into()],
            Custom(ref string) => vec![string.clone()],
            Tuple(ref chs, mode) => {
                #[allow(deprecated)]
                let with_bracket = match mode {
                    TupleMode::Auto => chs.len() > 1,
                    TupleMode::WithUnit => chs.len() != 1,
                    TupleMode::Simple => true,
                };
                let (prefix, suffix) = if with_bracket { ("(", ")") } else { ("", "") };
                let s = format_block_one_line(prefix, suffix, &chs.to_code(env), "", ", ");
                vec![s]
            }
            FromGlibConversion {
                ref mode,
                ref array_length_name,
                ref value,
            } => {
                let value_strings = value.to_code(env);
                let (prefix, suffix) =
                    mode.translate_from_glib_as_function(env, array_length_name.as_ref());
                let s = format_block_one_line(&prefix, &suffix, &value_strings, "", "");
                vec![s]
            }
            OptionalReturn {
                ref condition,
                ref value,
            } => {
                let value_strings = value.to_code(env);
                let prefix = format!("if {} {{ Some(", condition);
                let suffix = ") } else { None }";
                let s = format_block_one_line(&prefix, suffix, &value_strings, "", "");
                vec![s]
            }
            ErrorResultReturn { ref value } => {
                let value_strings = value.to_code(env);
                let prefix = "if error.is_null() { Ok(";
                let suffix = ") } else { Err(from_glib_full(error)) }";
                let s = format_block_one_line(prefix, suffix, &value_strings, "", "");
                vec![s]
            }
            AssertInitializedAndInMainThread => {
                vec!["assert_initialized_main_thread!();".to_string()]
            }
            AssertSkipInitialized => vec!["skip_assert_initialized!();".to_string()],
            Connect {
                ref signal,
                ref trampoline,
                in_trait,
            } => {
                let s1 = format!("connect_raw(self.as_ptr() as *mut _, b\"{}\\0\".as_ptr() as *const _,", signal);
                let self_str = if in_trait { "::<Self>" } else { "" };
                let s2 = format!(
                    "\ttransmute({}{} as usize), Box_::into_raw(f) as *mut _)",
                    trampoline,
                    self_str
                );
                vec![s1, s2]
            }
            Name(ref name) => vec![name.clone()],
            BoxFn { name: None, ref typ } => vec![
                format!("let user_data: Box<Box<{}>> = Box::new(Box::new(callback));", typ),
            ],
            BoxFn { name: Some(ref name), ref typ } => vec![
                // TODO: The name is generated based on user callback data holder. Not ideal doing
                //       it here, this way...
                format!("let {}_data: Box<Box<{}>> = Box::new(Box::new({}));",
                        name,
                        typ,
                        &name),
            ],
            ExternCFunc { ref name, ref parameters, ref body, ref return_value, ref bounds } => {
                let prefix = format!(r#"unsafe extern "C" fn {}{}("#, name, bounds);
                let suffix = ")".to_string();
                let params: Vec<_> = parameters.iter()
                    .flat_map(|param| param.to_code(env))
                    .collect();
                let mut s = format_block_one_line(&prefix, &suffix, &params, "", ", ");
                if let Some(ref return_value) = return_value {
                    s.push_str(&format!(" -> {}", return_value));
                }
                s.push_str(" {");
                let mut code = format_block_smart("", "}", &body.to_code(env), " ", " ");
                code.insert(0, s);
                code
            }
            Cast { ref name, ref type_ } => vec![format!("{} as {}", name, type_)],
            Call { ref func_name, ref arguments } => {
                let args: Vec<_> = arguments.iter()
                    .flat_map(|arg| arg.to_code(env))
                    .collect();
                let s = format_block_one_line("(", ")", &args, "", ",");
                vec![format!("{}{};", func_name, s)]
            }
        }
    }
}

impl ToCode for Param {
    fn to_code(&self, _env: &Env) -> Vec<String> {
        vec![format!("{}: {}", self.name, self.typ)]
    }
}

impl ToCode for [Chunk] {
    fn to_code(&self, env: &Env) -> Vec<String> {
        let mut v = Vec::new();
        for ch in self {
            let strs = ch.to_code(env);
            v.extend_from_slice(&strs);
        }
        v
    }
}
<commit_msg>fix destroy C func indentation<commit_after>use std::vec::Vec;

use chunk::{Chunk, Param, TupleMode};
use codegen::translate_from_glib::TranslateFromGlib;
use codegen::translate_to_glib::TranslateToGlib;
use env::Env;
use super::primitives::*;

pub trait ToCode {
    fn to_code(&self, env: &Env) -> Vec<String>;
}

impl ToCode for Chunk {
    fn to_code(&self, env: &Env) -> Vec<String> {
        use chunk::Chunk::*;
        match *self {
            Comment(ref chs) => comment_block(&chs.to_code(env)),
            Chunks(ref chs) => chs.to_code(env),
            BlockHalf(ref chs) => format_block("", "}", &chs.to_code(env)),
            UnsafeSmart(ref chs) => {
                format_block_smart("unsafe {", "}", &chs.to_code(env), " ", " ")
            }
            Unsafe(ref chs) => format_block("unsafe {", "}", &chs.to_code(env)),
            FfiCallTODO(ref name) => vec![format!("TODO: call ffi::{}()", name)],
            FfiCall {
                ref name,
                ref params,
            } => {
                let prefix = if name.find("::").is_some() {
                    format!("{}(", name)
                } else {
                    format!("ffi::{}(", name)
                };
                //TODO: change to format_block or format_block_smart
                let s = format_block_one_line(&prefix, ")", &params.to_code(env), "", ", ");
                vec![s]
            }
            FfiCallParameter {
                ref transformation_type,
            } => {
                let s = transformation_type.translate_to_glib();
                vec![s]
            }
            FfiCallOutParameter { ref par } => {
                let s = if par.caller_allocates {
                    format!("{}.to_glib_none_mut().0", par.name)
                } else {
                    format!("&mut {}", par.name)
                };
                vec![s]
            }
            FfiCallConversion {
                ref ret,
                ref array_length_name,
                ref call,
            } => {
                let call_strings = call.to_code(env);
                let (prefix, suffix) =
                    ret.translate_from_glib_as_function(env, array_length_name.as_ref());
                let s = format_block_one_line(&prefix, &suffix, &call_strings, "", "");
                vec![s]
            }
            Let {
                ref name,
                is_mut,
                ref value,
                ref type_,
            } => {
                let modif = if is_mut { "mut " } else { "" };
                let type_string = if let Some(ref type_) = *type_ {
                    let type_strings = type_.to_code(env);
                    format_block_one_line(": ", "", &type_strings, "", "")
                } else {
                    "".to_owned()
                };
                let value_strings = value.to_code(env);
                let prefix = format!("let {}{}{} = ", modif, name, type_string);
                let s = format_block_one_line(&prefix, ";", &value_strings, "", "");
                vec![s]
            }
            Uninitialized => vec!["mem::uninitialized()".into()],
            UninitializedNamed { ref name } => {
                let s = format!("{}::uninitialized()", name);
                vec![s]
            }
            NullPtr => vec!["ptr::null()".into()],
            NullMutPtr => vec!["ptr::null_mut()".into()],
            Custom(ref string) => vec![string.clone()],
            Tuple(ref chs, mode) => {
                #[allow(deprecated)]
                let with_bracket = match mode {
                    TupleMode::Auto => chs.len() > 1,
                    TupleMode::WithUnit => chs.len() != 1,
                    TupleMode::Simple => true,
                };
                let (prefix, suffix) = if with_bracket { ("(", ")") } else { ("", "") };
                let s = format_block_one_line(prefix, suffix, &chs.to_code(env), "", ", ");
                vec![s]
            }
            FromGlibConversion {
                ref mode,
                ref array_length_name,
                ref value,
            } => {
                let value_strings = value.to_code(env);
                let (prefix, suffix) =
                    mode.translate_from_glib_as_function(env, array_length_name.as_ref());
                let s = format_block_one_line(&prefix, &suffix, &value_strings, "", "");
                vec![s]
            }
            OptionalReturn {
                ref condition,
                ref value,
            } => {
                let value_strings = value.to_code(env);
                let prefix = format!("if {} {{ Some(", condition);
                let suffix = ") } else { None }";
                let s = format_block_one_line(&prefix, suffix, &value_strings, "", "");
                vec![s]
            }
            ErrorResultReturn { ref value } => {
                let value_strings = value.to_code(env);
                let prefix = "if error.is_null() { Ok(";
                let suffix = ") } else { Err(from_glib_full(error)) }";
                let s = format_block_one_line(prefix, suffix, &value_strings, "", "");
                vec![s]
            }
            AssertInitializedAndInMainThread => {
                vec!["assert_initialized_main_thread!();".to_string()]
            }
            AssertSkipInitialized => vec!["skip_assert_initialized!();".to_string()],
            Connect {
                ref signal,
                ref trampoline,
                in_trait,
            } => {
                let s1 = format!("connect_raw(self.as_ptr() as *mut _, b\"{}\\0\".as_ptr() as *const _,", signal);
                let self_str = if in_trait { "::<Self>" } else { "" };
                let s2 = format!(
                    "\ttransmute({}{} as usize), Box_::into_raw(f) as *mut _)",
                    trampoline,
                    self_str
                );
                vec![s1, s2]
            }
            Name(ref name) => vec![name.clone()],
            BoxFn { name: None, ref typ } => vec![
                format!("let user_data: Box<Box<{}>> = Box::new(Box::new(callback));", typ),
            ],
            BoxFn { name: Some(ref name), ref typ } => vec![
                // TODO: The name is generated based on user callback data holder. Not ideal doing
                //       it here, this way...
                format!("let {}_data: Box<Box<{}>> = Box::new(Box::new({}));",
                        name,
                        typ,
                        &name),
            ],
            ExternCFunc { ref name, ref parameters, ref body, ref return_value, ref bounds } => {
                let prefix = format!(r#"unsafe extern "C" fn {}{}("#, name, bounds);
                let suffix = ")".to_string();
                let params: Vec<_> = parameters.iter()
                    .flat_map(|param| param.to_code(env))
                    .collect();
                let mut s = format_block_one_line(&prefix, &suffix, &params, "", ", ");
                if let Some(ref return_value) = return_value {
                    s.push_str(&format!(" -> {}", return_value));
                }
                s.push_str(" {");
                let mut code = format_block("", "}", &body.to_code(env));
                code.insert(0, s);
                code
            }
            Cast { ref name, ref type_ } => vec![format!("{} as {}", name, type_)],
            Call { ref func_name, ref arguments } => {
                let args: Vec<_> = arguments.iter()
                    .flat_map(|arg| arg.to_code(env))
                    .collect();
                let s = format_block_one_line("(", ")", &args, "", ",");
                vec![format!("{}{};", func_name, s)]
            }
        }
    }
}

impl ToCode for Param {
    fn to_code(&self, _env: &Env) -> Vec<String> {
        vec![format!("{}: {}", self.name, self.typ)]
    }
}

impl ToCode for [Chunk] {
    fn to_code(&self, env: &Env) -> Vec<String> {
        let mut v = Vec::new();
        for ch in self {
            let strs = ch.to_code(env);
            v.extend_from_slice(&strs);
        }
        v
    }
}
<|endoftext|>


<commit_before>use std::borrow::Cow;
use std::ops::Not;

use crate::requests::*;
use crate::types::*;

/// Use this method to send text messages.
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize)]
#[must_use = "requests do nothing unless sent"]
pub struct SendMessage<'s> {
    chat_id: ChatRef,
    text: Cow<'s, str>,
    #[serde(skip_serializing_if = "Option::is_none")]
    parse_mode: Option<ParseMode>,
    #[serde(skip_serializing_if = "Not::not")]
    disable_web_page_preview: bool,
    #[serde(skip_serializing_if = "Not::not")]
    disable_notification: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    reply_to_message_id: Option<MessageId>,
    #[serde(skip_serializing_if = "Option::is_none")]
    reply_markup: Option<ReplyMarkup>,
}

impl<'c, 's> Request for SendMessage<'s> {
    type Type = JsonRequestType<Self>;
    type Response = JsonIdResponse<Message>;

    fn serialize(&self) -> Result<HttpRequest, Error> {
        Self::Type::serialize(RequestUrl::method("sendMessage"), self)
    }
}

impl<'s> SendMessage<'s> {
    pub fn new<C, T>(chat: C, text: T) -> Self
    where
        C: ToChatRef,
        T: Into<Cow<'s, str>>,
    {
        SendMessage {
            chat_id: chat.to_chat_ref(),
            text: text.into(),
            parse_mode: None,
            disable_web_page_preview: false,
            disable_notification: false,
            reply_to_message_id: None,
            reply_markup: None,
        }
    }

    pub fn parse_mode(&mut self, parse_mode: ParseMode) -> &mut Self {
        self.parse_mode = Some(parse_mode);
        self
    }

    pub fn disable_preview(&mut self) -> &mut Self {
        self.disable_web_page_preview = true;
        self
    }

    pub fn disable_notification(&mut self) -> &mut Self {
        self.disable_notification = true;
        self
    }

    pub fn reply_to<R>(&mut self, to: R) -> &mut Self
    where
        R: ToMessageId,
    {
        self.reply_to_message_id = Some(to.to_message_id());
        self
    }

    pub fn reply_markup<R>(&mut self, reply_markup: R) -> &mut Self
    where
        R: Into<ReplyMarkup>,
    {
        self.reply_markup = Some(reply_markup.into());
        self
    }
}

/// Send text message.
pub trait CanSendMessage {
    fn text<'s, T>(&self, text: T) -> SendMessage<'s>
    where
        T: Into<Cow<'s, str>>;
}

impl<C> CanSendMessage for C
where
    C: ToChatRef,
{
    fn text<'s, T>(&self, text: T) -> SendMessage<'s>
    where
        T: Into<Cow<'s, str>>,
    {
        SendMessage::new(self, text)
    }
}

/// Reply with text message.
pub trait CanReplySendMessage {
    fn text_reply<'c, 's, T>(&self, text: T) -> SendMessage<'s>
    where
        T: Into<Cow<'s, str>>;
}

impl<M> CanReplySendMessage for M
where
    M: ToMessageId + ToSourceChat,
{
    fn text_reply<'c, 's, T>(&self, text: T) -> SendMessage<'s>
    where
        T: Into<Cow<'s, str>>,
    {
        let mut rq = self.to_source_chat().text(text);
        rq.reply_to(self.to_message_id());
        rq
    }
}
<commit_msg>Account for when a `ChannelPost` is returned from `SendMessage`<commit_after>use std::borrow::Cow;
use std::ops::Not;

use crate::requests::*;
use crate::types::*;

/// Use this method to send text messages.
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize)]
#[must_use = "requests do nothing unless sent"]
pub struct SendMessage<'s> {
    chat_id: ChatRef,
    text: Cow<'s, str>,
    #[serde(skip_serializing_if = "Option::is_none")]
    parse_mode: Option<ParseMode>,
    #[serde(skip_serializing_if = "Not::not")]
    disable_web_page_preview: bool,
    #[serde(skip_serializing_if = "Not::not")]
    disable_notification: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    reply_to_message_id: Option<MessageId>,
    #[serde(skip_serializing_if = "Option::is_none")]
    reply_markup: Option<ReplyMarkup>,
}

impl<'c, 's> Request for SendMessage<'s> {
    type Type = JsonRequestType<Self>;
    type Response = JsonIdResponse<MessageOrChannelPost>;

    fn serialize(&self) -> Result<HttpRequest, Error> {
        Self::Type::serialize(RequestUrl::method("sendMessage"), self)
    }
}

impl<'s> SendMessage<'s> {
    pub fn new<C, T>(chat: C, text: T) -> Self
    where
        C: ToChatRef,
        T: Into<Cow<'s, str>>,
    {
        SendMessage {
            chat_id: chat.to_chat_ref(),
            text: text.into(),
            parse_mode: None,
            disable_web_page_preview: false,
            disable_notification: false,
            reply_to_message_id: None,
            reply_markup: None,
        }
    }

    pub fn parse_mode(&mut self, parse_mode: ParseMode) -> &mut Self {
        self.parse_mode = Some(parse_mode);
        self
    }

    pub fn disable_preview(&mut self) -> &mut Self {
        self.disable_web_page_preview = true;
        self
    }

    pub fn disable_notification(&mut self) -> &mut Self {
        self.disable_notification = true;
        self
    }

    pub fn reply_to<R>(&mut self, to: R) -> &mut Self
    where
        R: ToMessageId,
    {
        self.reply_to_message_id = Some(to.to_message_id());
        self
    }

    pub fn reply_markup<R>(&mut self, reply_markup: R) -> &mut Self
    where
        R: Into<ReplyMarkup>,
    {
        self.reply_markup = Some(reply_markup.into());
        self
    }
}

/// Send text message.
pub trait CanSendMessage {
    fn text<'s, T>(&self, text: T) -> SendMessage<'s>
    where
        T: Into<Cow<'s, str>>;
}

impl<C> CanSendMessage for C
where
    C: ToChatRef,
{
    fn text<'s, T>(&self, text: T) -> SendMessage<'s>
    where
        T: Into<Cow<'s, str>>,
    {
        SendMessage::new(self, text)
    }
}

/// Reply with text message.
pub trait CanReplySendMessage {
    fn text_reply<'c, 's, T>(&self, text: T) -> SendMessage<'s>
    where
        T: Into<Cow<'s, str>>;
}

impl<M> CanReplySendMessage for M
where
    M: ToMessageId + ToSourceChat,
{
    fn text_reply<'c, 's, T>(&self, text: T) -> SendMessage<'s>
    where
        T: Into<Cow<'s, str>>,
    {
        let mut rq = self.to_source_chat().text(text);
        rq.reply_to(self.to_message_id());
        rq
    }
}
<|endoftext|>


<commit_before>//! How many Pythagorean triples exist less than or equal to a million?
//! i.e. a²+b²=c² and a,b,c ≤ 1000000

use num::Integer;
use rayon::prelude::*;
use rayon::range::RangeIter;
use std::usize;
use std::ops::Add;
use test;

/// Use Euclid's formula to count Pythagorean triples
///
/// https://en.wikipedia.org/wiki/Pythagorean_triple#Generating_a_triple
///
/// For coprime integers m and n, with m > n and m-n is odd, then
///     a = m²-n², b = 2mn, c = m²+n²
///
/// This is a coprime triple.  Multiplying by factors k covers all triples.
fn par_euclid<FM, M, FN, N>(map_m: FM, map_n: FN) -> u32
    where FM: FnOnce(RangeIter<u32>) -> M,
          M: ParallelIterator<Item=u32>,
          FN: Fn(RangeIter<u32>) -> N + Sync,
          N: ParallelIterator<Item=u32>,
{
    map_m((1u32 .. 2000).into_par_iter()).map(|m| {
        map_n((1 .. m).into_par_iter())
            .filter(|n| (m - n).is_odd() && m.gcd(n) == 1)
            .map(|n| 4000000 / (m*m + n*n))
            .sum()
    }).sum()
}

/// Same as par_euclid, without tweaking split lengths
fn par_euclid_weightless() -> u32 {
    (1u32 .. 2000).into_par_iter().map(|m| {
        (1 .. m).into_par_iter()
            .filter(|n| (m - n).is_odd() && m.gcd(n) == 1)
            .map(|n| 4000000 / (m*m + n*n))
            .sum()
    }).sum()
}

/// Same as par_euclid, without using rayon.
fn euclid() -> u32 {
    (1u32 .. 2000).map(|m| {
        (1 .. m)
            .filter(|n| (m - n).is_odd() && m.gcd(n) == 1)
            .map(|n| 4000000 / (m*m + n*n))
            .fold(0, Add::add)
    }).fold(0, Add::add)
}

#[bench]
/// Benchmark without rayon at all
fn euclid_serial(b: &mut test::Bencher) {
    let count = euclid();
    b.iter(|| assert_eq!(euclid(), count))
}

#[bench]
/// Use huge minimums to force it fully serialized.
fn euclid_faux_serial(b: &mut test::Bencher) {
    let count = euclid();
    let serial = |r: RangeIter<u32>| r.with_min_len(usize::MAX);
    b.iter(|| assert_eq!(par_euclid(&serial, &serial), count))
}

#[bench]
/// Use the default without any weights
fn euclid_parallel_weightless(b: &mut test::Bencher) {
    let count = euclid();
    b.iter(|| assert_eq!(par_euclid_weightless(), count))
}

#[bench]
/// Use the default settings.
fn euclid_parallel_one(b: &mut test::Bencher) {
    let count = euclid();
    b.iter(|| assert_eq!(par_euclid(|m| m, |n| n), count))
}

#[bench]
/// Use a low maximum to force the outer loop parallelized.
fn euclid_parallel_outer(b: &mut test::Bencher) {
    let count = euclid();
    let parallel = |r: RangeIter<u32>| r.with_max_len(1);
    b.iter(|| assert_eq!(par_euclid(&parallel, |n| n), count))
}

#[bench]
/// Use low maximums to force it fully parallelized.
fn euclid_parallel_full(b: &mut test::Bencher) {
    let count = euclid();
    let parallel = |r: RangeIter<u32>| r.with_max_len(1);
    b.iter(|| assert_eq!(par_euclid(&parallel, &parallel), count))
}
<commit_msg>Update a RangeIter use in rayon-demo<commit_after>//! How many Pythagorean triples exist less than or equal to a million?
//! i.e. a²+b²=c² and a,b,c ≤ 1000000

use num::Integer;
use rayon::prelude::*;
use rayon::range::Iter;
use std::usize;
use std::ops::Add;
use test;

/// Use Euclid's formula to count Pythagorean triples
///
/// https://en.wikipedia.org/wiki/Pythagorean_triple#Generating_a_triple
///
/// For coprime integers m and n, with m > n and m-n is odd, then
///     a = m²-n², b = 2mn, c = m²+n²
///
/// This is a coprime triple.  Multiplying by factors k covers all triples.
fn par_euclid<FM, M, FN, N>(map_m: FM, map_n: FN) -> u32
    where FM: FnOnce(Iter<u32>) -> M,
          M: ParallelIterator<Item=u32>,
          FN: Fn(Iter<u32>) -> N + Sync,
          N: ParallelIterator<Item=u32>,
{
    map_m((1u32 .. 2000).into_par_iter()).map(|m| {
        map_n((1 .. m).into_par_iter())
            .filter(|n| (m - n).is_odd() && m.gcd(n) == 1)
            .map(|n| 4000000 / (m*m + n*n))
            .sum()
    }).sum()
}

/// Same as par_euclid, without tweaking split lengths
fn par_euclid_weightless() -> u32 {
    (1u32 .. 2000).into_par_iter().map(|m| {
        (1 .. m).into_par_iter()
            .filter(|n| (m - n).is_odd() && m.gcd(n) == 1)
            .map(|n| 4000000 / (m*m + n*n))
            .sum()
    }).sum()
}

/// Same as par_euclid, without using rayon.
fn euclid() -> u32 {
    (1u32 .. 2000).map(|m| {
        (1 .. m)
            .filter(|n| (m - n).is_odd() && m.gcd(n) == 1)
            .map(|n| 4000000 / (m*m + n*n))
            .fold(0, Add::add)
    }).fold(0, Add::add)
}

#[bench]
/// Benchmark without rayon at all
fn euclid_serial(b: &mut test::Bencher) {
    let count = euclid();
    b.iter(|| assert_eq!(euclid(), count))
}

#[bench]
/// Use huge minimums to force it fully serialized.
fn euclid_faux_serial(b: &mut test::Bencher) {
    let count = euclid();
    let serial = |r: Iter<u32>| r.with_min_len(usize::MAX);
    b.iter(|| assert_eq!(par_euclid(&serial, &serial), count))
}

#[bench]
/// Use the default without any weights
fn euclid_parallel_weightless(b: &mut test::Bencher) {
    let count = euclid();
    b.iter(|| assert_eq!(par_euclid_weightless(), count))
}

#[bench]
/// Use the default settings.
fn euclid_parallel_one(b: &mut test::Bencher) {
    let count = euclid();
    b.iter(|| assert_eq!(par_euclid(|m| m, |n| n), count))
}

#[bench]
/// Use a low maximum to force the outer loop parallelized.
fn euclid_parallel_outer(b: &mut test::Bencher) {
    let count = euclid();
    let parallel = |r: Iter<u32>| r.with_max_len(1);
    b.iter(|| assert_eq!(par_euclid(&parallel, |n| n), count))
}

#[bench]
/// Use low maximums to force it fully parallelized.
fn euclid_parallel_full(b: &mut test::Bencher) {
    let count = euclid();
    let parallel = |r: Iter<u32>| r.with_max_len(1);
    b.iter(|| assert_eq!(par_euclid(&parallel, &parallel), count))
}
<|endoftext|>


<commit_before>use history::State;
use history::History;

struct Nav {
    state_: State
}

//impl Nav {
//    fn has_child
//}

<commit_msg>sketch nav<commit_after>use history::State;
use history::History;

struct Nav {
    state_: State
}

/*
impl Nav {
    fn has_child() -> bool;
    fn next_sibling() -> bool;
    fn up() -> bool;
    fn is_terminal() -> bool;
    fn get_string() -> &str;
    fn is_end() -> bool
}
*/

<|endoftext|>


<commit_before>extern crate postgres;
extern crate chrono;

use postgres::{Connection, SslMode, types};
use std::io::{self, Read};

enum Align {
    Left,
    Right,
}

fn parse_result(column: &postgres::rows::Row, coltype: &Vec<types::Type>, colpos: usize) -> String {
    let val: String = match coltype[colpos] {
        types::Type::Text | types::Type::Varchar => column.get(colpos),
        types::Type::Bool => {
            let tmpbool: bool = column.get(colpos);
            match tmpbool {
                true  => String::from("true"),
                false => String::from("false"),
            }
        },
        types::Type::Int2 | types::Type::Int4 => {
            let tmpint: i32 = column.get(colpos);
            tmpint.to_string()
        },
        types::Type::Int8 => {
            let tmpint: i64 = column.get(colpos);
            tmpint.to_string()
        },
        types::Type::Float4 => {
            let tmpflt: f32 = column.get(colpos);
            tmpflt.to_string()
        },
        types::Type::Float8 => {
            let tmpflt: f64 = column.get(colpos);
            tmpflt.to_string()
        },
        _ => String::from(""),
    };

    val
}

fn get_alignment(coltype: &Vec<types::Type>, colpos: usize) -> Align {
    match coltype[colpos] {
        types::Type::Int2   => Align::Right,
        types::Type::Int4   => Align::Right,
        types::Type::Int8   => Align::Right,
        types::Type::Float4 => Align::Right,
        types::Type::Float8 => Align::Right,
        _                   => Align::Left,
    }
}

fn format_field(column: &str, width: usize, align: Align) -> String {
    let mut padstr = String::from("");
    let padlen: usize = width - column.len();

    for _ in 0..padlen {
        padstr = padstr + " ";
    }

    let ret: String = match align {
        Align::Right => format!("{}{}", padstr, column),
        Align::Left  => format!("{}{}", column, padstr),
    };

    ret
}

fn print_row(coltypes: &Vec<types::Type>, colwidths: &Vec<usize>, rowdata: &Vec<String>) {
    for (i, col) in rowdata.iter().enumerate() {
        let align = get_alignment(&coltypes, i);

        if i > 0 {
            print!("|");
        }

        print!(" {} ", format_field(&col, colwidths[i], align));
    }

    println!("");
}

fn print_header(colwidths: &Vec<usize>) {
    for (i, col) in colwidths.iter().enumerate() {
        if i > 0 {
            print!("+");
        }

        print!("-{data:-<width$}-", data="-", width=col);
    }

    println!("");
}

fn main() {
    let mut buf = String::new();
    let mut colnames: Vec<String> = Vec::new();
    let mut coldata: Vec<Vec<String>> = Vec::new();
    let mut colwidths: Vec<usize> = Vec::new();
    let mut coltypes: Vec<types::Type> = Vec::new();

    io::stdin().read_to_string(&mut buf);

    let conn = Connection::connect("postgres://jeff@localhost", SslMode::None).unwrap();
    let res = &conn.query(&mut buf, &[]).unwrap();
    let numcols = res.columns().len();

    for col in res.columns() {
        let colname = String::from(col.name());
        colwidths.push(colname.len());
        colnames.push(colname);
        coltypes.push(col.type_().clone());
    }

    for row in res.iter() {
        let mut colvals: Vec<String> = Vec::new();

        for i in 0..numcols {
            let ret = row.get_bytes(i);
            let col = if ret.is_some() { parse_result(&row, &coltypes, i) } else { String::from("") };

            if colwidths[i] < col.len() {
                colwidths[i] = col.len();
            }

            colvals.push(col);
        }

        coldata.push(colvals);
    }

    print_row(&coltypes, &colwidths, &colnames);
    print_header(&colwidths);
    for rowdata in coldata {
        print_row(&coltypes, &colwidths, &rowdata);
    }
}
<commit_msg>add support for color printing<commit_after>extern crate postgres;
extern crate chrono;

use postgres::{Connection, SslMode, types};
use std::io::{self, Read};

enum Align {
    Left,
    Right,
    Center,
}

#[allow(dead_code)]
enum Color {
    White,
    BoldWhite,
    BoldRed,
    BoldGreen,
    BoldBlue,
}

fn color_text(text: &str, color: Color) -> String {
    let clrstr = match color {
        Color::White       => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[37m", text)        },
        Color::BoldWhite   => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[37m", text) },
        Color::BoldRed     => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[31m", text) },
        Color::BoldGreen   => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[32m", text) },
        Color::BoldBlue    => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[34m", text) },
    };

    clrstr
}

fn parse_result(column: &postgres::rows::Row, coltype: &Vec<types::Type>, colpos: usize) -> String {
    let val: String = match coltype[colpos] {
        types::Type::Text | types::Type::Varchar => column.get(colpos),
        types::Type::Bool => {
            let tmpbool: bool = column.get(colpos);
            match tmpbool {
                true  => String::from("true"),
                false => String::from("false"),
            }
        },
        types::Type::Int2 | types::Type::Int4 => {
            let tmpint: i32 = column.get(colpos);
            tmpint.to_string()
        },
        types::Type::Int8 => {
            let tmpint: i64 = column.get(colpos);
            tmpint.to_string()
        },
        types::Type::Float4 => {
            let tmpflt: f32 = column.get(colpos);
            tmpflt.to_string()
        },
        types::Type::Float8 => {
            let tmpflt: f64 = column.get(colpos);
            tmpflt.to_string()
        },
        _ => String::from(""),
    };

    val
}

fn get_alignment(coltype: &Vec<types::Type>, colpos: usize) -> Align {
    match coltype[colpos] {
        types::Type::Int2   => Align::Right,
        types::Type::Int4   => Align::Right,
        types::Type::Int8   => Align::Right,
        types::Type::Float4 => Align::Right,
        types::Type::Float8 => Align::Right,
        _                   => Align::Left,
    }
}

fn format_field(column: &str, width: usize, align: Align) -> String {
    let mut padstr = String::from("");
    let padlen: usize = width - column.len();

    for _ in 0..padlen {
        padstr = padstr + " ";
    }

    let ret: String = match align {
        Align::Right => format!("{}{}", padstr, column),
        Align::Left  => format!("{}{}", column, padstr),
    };

    ret
}

fn print_row(coltypes: &Vec<types::Type>, colwidths: &Vec<usize>, rowdata: &Vec<String>) {
    for (i, col) in rowdata.iter().enumerate() {
        let align = get_alignment(&coltypes, i);

        if i > 0 {
            print!("|");
        }

        print!(" {} ", format_field(&col, colwidths[i], align));
    }

    println!("");
}

fn print_header(colwidths: &Vec<usize>) {
    for (i, col) in colwidths.iter().enumerate() {
        if i > 0 {
            print!("+");
        }

        print!("-{data:-<width$}-", data="-", width=col);
    }

    println!("");
}

fn main() {
    let mut buf = String::new();
    let mut colnames: Vec<String> = Vec::new();
    let mut coldata: Vec<Vec<String>> = Vec::new();
    let mut colwidths: Vec<usize> = Vec::new();
    let mut coltypes: Vec<types::Type> = Vec::new();

    io::stdin().read_to_string(&mut buf);

    let conn = Connection::connect("postgres://jeff@localhost", SslMode::None).unwrap();
    let res = &conn.query(&mut buf, &[]).unwrap();
    let numcols = res.columns().len();

    for col in res.columns() {
        let colname = String::from(col.name());
        colwidths.push(colname.len());
        colnames.push(colname);
        coltypes.push(col.type_().clone());
    }

    for row in res.iter() {
        let mut colvals: Vec<String> = Vec::new();

        for i in 0..numcols {
            let ret = row.get_bytes(i);
            let col = if ret.is_some() { parse_result(&row, &coltypes, i) } else { String::from("") };

            if colwidths[i] < col.len() {
                colwidths[i] = col.len();
            }

            colvals.push(col);
        }

        coldata.push(colvals);
    }

    print_row(&coltypes, &colwidths, &colnames);
    print_header(&colwidths);
    for rowdata in coldata {
        print_row(&coltypes, &colwidths, &rowdata);
    }
}
<|endoftext|>


<commit_before>use std::io::{ErrorKind,Read,Write};
use mio::tcp::TcpStream;
use openssl::ssl::NonblockingSslStream;
use openssl::ssl::error::{NonblockingSslError,SslError};

#[derive(Debug)]
pub enum SocketResult {
  Continue,
  WouldBlock,
  Error
}

pub trait SocketHandler {
  fn socket_read(&mut self,  buf: &mut[u8]) -> (usize, SocketResult);
  fn socket_write(&mut self, buf: &[u8])    -> (usize, SocketResult);
  fn socket_ref(&self) -> &TcpStream;
}

impl SocketHandler for TcpStream {
  fn socket_read(&mut self,  buf: &mut[u8]) -> (usize, SocketResult) {
    match self.read(buf) {
      Ok(0)  => (0, SocketResult::Continue),
      Ok(sz) => (sz, SocketResult::Continue),
      Err(e) => match e.kind() {
        ErrorKind::WouldBlock => (0, SocketResult::WouldBlock),
        ErrorKind::BrokenPipe => {
          debug!("broken pipe reading from the socket");
          (0, SocketResult::Error)
        },
        _ => {
          debug!("not implemented; client err={:?}", e);
          (0, SocketResult::Error)
        },
      }
    }
  }

  fn socket_write(&mut self,  buf: &[u8]) -> (usize, SocketResult) {
    match self.write(buf) {
      Ok(0)  => (0, SocketResult::Continue),
      Ok(sz) => (sz, SocketResult::Continue),
      Err(e) => match e.kind() {
        ErrorKind::WouldBlock => (0, SocketResult::WouldBlock),
        ErrorKind::BrokenPipe => {
          debug!("broken pipe writing to the socket");
          (0, SocketResult::Error)
        },
        _ => {
          debug!("not implemented; client err={:?}", e);
          (0, SocketResult::Error)
        },
      }
    }
  }

  fn socket_ref(&self) -> &TcpStream { self }
}

impl SocketHandler for NonblockingSslStream<TcpStream> {
  fn socket_read(&mut self,  buf: &mut[u8]) -> (usize, SocketResult) {
    match self.read(buf) {
      Ok(0)  => (0, SocketResult::Continue),
      Ok(sz) => (sz, SocketResult::Continue),
      Err(NonblockingSslError::WantRead)    => (0, SocketResult::WouldBlock),
      Err(NonblockingSslError::WantWrite)   => (0, SocketResult::WouldBlock),
      Err(NonblockingSslError::SslError(e)) => {
         error!("readable TLS client err={:?}", e);
         (0, SocketResult::Error)
      }
    }
  }

  fn socket_write(&mut self,  buf: &[u8]) -> (usize, SocketResult) {
    match self.write(buf) {
      Ok(0)  => (0, SocketResult::Continue),
      Ok(sz) => (sz, SocketResult::Continue),
      Err(NonblockingSslError::WantRead)    => (0, SocketResult::WouldBlock),
      Err(NonblockingSslError::WantWrite)   => (0, SocketResult::WouldBlock),
      Err(NonblockingSslError::SslError(e)) => {
         error!("readable TLS client err={:?}", e);
         (0, SocketResult::Error)
      }
    }
  }

  fn socket_ref(&self) -> &TcpStream { self.get_ref() }
}
<commit_msg>Loop until blocking<commit_after>use std::io::{ErrorKind,Read,Write};
use mio::tcp::TcpStream;
use openssl::ssl::NonblockingSslStream;
use openssl::ssl::error::{NonblockingSslError,SslError};

#[derive(Debug)]
pub enum SocketResult {
  Continue,
  WouldBlock,
  Error
}

pub trait SocketHandler {
  fn socket_read(&mut self,  buf: &mut[u8]) -> (usize, SocketResult);
  fn socket_write(&mut self, buf: &[u8])    -> (usize, SocketResult);
  fn socket_ref(&self) -> &TcpStream;
}

impl SocketHandler for TcpStream {
  fn socket_read(&mut self,  buf: &mut[u8]) -> (usize, SocketResult) {
    let mut size = 0usize;
    loop {
      if size == buf.len() {
        return (size, SocketResult::Continue);
      }
      match self.read(&mut buf[size..]) {
        Ok(0)  => return (size, SocketResult::Continue),
        Ok(sz) => size +=sz,
        Err(e) => match e.kind() {
          ErrorKind::WouldBlock => return (size, SocketResult::WouldBlock),
          ErrorKind::BrokenPipe => {
            debug!("broken pipe reading from the socket");
            return (size, SocketResult::Error)
          },
          _ => {
            debug!("socket_write not implemented; client err={:?}", e);
            return (size, SocketResult::Error)
          },
        }
      }
    }
  }

  fn socket_write(&mut self,  buf: &[u8]) -> (usize, SocketResult) {
    let mut size = 0usize;
    loop {
      if size == buf.len() {
        return (size, SocketResult::Continue);
      }
      match self.write(&buf[size..]) {
        Ok(0)  => return (size, SocketResult::Continue),
        Ok(sz) => size += sz,
        Err(e) => match e.kind() {
          ErrorKind::WouldBlock => return (size, SocketResult::WouldBlock),
          ErrorKind::BrokenPipe => {
            debug!("broken pipe writing to the socket");
            return (size, SocketResult::Error)
          },
          _ => {
            debug!("socket_write not implemented; client err={:?}", e);
            return (size, SocketResult::Error)
          },
        }
      }
    }
  }

  fn socket_ref(&self) -> &TcpStream { self }
}

impl SocketHandler for NonblockingSslStream<TcpStream> {
  fn socket_read(&mut self,  buf: &mut[u8]) -> (usize, SocketResult) {
    let mut size = 0usize;
    loop {
      if size == buf.len() {
        return (size, SocketResult::Continue);
      }
      match self.read(&mut buf[size..]) {
        Ok(0)  => return (size, SocketResult::Continue),
        Ok(sz) => size += sz,
        Err(NonblockingSslError::WantRead)    => return (size, SocketResult::WouldBlock),
        Err(NonblockingSslError::WantWrite)   => return (size, SocketResult::WouldBlock),
        Err(NonblockingSslError::SslError(e)) => {
          error!("readable TLS client err={:?}", e);
          return (size, SocketResult::Error)
        }
      }
    }
  }

  fn socket_write(&mut self,  buf: &[u8]) -> (usize, SocketResult) {
    let mut size = 0usize;
    loop {
      if size == buf.len() {
        return (size, SocketResult::Continue);
      }
      match self.write(&buf[size..]) {
        Ok(0)  => return (size, SocketResult::Continue),
        Ok(sz) => size +=sz,
        Err(NonblockingSslError::WantRead)    => return (size, SocketResult::WouldBlock),
        Err(NonblockingSslError::WantWrite)   => return (size, SocketResult::WouldBlock),
        Err(NonblockingSslError::SslError(e)) => {
          error!("readable TLS client err={:?}", e);
          return (size, SocketResult::Error)
        }
      }
    }
  }

  fn socket_ref(&self) -> &TcpStream { self.get_ref() }
}
<|endoftext|>


<commit_before>//! Works only with correct paths or no arguments at all

use std::path::Path;
use std::{env, fs};

fn main() -> Result<(), std::io::Error> {
    // ignoring all arguments except the 1st
    if let Some(path) = env::args().nth(1) {
        // check if the program received an argument
        print_files(Path::new(&path))?;
    } else {
        // note that current_dir value might be invalid, so it's a Result
        print_files(&env::current_dir()?)?;
    };
    Ok(())
}

fn print_files(path: &Path) -> std::io::Result<()> {
    // flatten entries to avoid calling .unwrap()
    let mut entries: Vec<_> = fs::read_dir(path)?
        .flat_map(|res| res)
        .map(|f| f.file_name())
        .collect();
    // read_dir does not guarantee order
    entries.sort();
    entries.iter().for_each(|f| {
        println!("{}", f.to_string_lossy());
    });
    Ok(())
}
<commit_msg>incorporate euclio's helpful feedback<commit_after>//! Works only with correct paths or no arguments at all

use std::path::Path;
use std::{env, fs};

fn main() -> Result<(), std::io::Error> {
    // ignoring all arguments except the 1st
    if let Some(path) = env::args().nth(1) {
        // check if the program received an argument
        print_files(Path::new(&path))?;
    } else {
        // note that current_dir value might be invalid, so it's a Result
        print_files(&env::current_dir()?)?;
    };
    Ok(())
}

fn print_files(path: &Path) -> std::io::Result<()> {
    // flatten entries to avoid calling .unwrap()
    let mut entries: Vec<_> = fs::read_dir(path)?
        .flat_map(|entry| entry.ok().map(|f| f.file_name()))
        .collect();
    // read_dir does not guarantee order
    entries.sort();
    entries.iter().for_each(|f| {
        println!("{}", f.to_string_lossy());
    });
    Ok(())
}
<|endoftext|>