<commit_before>use std::borrow::Cow;
use std::fmt;
use std::io;
use std::ops::Deref;

use ansi::RESET;
use difference::Difference;
use style::{Style, Colour};
use write::AnyWrite;

/// An ANSIGenericString includes a generic string type and a Style to
/// display that string.  ANSIString and ANSIByteString are aliases for
/// this type on str and [u8], respectively.
#[derive(PartialEq, Debug, Clone)]
pub struct ANSIGenericString<'a, S: 'a + ToOwned + ?Sized>
where <S as ToOwned>::Owned: fmt::Debug {
    style: Style,
    string: Cow<'a, S>,
}

/// An ANSI String is a string coupled with the Style to display it
/// in a terminal.
///
/// Although not technically a string itself, it can be turned into
/// one with the `to_string` method.
///
/// ### Examples
///
/// ```no_run
/// use ansi_term::ANSIString;
/// use ansi_term::Colour::Red;
///
/// let red_string = Red.paint("a red string");
/// println!("{}", red_string);
/// ```
///
/// ```
/// use ansi_term::ANSIString;
///
/// let plain_string = ANSIString::from("a plain string");
/// assert_eq!(&*plain_string, "a plain string");
/// ```
pub type ANSIString<'a> = ANSIGenericString<'a, str>;

/// An ANSIByteString represents a formatted series of bytes.  Use
/// ANSIByteString when styling text with an unknown encoding.
pub type ANSIByteString<'a> = ANSIGenericString<'a, [u8]>;

impl<'a, I, S: 'a + ToOwned + ?Sized> From<I> for ANSIGenericString<'a, S>
where I: Into<Cow<'a, S>>,
      <S as ToOwned>::Owned: fmt::Debug {
    fn from(input: I) -> ANSIGenericString<'a, S> {
        ANSIGenericString {
            string: input.into(),
            style:  Style::default(),
        }
    }
}

impl<'a, S: 'a + ToOwned + ?Sized> Deref for ANSIGenericString<'a, S>
where <S as ToOwned>::Owned: fmt::Debug {
    type Target = S;

    fn deref(&self) -> &S {
        self.string.deref()
    }
}

/// A set of `ANSIGenericString`s collected together, in order to be
/// written with a minimum of control characters.
pub struct ANSIGenericStrings<'a, S: 'a + ToOwned + ?Sized>
    (pub &'a [ANSIGenericString<'a, S>])
    where <S as ToOwned>::Owned: fmt::Debug;

/// A set of `ANSIString`s collected together, in order to be written with a
/// minimum of control characters.
pub type ANSIStrings<'a> = ANSIGenericStrings<'a, str>;

/// A function to construct an ANSIStrings instance.
#[allow(non_snake_case)]
pub fn ANSIStrings<'a>(arg: &'a [ANSIString<'a>]) -> ANSIStrings<'a> {
    ANSIGenericStrings(arg)
}

/// A set of `ANSIByteString`s collected together, in order to be
/// written with a minimum of control characters.
pub type ANSIByteStrings<'a> = ANSIGenericStrings<'a, [u8]>;

/// A function to construct an ANSIByteStrings instance.
#[allow(non_snake_case)]
pub fn ANSIByteStrings<'a>(arg: &'a [ANSIByteString<'a>]) -> ANSIByteStrings<'a> {
    ANSIGenericStrings(arg)
}

// ---- paint functions ----

impl Style {

    /// Paints the given text with this colour, returning an ANSI string.
    pub fn paint<'a, I, S: 'a + ToOwned + ?Sized>(self, input: I) -> ANSIGenericString<'a, S>
    where I: Into<Cow<'a, S>>,
          <S as ToOwned>::Owned: fmt::Debug {
        ANSIGenericString {
            string: input.into(),
            style:  self,
        }
    }
}

impl Colour {

    /// Paints the given text with this colour, returning an ANSI string.
    /// This is a short-cut so you don't have to use Blue.normal() just
    /// to get blue text.
    pub fn paint<'a, I, S: 'a + ToOwned + ?Sized>(self, input: I) -> ANSIGenericString<'a, S>
    where I: Into<Cow<'a, S>>,
          <S as ToOwned>::Owned: fmt::Debug {
        ANSIGenericString {
            string: input.into(),
            style:  self.normal(),
        }
    }
}

// ---- writers for individual ANSI strings ----

impl<'a> fmt::Display for ANSIString<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let w: &mut fmt::Write = f;
        self.write_to_any(w)
    }
}

impl<'a> ANSIByteString<'a> {
    /// Write an ANSIByteString to an io::Write.  This writes the escape
    /// sequences for the associated Style around the bytes.
    pub fn write_to<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
        let w: &mut io::Write = w;
        self.write_to_any(w)
    }
}

impl<'a, S: 'a + ToOwned + ?Sized> ANSIGenericString<'a, S>
where <S as ToOwned>::Owned: fmt::Debug, &'a S: AsRef<[u8]> {
    fn write_to_any<W: AnyWrite<wstr=S> + ?Sized>(&self, w: &mut W) -> Result<(), W::Error> {
        write!(w, "{}", self.style.prefix())?;
        w.write_str(self.string.as_ref())?;
        write!(w, "{}", self.style.suffix())
    }
}

// ---- writers for combined ANSI strings ----

impl<'a> fmt::Display for ANSIStrings<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let f: &mut fmt::Write = f;
        self.write_to_any(f)
    }
}

impl<'a> ANSIByteStrings<'a> {
    /// Write ANSIByteStrings to an io::Write.  This writes the minimal
    /// escape sequences for the associated Styles around each set of
    /// bytes.
    pub fn write_to<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
        let w: &mut io::Write = w;
        self.write_to_any(w)
    }
}

impl<'a, S: 'a + ToOwned + ?Sized> ANSIGenericStrings<'a, S>
where <S as ToOwned>::Owned: fmt::Debug, &'a S: AsRef<[u8]> {
    fn write_to_any<W: AnyWrite<wstr=S> + ?Sized>(&self, w: &mut W) -> Result<(), W::Error> {
        use self::Difference::*;

        let first = match self.0.first() {
            None => return Ok(()),
            Some(f) => f,
        };

        write!(w, "{}", first.style.prefix())?;
        w.write_str(first.string.as_ref())?;

        for window in self.0.windows(2) {
            match Difference::between(&window[0].style, &window[1].style) {
                ExtraStyles(style) => write!(w, "{}", style.prefix())?,
                Reset              => write!(w, "{}{}", RESET, window[1].style.prefix())?,
                NoDifference       => {/* Do nothing! */},
            }

            w.write_str(&window[1].string)?;
        }

        // Write the final reset string after all of the ANSIStrings have been
        // written, *except* if the last one has no styles, because it would
        // have already been written by this point.
        if let Some(last) = self.0.last() {
            if !last.style.is_plain() {
                write!(w, "{}", RESET)?;
            }
        }

        Ok(())
    }
}

// ---- tests ----

#[cfg(test)]
mod tests {
    pub use super::super::ANSIStrings;
    pub use style::Style;
    pub use style::Colour::*;

    #[test]
    fn no_control_codes_for_plain() {
        let one = Style::default().paint("one");
        let two = Style::default().paint("two");
        let output = format!("{}", ANSIStrings( &[ one, two ] ));
        assert_eq!(&*output, "onetwo");
    }
}
<commit_msg>Markdown fix (and test) for Colour::paint<commit_after>use std::borrow::Cow;
use std::fmt;
use std::io;
use std::ops::Deref;

use ansi::RESET;
use difference::Difference;
use style::{Style, Colour};
use write::AnyWrite;

/// An ANSIGenericString includes a generic string type and a Style to
/// display that string.  ANSIString and ANSIByteString are aliases for
/// this type on str and [u8], respectively.
#[derive(PartialEq, Debug, Clone)]
pub struct ANSIGenericString<'a, S: 'a + ToOwned + ?Sized>
where <S as ToOwned>::Owned: fmt::Debug {
    style: Style,
    string: Cow<'a, S>,
}

/// An ANSI String is a string coupled with the Style to display it
/// in a terminal.
///
/// Although not technically a string itself, it can be turned into
/// one with the `to_string` method.
///
/// ### Examples
///
/// ```no_run
/// use ansi_term::ANSIString;
/// use ansi_term::Colour::Red;
///
/// let red_string = Red.paint("a red string");
/// println!("{}", red_string);
/// ```
///
/// ```
/// use ansi_term::ANSIString;
///
/// let plain_string = ANSIString::from("a plain string");
/// assert_eq!(&*plain_string, "a plain string");
/// ```
pub type ANSIString<'a> = ANSIGenericString<'a, str>;

/// An ANSIByteString represents a formatted series of bytes.  Use
/// ANSIByteString when styling text with an unknown encoding.
pub type ANSIByteString<'a> = ANSIGenericString<'a, [u8]>;

impl<'a, I, S: 'a + ToOwned + ?Sized> From<I> for ANSIGenericString<'a, S>
where I: Into<Cow<'a, S>>,
      <S as ToOwned>::Owned: fmt::Debug {
    fn from(input: I) -> ANSIGenericString<'a, S> {
        ANSIGenericString {
            string: input.into(),
            style:  Style::default(),
        }
    }
}

impl<'a, S: 'a + ToOwned + ?Sized> Deref for ANSIGenericString<'a, S>
where <S as ToOwned>::Owned: fmt::Debug {
    type Target = S;

    fn deref(&self) -> &S {
        self.string.deref()
    }
}

/// A set of `ANSIGenericString`s collected together, in order to be
/// written with a minimum of control characters.
pub struct ANSIGenericStrings<'a, S: 'a + ToOwned + ?Sized>
    (pub &'a [ANSIGenericString<'a, S>])
    where <S as ToOwned>::Owned: fmt::Debug;

/// A set of `ANSIString`s collected together, in order to be written with a
/// minimum of control characters.
pub type ANSIStrings<'a> = ANSIGenericStrings<'a, str>;

/// A function to construct an ANSIStrings instance.
#[allow(non_snake_case)]
pub fn ANSIStrings<'a>(arg: &'a [ANSIString<'a>]) -> ANSIStrings<'a> {
    ANSIGenericStrings(arg)
}

/// A set of `ANSIByteString`s collected together, in order to be
/// written with a minimum of control characters.
pub type ANSIByteStrings<'a> = ANSIGenericStrings<'a, [u8]>;

/// A function to construct an ANSIByteStrings instance.
#[allow(non_snake_case)]
pub fn ANSIByteStrings<'a>(arg: &'a [ANSIByteString<'a>]) -> ANSIByteStrings<'a> {
    ANSIGenericStrings(arg)
}

// ---- paint functions ----

impl Style {

    /// Paints the given text with this colour, returning an ANSI string.
    pub fn paint<'a, I, S: 'a + ToOwned + ?Sized>(self, input: I) -> ANSIGenericString<'a, S>
    where I: Into<Cow<'a, S>>,
          <S as ToOwned>::Owned: fmt::Debug {
        ANSIGenericString {
            string: input.into(),
            style:  self,
        }
    }
}

impl Colour {

    /// Paints the given text with this colour, returning an ANSI string.
    /// This is a short-cut so you don’t have to use `Blue.normal()` just
    /// to get blue text.
    ///
    /// ```
    /// use ansi_term::Colour::Blue;
    /// println!("{}", Blue.paint("da ba dee"));
    /// ```
    pub fn paint<'a, I, S: 'a + ToOwned + ?Sized>(self, input: I) -> ANSIGenericString<'a, S>
    where I: Into<Cow<'a, S>>,
          <S as ToOwned>::Owned: fmt::Debug {
        ANSIGenericString {
            string: input.into(),
            style:  self.normal(),
        }
    }
}

// ---- writers for individual ANSI strings ----

impl<'a> fmt::Display for ANSIString<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let w: &mut fmt::Write = f;
        self.write_to_any(w)
    }
}

impl<'a> ANSIByteString<'a> {
    /// Write an ANSIByteString to an io::Write.  This writes the escape
    /// sequences for the associated Style around the bytes.
    pub fn write_to<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
        let w: &mut io::Write = w;
        self.write_to_any(w)
    }
}

impl<'a, S: 'a + ToOwned + ?Sized> ANSIGenericString<'a, S>
where <S as ToOwned>::Owned: fmt::Debug, &'a S: AsRef<[u8]> {
    fn write_to_any<W: AnyWrite<wstr=S> + ?Sized>(&self, w: &mut W) -> Result<(), W::Error> {
        write!(w, "{}", self.style.prefix())?;
        w.write_str(self.string.as_ref())?;
        write!(w, "{}", self.style.suffix())
    }
}

// ---- writers for combined ANSI strings ----

impl<'a> fmt::Display for ANSIStrings<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let f: &mut fmt::Write = f;
        self.write_to_any(f)
    }
}

impl<'a> ANSIByteStrings<'a> {
    /// Write ANSIByteStrings to an io::Write.  This writes the minimal
    /// escape sequences for the associated Styles around each set of
    /// bytes.
    pub fn write_to<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
        let w: &mut io::Write = w;
        self.write_to_any(w)
    }
}

impl<'a, S: 'a + ToOwned + ?Sized> ANSIGenericStrings<'a, S>
where <S as ToOwned>::Owned: fmt::Debug, &'a S: AsRef<[u8]> {
    fn write_to_any<W: AnyWrite<wstr=S> + ?Sized>(&self, w: &mut W) -> Result<(), W::Error> {
        use self::Difference::*;

        let first = match self.0.first() {
            None => return Ok(()),
            Some(f) => f,
        };

        write!(w, "{}", first.style.prefix())?;
        w.write_str(first.string.as_ref())?;

        for window in self.0.windows(2) {
            match Difference::between(&window[0].style, &window[1].style) {
                ExtraStyles(style) => write!(w, "{}", style.prefix())?,
                Reset              => write!(w, "{}{}", RESET, window[1].style.prefix())?,
                NoDifference       => {/* Do nothing! */},
            }

            w.write_str(&window[1].string)?;
        }

        // Write the final reset string after all of the ANSIStrings have been
        // written, *except* if the last one has no styles, because it would
        // have already been written by this point.
        if let Some(last) = self.0.last() {
            if !last.style.is_plain() {
                write!(w, "{}", RESET)?;
            }
        }

        Ok(())
    }
}

// ---- tests ----

#[cfg(test)]
mod tests {
    pub use super::super::ANSIStrings;
    pub use style::Style;
    pub use style::Colour::*;

    #[test]
    fn no_control_codes_for_plain() {
        let one = Style::default().paint("one");
        let two = Style::default().paint("two");
        let output = format!("{}", ANSIStrings( &[ one, two ] ));
        assert_eq!(&*output, "onetwo");
    }
}
<|endoftext|>


<commit_before>
// https://users.rust-lang.org/t/what-am-i-doing-wrong-go-program-is-12x-faster-than-rust/5692/13
// https://doc.rust-lang.org/rustc-serialize/rustc_serialize/json/index.html
// https://serde.rs/codegen-hybrid.html

// FIXME: Use https://github.com/nox/serde_urlencoded
// FIXME: Make sure that all structs above Issue are not using `String`s instead of `Enum`s.
// FIXME: Harmonize the different state enums (e.g. IssueState, MergeRequestState, Authors)
// FIXME: Move all enums here (ListingOrderBy, ListingSort, etc.)
// FIXME: Use a type for sha1
// FIXME: Use chrono crate for dates
// FIXME: Use unsigned integers where it makes sense (id, iid, etc.)
// FIXME: Verify all `match` in push_str() in build_query(): They should contain all members.
// FIXME: Get rid of build_query(), use serde's Serialize instead.
// FIXME: Write nicer wrappers, getting rid of Listing.

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum ListingSort {
    #[serde(rename = "asc")]
    Asc,
    #[serde(rename = "desc")]
    Desc,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum ListingVisibility {
    #[serde(rename = "public")]
    Public,
    #[serde(rename = "internal")]
    Internal,
    #[serde(rename = "private")]
    Private,
}

#[derive(Debug, Serialize, Deserialize)]
enum IssueState {
    #[serde(rename = "opened")]
    Opened,

    #[serde(rename = "closed")]
    Closed,
}

#[derive(Debug, Serialize, Deserialize)]
enum UserState {
    #[serde(rename = "active")]
    Active,

    #[serde(rename = "blocked")]
    Blocked,
}

#[derive(Debug, Serialize, Deserialize)]
enum MilestoneState {
    #[serde(rename = "active")]
    Active,

    #[serde(rename = "closed")]
    Closed,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Version {
    pub version: String,
    pub revision: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Group {
    pub id: i64,
    pub name: String,
    pub path: String,
    pub description: String,
    pub visibility_level: i64,
    pub lfs_enabled: bool,
    pub avatar_url: Option<String>,
    pub web_url: String,
    pub request_access_enabled: bool,
}

pub type Groups = Vec<Group>;

#[derive(Debug, Serialize, Deserialize)]
pub struct ProjectOwner {
    pub name: String,
    pub username: String,
    pub id: i64,
    pub state: String,
    pub avatar_url: String,
    pub web_url: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectNamespaceAvatar {
    url: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectNamespace {
    id: i64,
    name: String,
    path: String,
    owner_id: Option<i64>,  // FIXME: Why would a project not have this?
    created_at: String,  // FIXME: Date instead?
    updated_at: String,  // FIXME: Date instead?
    description: String,
    avatar: Option<ProjectNamespaceAvatar>,
    membership_lock: Option<bool>,
    share_with_group_lock: bool,
    visibility_level: i64,
    request_access_enabled: bool,
    ldap_sync_status: Option<String>,
    ldap_sync_error: Option<String>,  // FIXME: Is String the proper type?
    ldap_sync_last_update_at: Option<String>,  // FIXME: Is String the proper type?
    ldap_sync_last_successful_update_at: Option<String>,  // FIXME: Is String the proper type?
    ldap_sync_last_sync_at: Option<String>,  // FIXME: Is String the proper type?
    deleted_at: Option<String>,  // FIXME: Is String the proper type?
    lfs_enabled: Option<String>,  // FIXME: Is String the proper type?
    repository_size_limit: Option<String>  // FIXME: Is String the proper type?
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectForkedFrom {
    id: i64,
    http_url_to_repo: String,
    web_url: String,
    name: String,
    name_with_namespace: String,
    path: String,
    path_with_namespace: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectAccess {
    access_level: i64,
    notification_level: i64,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectPermissions {
    project_access: Option<ProjectAccess>,
    group_access: Option<ProjectAccess>,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectSharedWithGroup {
    group_id: i64,
    group_name: String,
    group_access_level: i64,
}

// https://users.rust-lang.org/t/what-am-i-doing-wrong-go-program-is-12x-faster-than-rust/5692/13
// https://doc.rust-lang.org/rustc-serialize/rustc_serialize/json/index.html
#[derive(Debug, Serialize, Deserialize)]
pub struct Project {
    id: i64,
    description: String,
    default_branch: Option<String>,
    tag_list: Vec<String>,
    public: bool,
    archived: bool,
    visibility_level: i64,
    ssh_url_to_repo: String,
    http_url_to_repo: String,
    web_url: String,
    // owner: Option<ProjectOwner>,  // FIXME: Why would a project not have an owner?
    name: String,
    name_with_namespace: String,
    path: String,
    path_with_namespace: String,
    container_registry_enabled: Option<bool>,
    issues_enabled: bool,
    merge_requests_enabled: bool,
    wiki_enabled: bool,
    builds_enabled: bool,
    snippets_enabled: bool,
    created_at: String,  // FIXME: Date instead?
    last_activity_at: String,  // FIXME: Date instead?
    shared_runners_enabled: bool,
    lfs_enabled: bool,
    creator_id: i64,
    namespace: ProjectNamespace,
    forked_from_project: Option<ProjectForkedFrom>,
    avatar_url: Option<String>,
    star_count: i64,
    forks_count: i64,
    open_issues_count: i64,
    runners_token: Option<String>,
    public_builds: bool,
    shared_with_groups: Vec<ProjectSharedWithGroup>,
    only_allow_merge_if_build_succeeds: bool,
    request_access_enabled: bool,
    only_allow_merge_if_all_discussions_are_resolved: Option<bool>,  // FIXME: Is bool the proper type?
    approvals_before_merge: Option<i64>,
    permissions: ProjectPermissions,
}

pub type Projects = Vec<Project>;

#[derive(Debug, Serialize, Deserialize)]
struct Milestone {
    id: i64,
    iid: i64,
    project_id: i64,
    title: String,
    description: String,
    state: MilestoneState,
    created_at: String,  // FIXME: Use date type?
    updated_at: String,  // FIXME: Use date type?
    due_date: Option<String>  // FIXME: Use date type?
}

#[derive(Debug, Serialize, Deserialize)]
struct User {
    name: String,
    username: String,
    id: i64,
    state: UserState,
    avatar_url: Option<String>,
    web_url: Option<String>
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Issue {
    id: i64,
    iid: i64,
    project_id: i64,
    title: String,
    description: String,
    state: IssueState,
    created_at: String,  // FIXME: Use date type?
    updated_at: String,  // FIXME: Use date type?
    labels: Vec<String>,
    milestone: Option<Milestone>,
    assignee: Option<User>,
    author: User,
    subscribed: bool,
    user_notes_count: i64,
    upvotes: i64,
    downvotes: i64,
    due_date: Option<String>,  // FIXME: Use date type?
    confidential: bool,
    web_url: Option<String>
}

pub type Issues = Vec<Issue>;
<commit_msg>Bug fix: `Project::permissions` should be optional<commit_after>
// https://users.rust-lang.org/t/what-am-i-doing-wrong-go-program-is-12x-faster-than-rust/5692/13
// https://doc.rust-lang.org/rustc-serialize/rustc_serialize/json/index.html
// https://serde.rs/codegen-hybrid.html

// FIXME: Use https://github.com/nox/serde_urlencoded
// FIXME: Make sure that all structs above Issue are not using `String`s instead of `Enum`s.
// FIXME: Harmonize the different state enums (e.g. IssueState, MergeRequestState, Authors)
// FIXME: Move all enums here (ListingOrderBy, ListingSort, etc.)
// FIXME: Use a type for sha1
// FIXME: Use chrono crate for dates
// FIXME: Use unsigned integers where it makes sense (id, iid, etc.)
// FIXME: Verify all `match` in push_str() in build_query(): They should contain all members.
// FIXME: Get rid of build_query(), use serde's Serialize instead.
// FIXME: Write nicer wrappers, getting rid of Listing.

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum ListingSort {
    #[serde(rename = "asc")]
    Asc,
    #[serde(rename = "desc")]
    Desc,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum ListingVisibility {
    #[serde(rename = "public")]
    Public,
    #[serde(rename = "internal")]
    Internal,
    #[serde(rename = "private")]
    Private,
}

#[derive(Debug, Serialize, Deserialize)]
enum IssueState {
    #[serde(rename = "opened")]
    Opened,

    #[serde(rename = "closed")]
    Closed,
}

#[derive(Debug, Serialize, Deserialize)]
enum UserState {
    #[serde(rename = "active")]
    Active,

    #[serde(rename = "blocked")]
    Blocked,
}

#[derive(Debug, Serialize, Deserialize)]
enum MilestoneState {
    #[serde(rename = "active")]
    Active,

    #[serde(rename = "closed")]
    Closed,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Version {
    pub version: String,
    pub revision: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Group {
    pub id: i64,
    pub name: String,
    pub path: String,
    pub description: String,
    pub visibility_level: i64,
    pub lfs_enabled: bool,
    pub avatar_url: Option<String>,
    pub web_url: String,
    pub request_access_enabled: bool,
}

pub type Groups = Vec<Group>;

#[derive(Debug, Serialize, Deserialize)]
pub struct ProjectOwner {
    pub name: String,
    pub username: String,
    pub id: i64,
    pub state: String,
    pub avatar_url: String,
    pub web_url: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectNamespaceAvatar {
    url: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectNamespace {
    id: i64,
    name: String,
    path: String,
    owner_id: Option<i64>,  // FIXME: Why would a project not have this?
    created_at: String,  // FIXME: Date instead?
    updated_at: String,  // FIXME: Date instead?
    description: String,
    avatar: Option<ProjectNamespaceAvatar>,
    membership_lock: Option<bool>,
    share_with_group_lock: bool,
    visibility_level: i64,
    request_access_enabled: bool,
    ldap_sync_status: Option<String>,
    ldap_sync_error: Option<String>,  // FIXME: Is String the proper type?
    ldap_sync_last_update_at: Option<String>,  // FIXME: Is String the proper type?
    ldap_sync_last_successful_update_at: Option<String>,  // FIXME: Is String the proper type?
    ldap_sync_last_sync_at: Option<String>,  // FIXME: Is String the proper type?
    deleted_at: Option<String>,  // FIXME: Is String the proper type?
    lfs_enabled: Option<String>,  // FIXME: Is String the proper type?
    repository_size_limit: Option<String>  // FIXME: Is String the proper type?
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectForkedFrom {
    id: i64,
    http_url_to_repo: String,
    web_url: String,
    name: String,
    name_with_namespace: String,
    path: String,
    path_with_namespace: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectAccess {
    access_level: i64,
    notification_level: i64,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectPermissions {
    project_access: Option<ProjectAccess>,
    group_access: Option<ProjectAccess>,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectSharedWithGroup {
    group_id: i64,
    group_name: String,
    group_access_level: i64,
}

// https://users.rust-lang.org/t/what-am-i-doing-wrong-go-program-is-12x-faster-than-rust/5692/13
// https://doc.rust-lang.org/rustc-serialize/rustc_serialize/json/index.html
#[derive(Debug, Serialize, Deserialize)]
pub struct Project {
    id: i64,
    description: String,
    default_branch: Option<String>,
    tag_list: Vec<String>,
    public: bool,
    archived: bool,
    visibility_level: i64,
    ssh_url_to_repo: String,
    http_url_to_repo: String,
    web_url: String,
    // owner: Option<ProjectOwner>,  // FIXME: Why would a project not have an owner?
    name: String,
    name_with_namespace: String,
    path: String,
    path_with_namespace: String,
    container_registry_enabled: Option<bool>,
    issues_enabled: bool,
    merge_requests_enabled: bool,
    wiki_enabled: bool,
    builds_enabled: bool,
    snippets_enabled: bool,
    created_at: String,  // FIXME: Date instead?
    last_activity_at: String,  // FIXME: Date instead?
    shared_runners_enabled: bool,
    lfs_enabled: bool,
    creator_id: i64,
    namespace: ProjectNamespace,
    forked_from_project: Option<ProjectForkedFrom>,
    avatar_url: Option<String>,
    star_count: i64,
    forks_count: i64,
    open_issues_count: i64,
    runners_token: Option<String>,
    public_builds: bool,
    shared_with_groups: Vec<ProjectSharedWithGroup>,
    only_allow_merge_if_build_succeeds: bool,
    request_access_enabled: bool,
    only_allow_merge_if_all_discussions_are_resolved: Option<bool>,  // FIXME: Is bool the proper type?
    approvals_before_merge: Option<i64>,
    permissions: Option<ProjectPermissions>,
}

pub type Projects = Vec<Project>;

#[derive(Debug, Serialize, Deserialize)]
struct Milestone {
    id: i64,
    iid: i64,
    project_id: i64,
    title: String,
    description: String,
    state: MilestoneState,
    created_at: String,  // FIXME: Use date type?
    updated_at: String,  // FIXME: Use date type?
    due_date: Option<String>  // FIXME: Use date type?
}

#[derive(Debug, Serialize, Deserialize)]
struct User {
    name: String,
    username: String,
    id: i64,
    state: UserState,
    avatar_url: Option<String>,
    web_url: Option<String>
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Issue {
    id: i64,
    iid: i64,
    project_id: i64,
    title: String,
    description: String,
    state: IssueState,
    created_at: String,  // FIXME: Use date type?
    updated_at: String,  // FIXME: Use date type?
    labels: Vec<String>,
    milestone: Option<Milestone>,
    assignee: Option<User>,
    author: User,
    subscribed: bool,
    user_notes_count: i64,
    upvotes: i64,
    downvotes: i64,
    due_date: Option<String>,  // FIXME: Use date type?
    confidential: bool,
    web_url: Option<String>
}

pub type Issues = Vec<Issue>;
<|endoftext|>


<commit_before>use std::path::Path;
use std::fs::File;

use image::{ DynamicImage, GenericImage, ImageFormat };
use image;

use bitreader::BitReader;

pub struct CoverImage {
    cover_image: DynamicImage
}

impl CoverImage {
    pub fn new(file_path: &str) -> CoverImage {
        CoverImage { cover_image: image::open(&Path::new(&file_path)).unwrap() }
    }

    pub fn encode_with(&self, message: &str) {
        let bit_vector = get_bit_vec(message);

        encode(&self.cover_image, &bit_vector);

        let ref mut fout = File::create(&Path::new("/home/hugh/Pictures/yurt.png")).unwrap();

        let _ = self.cover_image.save(fout, ImageFormat::PNG).unwrap();
    }
}

// Get a Vector of Bits to Encode the Image with
fn get_bit_vec(message: &str) -> Vec<u8> {
    let mut bit_vector = Vec::new();
    let mut reader = BitReader::new(&message.as_bytes());

    // Multiplied by 8 because it's a Vec of bits not bytes
    for _ in 0..message.len() * 8 {
        bit_vector.push(reader.read_u8(1).unwrap());
    }

    bit_vector
}

// Encode the image with the Vector of Bits
fn encode(c_image: &DynamicImage, bit_vec: &Vec<u8>) {
    let mut tiled_image_vec = tile_image(c_image);
    let encoded_image = dct(&mut tiled_image_vec, bit_vec);
}

fn tile_image(c_image: &DynamicImage) -> Vec<image::Rgba<u8>> {
    let (width, height) = c_image.dimensions();

    let mut image_blocks = Vec::new();

    for row_index in 0..(height / 8) as u32 {
        for col_index in 0..(width / 8) as u32 {
            for row in 0..8 {
                for column in 0..8 {
                    image_blocks.push(c_image.get_pixel(column + (col_index * 8), row + (row_index * 8)));
                }
            }
        }
    }

    image_blocks
}

fn dct(tiled_image: &mut Vec<image::Rgba<u8>>, message: &Vec<u8>) {
    for (x, y) in (0..2).enumerate() {

    }
}

/**************************************************************************************************
 *                                                                                *
 *                                         Tests                                                  *
 *                                                                                *
 **************************************************************************************************/

#[cfg(test)]
#[test]
fn test_get_bit_vec_len() {
    let bits = get_bit_vec("h");

    assert_eq!(8, bits.len());
}

#[cfg(test)]
#[test]
fn test_get_bit_vec() {
    let test_bits = vec![0, 1, 1, 0, 1, 0, 0, 0];
    let bits = get_bit_vec("h");

    assert_eq!(bits, test_bits);
}

#[cfg(test)]
#[test]
fn test_encode_red_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[0] % 2, bit_vec[0]);
}

#[cfg(test)]
#[test]
fn test_encode_green_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[1] % 2, bit_vec[1]);
}

#[cfg(test)]
#[test]
fn test_encode_blue_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[2] % 2 as u8, bit_vec[2]);
}

#[cfg(test)]
#[test]
fn test_full_byte_is_encoded() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let mut encoded_bit_vec = Vec::new();
    let mut count = 0;

    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    'outer: for x_co_ord in 0..3 {
        let pixel = img.get_pixel(x_co_ord, 0);

        for channel in 0..3 {
            if count >= 8 {
                break 'outer;
            }

            encoded_bit_vec.push(pixel.data[channel] % 2);

            count += 1;
        }
    }

    assert_eq!(encoded_bit_vec, bit_vec);
}

#[cfg(test)]
#[test]
fn test_tile_image_length() {
    let img = image::open(&Path::new("/home/hugh/Pictures/colour.jpg")).unwrap();

    let vec = tile_image(&img);

    assert_eq!(vec.len(), 91200);
}

#[cfg(test)]
#[test]
fn test_tile_image_first_pixel() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(0, 0);

    let vec = tile_image(&img);

    assert_eq!(vec[0], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel1() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(15, 7);

    let vec = tile_image(&img);

    assert_eq!(vec[127], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel2() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(40, 16);

    let vec = tile_image(&img);

    assert_eq!(vec[6720], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel3() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(15, 7);

    let vec = tile_image(&img);

    assert_eq!(vec[127], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_last_pixel() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(399, 399);

    let vec = tile_image(&img);

    assert_eq!(vec[159999], pixel);
}
<commit_msg>More stuff for dct<commit_after>use std::path::Path;
use std::fs::File;

use image::{ DynamicImage, GenericImage, ImageFormat };
use image;

use bitreader::BitReader;

pub struct CoverImage {
    cover_image: DynamicImage
}

impl CoverImage {
    pub fn new(file_path: &str) -> CoverImage {
        CoverImage { cover_image: image::open(&Path::new(&file_path)).unwrap() }
    }

    pub fn encode_with(&self, message: &str) {
        let bit_vector = get_bit_vec(message);

        encode(&self.cover_image, &bit_vector);

        let ref mut fout = File::create(&Path::new("/home/hugh/Pictures/yurt.png")).unwrap();

        let _ = self.cover_image.save(fout, ImageFormat::PNG).unwrap();
    }
}

// Get a Vector of Bits to Encode the Image with
fn get_bit_vec(message: &str) -> Vec<u8> {
    let mut bit_vector = Vec::new();
    let mut reader = BitReader::new(&message.as_bytes());

    // Multiplied by 8 because it's a Vec of bits not bytes
    for _ in 0..message.len() * 8 {
        bit_vector.push(reader.read_u8(1).unwrap());
    }

    bit_vector
}

// Encode the image with the Vector of Bits
fn encode(c_image: &DynamicImage, bit_vec: &Vec<u8>) {
    let mut tiled_image_vec = tile_image(c_image);
    let encoded_image = encode_image(&mut tiled_image_vec, bit_vec);
}

fn tile_image(c_image: &DynamicImage) -> Vec<image::Rgba<u8>> {
    let (width, height) = c_image.dimensions();

    let mut image_blocks = Vec::new();

    for row_index in 0..(height / 8) as u32 {
        for col_index in 0..(width / 8) as u32 {
            for row in 0..8 {
                for column in 0..8 {
                    image_blocks.push(c_image.get_pixel(column + (col_index * 8), row + (row_index * 8)));
                }
            }
        }
    }

    image_blocks
}

fn encode_image(tiled_image: &mut Vec<image::Rgba<u8>>, message: &Vec<u8>) {

}

/**************************************************************************************************
 *                                                                                *
 *                                         Tests                                                  *
 *                                                                                *
 **************************************************************************************************/

#[cfg(test)]
#[test]
fn test_get_bit_vec_len() {
    let bits = get_bit_vec("h");

    assert_eq!(8, bits.len());
}

#[cfg(test)]
#[test]
fn test_get_bit_vec() {
    let test_bits = vec![0, 1, 1, 0, 1, 0, 0, 0];
    let bits = get_bit_vec("h");

    assert_eq!(bits, test_bits);
}

#[cfg(test)]
#[test]
fn test_encode_red_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[0] % 2, bit_vec[0]);
}

#[cfg(test)]
#[test]
fn test_encode_green_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[1] % 2, bit_vec[1]);
}

#[cfg(test)]
#[test]
fn test_encode_blue_channel_lsb_set() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    let pixel = img.get_pixel(0, 0);

    assert_eq!(pixel.data[2] % 2 as u8, bit_vec[2]);
}

#[cfg(test)]
#[test]
fn test_full_byte_is_encoded() {
    let mut img = image::open(&Path::new("/home/hugh/Pictures/scenery.jpg")).unwrap();
    let mut encoded_bit_vec = Vec::new();
    let mut count = 0;

    let bit_vec = vec![0, 1, 1, 0, 1, 0, 0, 0];

    encode(&mut img, &bit_vec);

    'outer: for x_co_ord in 0..3 {
        let pixel = img.get_pixel(x_co_ord, 0);

        for channel in 0..3 {
            if count >= 8 {
                break 'outer;
            }

            encoded_bit_vec.push(pixel.data[channel] % 2);

            count += 1;
        }
    }

    assert_eq!(encoded_bit_vec, bit_vec);
}

#[cfg(test)]
#[test]
fn test_tile_image_length() {
    let img = image::open(&Path::new("/home/hugh/Pictures/colour.jpg")).unwrap();

    let vec = tile_image(&img);

    assert_eq!(vec.len(), 91200);
}

#[cfg(test)]
#[test]
fn test_tile_image_first_pixel() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(0, 0);

    let vec = tile_image(&img);

    assert_eq!(vec[0], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel1() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(15, 7);

    let vec = tile_image(&img);

    assert_eq!(vec[127], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel2() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(40, 16);

    let vec = tile_image(&img);

    assert_eq!(vec[6720], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_random_pixel3() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(15, 7);

    let vec = tile_image(&img);

    assert_eq!(vec[127], pixel);
}

#[cfg(test)]
#[test]
fn test_tile_image_last_pixel() {
    let img = image::open(&Path::new("/home/hugh/Pictures/project.jpg")).unwrap();

    let pixel = img.get_pixel(399, 399);

    let vec = tile_image(&img);

    assert_eq!(vec[159999], pixel);
}
<|endoftext|>


<commit_before>//! Starts a timely dataflow execution from configuration information and per-worker logic.

use timely_communication::{initialize, Configuration, Allocator, WorkerGuards};
use dataflow::scopes::{Root, Child, Scope};

/// Executes a single-threaded timely dataflow computation.
///
/// The `example` method takes a closure on a `Scope` which it executes to initialize and run a
/// timely dataflow computation on a single thread. This method is intended for use in examples,
/// rather than programs that may need to run across multiple workers.
///
/// #Examples
/// ```
/// use timely::dataflow::operators::{ToStream, Inspect};
///
/// timely::example(|scope| {
///     (0..10).to_stream(scope)
///            .inspect(|x| println!("seen: {:?}", x));
/// });
/// ```
pub fn example<F>(func: F)
where F: Fn(&mut Child<Root<Allocator>, u64>)+Send+Sync+'static {
    initialize(Configuration::Thread, move |allocator| {
        let mut root = Root::new(allocator);
        root.scoped::<u64,_,_>(|x| func(x));
        while root.step() { }
    }).unwrap();
}

/// Executes a timely dataflow from a configuration and per-communicator logic.
///
/// The `execute` method takes a `Configuration` and spins up some number of
/// workers threads, each of which execute the supplied closure to construct and run a timely
/// dataflow computation.
///
/// #Examples
/// ```
/// use timely::dataflow::Scope;
/// use timely::dataflow::operators::{ToStream, Inspect};
///
/// // execute a timely dataflow using three worker threads.
/// timely::execute(timely::Configuration::Process(3), |root| {
///     root.scoped::<u64,_,_>(|scope| {
///         (0..10).to_stream(scope)
///                .inspect(|x| println!("seen: {:?}", x));
///     })
/// }).unwrap();
/// ```
pub fn execute<T:Send+'static, F>(config: Configuration, func: F) -> Result<WorkerGuards<T>,String>
where F: Fn(&mut Root<Allocator>)->T+Send+Sync+'static {
    initialize(config, move |allocator| {
        let mut root = Root::new(allocator);
        let result = func(&mut root);
        while root.step() { }
        result
    })
}

/// Executes a timely dataflow from supplied arguments and per-communicator logic.
///
/// The `execute` method takes arguments (typically `std::env::args()`) and spins up some number of
/// workers threads, each of which execute the supplied closure to construct and run a timely
/// dataflow computation.
///
/// The arguments `execute` currently understands are:
///
/// `-w, --workers`: number of per-process worker threads.
///
/// `-n, --processes`: number of processes involved in the computation.
///
/// `-p, --process`: identity of this process; from 0 to n-1.
///
/// `-h, --hostfile`: a text file whose lines are "hostname:port" in order of process identity.
/// If not specified, `localhost` will be used, with port numbers increasing from 2101 (chosen
/// arbitrarily).
///
/// #Examples
/// ```
/// use timely::dataflow::*;
/// use timely::dataflow::operators::{ToStream, Inspect};
///
/// // execute a timely dataflow using command line parameters
/// timely::execute_from_args(std::env::args(), |root| {
///     root.scoped::<u64,_,_>(|scope| {
///         (0..10).to_stream(scope)
///                .inspect(|x| println!("seen: {:?}", x));
///     })
/// }).unwrap();
/// ```
/// ```ignore
/// host0% cargo run -- -w 2 -n 4 -h hosts.txt -p 0
/// host1% cargo run -- -w 2 -n 4 -h hosts.txt -p 1
/// host2% cargo run -- -w 2 -n 4 -h hosts.txt -p 2
/// host3% cargo run -- -w 2 -n 4 -h hosts.txt -p 3
/// ```
/// ```ignore
/// % cat hosts.txt
/// host0:port
/// host1:port
/// host2:port
/// host3:port
/// ```
pub fn execute_from_args<I, T:Send+'static, F>(iter: I, func: F) -> Result<WorkerGuards<T>,String>
    where I: Iterator<Item=String>,
          F: Fn(&mut Root<Allocator>)->T+Send+Sync+'static, {
    execute(try!(Configuration::from_args(iter)), func)
 }
<commit_msg>added information about returning results from execute closures<commit_after>//! Starts a timely dataflow execution from configuration information and per-worker logic.

use timely_communication::{initialize, Configuration, Allocator, WorkerGuards};
use dataflow::scopes::{Root, Child, Scope};

/// Executes a single-threaded timely dataflow computation.
///
/// The `example` method takes a closure on a `Scope` which it executes to initialize and run a
/// timely dataflow computation on a single thread. This method is intended for use in examples,
/// rather than programs that may need to run across multiple workers.
///
/// #Examples
/// ```
/// use timely::dataflow::operators::{ToStream, Inspect};
///
/// timely::example(|scope| {
///     (0..10).to_stream(scope)
///            .inspect(|x| println!("seen: {:?}", x));
/// });
/// ```
pub fn example<F>(func: F)
where F: Fn(&mut Child<Root<Allocator>, u64>)+Send+Sync+'static {
    initialize(Configuration::Thread, move |allocator| {
        let mut root = Root::new(allocator);
        root.scoped::<u64,_,_>(|x| func(x));
        while root.step() { }
    }).unwrap();
}

/// Executes a timely dataflow from a configuration and per-communicator logic.
///
/// The `execute` method takes a `Configuration` and spins up some number of
/// workers threads, each of which execute the supplied closure to construct
/// and run a timely dataflow computation.
///
/// The closure may return a `T: Send+'static`, and `execute` returns a result
/// containing a `WorkerGuards<T>` (or error information), which can be joined
/// to recover the result `T` values from the local workers.
///
/// #Examples
/// ```
/// use timely::dataflow::Scope;
/// use timely::dataflow::operators::{ToStream, Inspect};
///
/// // execute a timely dataflow using three worker threads.
/// timely::execute(timely::Configuration::Process(3), |root| {
///     root.scoped::<u64,_,_>(|scope| {
///         (0..10).to_stream(scope)
///                .inspect(|x| println!("seen: {:?}", x));
///     })
/// }).unwrap();
/// ```
pub fn execute<T:Send+'static, F>(config: Configuration, func: F) -> Result<WorkerGuards<T>,String>
where F: Fn(&mut Root<Allocator>)->T+Send+Sync+'static {
    initialize(config, move |allocator| {
        let mut root = Root::new(allocator);
        let result = func(&mut root);
        while root.step() { }
        result
    })
}

/// Executes a timely dataflow from supplied arguments and per-communicator logic.
///
/// The `execute` method takes arguments (typically `std::env::args()`) and spins up some number of
/// workers threads, each of which execute the supplied closure to construct and run a timely
/// dataflow computation.
///
/// The closure may return a `T: Send+'static`, and `execute` returns a result
/// containing a `WorkerGuards<T>` (or error information), which can be joined
/// to recover the result `T` values from the local workers.
///
/// The arguments `execute` currently understands are:
///
/// `-w, --workers`: number of per-process worker threads.
///
/// `-n, --processes`: number of processes involved in the computation.
///
/// `-p, --process`: identity of this process; from 0 to n-1.
///
/// `-h, --hostfile`: a text file whose lines are "hostname:port" in order of process identity.
/// If not specified, `localhost` will be used, with port numbers increasing from 2101 (chosen
/// arbitrarily).
///
/// #Examples
/// ```
/// use timely::dataflow::*;
/// use timely::dataflow::operators::{ToStream, Inspect};
///
/// // execute a timely dataflow using command line parameters
/// timely::execute_from_args(std::env::args(), |root| {
///     root.scoped::<u64,_,_>(|scope| {
///         (0..10).to_stream(scope)
///                .inspect(|x| println!("seen: {:?}", x));
///     })
/// }).unwrap();
/// ```
/// ```ignore
/// host0% cargo run -- -w 2 -n 4 -h hosts.txt -p 0
/// host1% cargo run -- -w 2 -n 4 -h hosts.txt -p 1
/// host2% cargo run -- -w 2 -n 4 -h hosts.txt -p 2
/// host3% cargo run -- -w 2 -n 4 -h hosts.txt -p 3
/// ```
/// ```ignore
/// % cat hosts.txt
/// host0:port
/// host1:port
/// host2:port
/// host3:port
/// ```
pub fn execute_from_args<I, T:Send+'static, F>(iter: I, func: F) -> Result<WorkerGuards<T>,String>
    where I: Iterator<Item=String>,
          F: Fn(&mut Root<Allocator>)->T+Send+Sync+'static, {
    execute(try!(Configuration::from_args(iter)), func)
 }
<|endoftext|>


<commit_before>#![cfg_attr(not(feature = "gtk_3_10"), allow(unused_variables, unused_mut))]

extern crate gtk;
extern crate gdk;

use gtk::prelude::*;
use gdk::enums::modifier_type;

/// Expands to its argument if GTK+ 3.10 support is configured and to `()` otherwise
#[cfg(not(feature = "gtk_3_10"))]
macro_rules! with_gtk_3_10 {
    ($ex:expr) => (
        ()
    );
    ($bl:block) => {
        ()
    }
}

/// Expands to its argument if GTK+ 3.10 support is configured and to `()` otherwise
#[cfg(feature = "gtk_3_10")]
macro_rules! with_gtk_3_10 {
    ($ex:expr) => (
        $ex
    );
    ($bl:block) => {
        $bl
    }
}

// make moving clones into closures more convenient
macro_rules! clone {
    (@param _) => ( _ );
    (@param $x:ident) => ( $x );
    ($($n:ident),+ => move || $body:expr) => (
        {
            $( let $n = $n.clone(); )+
            move || $body
        }
    );
    ($($n:ident),+ => move |$($p:tt),+| $body:expr) => (
        {
            $( let $n = $n.clone(); )+
            move |$(clone!(@param $p),)+| $body
        }
    );
}

fn about_clicked(button: &gtk::Button) {
    let dialog = gtk::AboutDialog::new();
    if let Some(window) = button.get_toplevel().and_then(|w| w.downcast::<gtk::Window>().ok()) {
        dialog.set_transient_for(Some(&window));
    }

    let crew = [
        "James T. Kirk",
        "Spock",
        "Leonard McCoy",
    ];

    dialog.set_authors(&crew);
    dialog.set_artists(&crew[1..]);

    println!("Authors: {:?}", dialog.get_authors());
    println!("Artists: {:?}", dialog.get_artists());
    println!("Documenters: {:?}", dialog.get_documenters());

    dialog.run();
    dialog.destroy();
}

fn main() {
    if gtk::init().is_err() {
        println!("Failed to initialize GTK.");
        return;
    }
    println!("Major: {}, Minor: {}", gtk::get_major_version(), gtk::get_minor_version());
    let window = gtk::Window::new(gtk::WindowType::Toplevel);
    let frame = gtk::Frame::new(Some("Yep a frame"));
    let _box = gtk::Box::new(gtk::Orientation::Horizontal, 10);
    let v_box = gtk::Box::new(gtk::Orientation::Horizontal, 10);
    let button_box = gtk::ButtonBox::new(gtk::Orientation::Horizontal);
    let label = gtk::Label::new(Some("Yeah a wonderful label too !"));
    let button = gtk::Button::new_with_label("Whattttt a button !");
    let button_about = gtk::Button::new_with_label("About?");
    let button_recent = gtk::Button::new_with_label("Choose a recent one !");
    let button_font = gtk::Button::new_with_label("Choose a font !");
    let app_button = gtk::Button::new_with_label("App ?");
    let file_button = gtk::Button::new_with_label("file ?");
    let font_button = gtk::FontButton::new();
    let toggle_button = gtk::ToggleButton::new_with_label("Toggle Me !");
    let check_button = gtk::CheckButton::new_with_label("Labeled check button");
    let color_button = gtk::ColorButton::new();
    let menu_button = with_gtk_3_10!(
        gtk::MenuButton::new()
    );
    let link_button = gtk::LinkButton::new("www.rust-lang.org");
    let volume_button = gtk::VolumeButton::new();
    let entry = gtk::Entry::new();
    let search_entry = with_gtk_3_10!(
        gtk::SearchEntry::new()
    );
    let separator = gtk::Separator::new(gtk::Orientation::Horizontal);
    let separator2 = gtk::Separator::new(gtk::Orientation::Horizontal);
    let switch = gtk::Switch::new();
    let switch2 = gtk::Switch::new();
    let scale = gtk::Scale::new_with_range(gtk::Orientation::Horizontal, 0., 100., 1.);
    let level_bar = with_gtk_3_10!(
        gtk::LevelBar::new_for_interval(0., 100.)
    );
    let spin_button = gtk::SpinButton::new_with_range(0., 100., 1.);
    let spinner = gtk::Spinner::new();
    let image = gtk::Image::new_from_file("./test/resources/gtk.jpg");
    let progress_bar = gtk::ProgressBar::new();
    let arrow = gtk::Arrow::new(gtk::ArrowType::Right, gtk::ShadowType::EtchedOut);
    let calendar = gtk::Calendar::new();
    let info_bar = gtk::InfoBar::new();
    let tmp_button = with_gtk_3_10!(
        gtk::Button::new_from_icon_name("edit-clear", gtk::IconSize::Button as i32)
    );

    println!("test");

    with_gtk_3_10! {{
        info_bar.set_show_close_button(true);
    }}

    /*info_bar.connect(signals::Response::new(|response_id| {
        info_bar.hide()
    }));*/ //TODO: Why does this not work?

    progress_bar.set_fraction(0.7);
    spinner.start();
    with_gtk_3_10! {{
        level_bar.set_value(37.);
    }}
    switch2.set_active(true);
    frame.set_border_width(10);
    _box.set_border_width(5);
    entry.set_placeholder_text(Some("An Entry with a placeholder !"));
    volume_button.set_orientation(gtk::Orientation::Horizontal);
    label.set_justify(gtk::Justification::Left);
    window.set_title("Yeah a beautiful window with gtk !");
    window.set_position(gtk::WindowPosition::Center);
    window.add(&frame);

    let entry_clone = entry.clone();
    button.connect_clicked(clone!(window => move |_| {
        let dialog = gtk::Dialog::new_with_buttons(Some("Hello!"), Some(&window), gtk::DIALOG_MODAL,
            &[("No", 0), ("Yes", 1), ("Yes!", 2)]);

        let ret = dialog.run();

        dialog.destroy();

        entry_clone.set_text(&format!("Clicked {}", ret));
    }));

    // use a plain function instead of a closure
    button_about.connect_clicked(about_clicked);

    button_font.connect_clicked(clone!(window => move |_| {
        let dialog = gtk::FontChooserDialog::new(Some("Font chooser test"), Some(&window));

        dialog.run();
        dialog.destroy();
    }));

    button_recent.connect_clicked(clone!(window => move |_| {
        let dialog = gtk::RecentChooserDialog::new(Some("Recent chooser test"), Some(&window));
        dialog.add_buttons(&[
            ("Ok", gtk::ResponseType::Ok as i32),
            ("Cancel", gtk::ResponseType::Cancel as i32)
        ]);

        dialog.run();
        dialog.destroy();
    }));

    file_button.connect_clicked(clone!(window => move |_| {
        //entry.set_text("Clicked!");
        let dialog = gtk::FileChooserDialog::new(Some("Choose a file"), Some(&window),
            gtk::FileChooserAction::Open);
        dialog.add_buttons(&[
            ("Open", gtk::ResponseType::Ok as i32),
            ("Cancel", gtk::ResponseType::Cancel as i32)
        ]);

        dialog.set_select_multiple(true);
        dialog.run();
        let files = dialog.get_filenames();
        dialog.destroy();

        println!("Files: {:?}", files);
    }));

    app_button.connect_clicked(clone!(window => move |_| {
        //entry.set_text("Clicked!");
        let dialog = gtk::AppChooserDialog::new_for_content_type(Some(&window), gtk::DIALOG_MODAL,
            "sh");

        dialog.run();
        dialog.destroy();
    }));

    let entry_clone = entry.clone();
    window.connect_key_press_event(move |_, key| {
        let keyval = key.as_ref().keyval;
        let keystate = key.as_ref().state;

        println!("key pressed: {} / {:?}", keyval, keystate);
        println!("text: {}", entry_clone.get_text().unwrap());

        if keystate.intersects(modifier_type::ControlMask) {
            println!("You pressed Ctrl!");
        }

        Inhibit(false)
    });

    window.connect_delete_event(|_, _| {
        gtk::main_quit();
        Inhibit(false)
    });

    frame.add(&_box);
    with_gtk_3_10! {{
        button_box.add(&tmp_button)
    }};
    button_box.add(&button);
    button_box.add(&button_about);
    button_box.add(&button_font);
    button_box.add(&button_recent);
    button_box.add(&file_button);
    button_box.add(&app_button);
    button_box.add(&font_button);
    button_box.add(&toggle_button);
    button_box.add(&color_button);
    button_box.add(&volume_button);
    v_box.add(&switch);
    with_gtk_3_10! {{
        v_box.add(&menu_button);
    }}
    v_box.add(&switch2);
    v_box.add(&check_button);
    v_box.add(&link_button);
    v_box.add(&spin_button);
    _box.add(&info_bar);
    _box.add(&v_box);
    _box.add(&scale);
    with_gtk_3_10! {{
        _box.add(&level_bar);
    }}
    _box.add(&button_box);
    _box.add(&progress_bar);
    _box.add(&separator);
    _box.add(&label);
    _box.add(&entry);
    _box.add(&separator2);
    with_gtk_3_10! {{
        _box.add(&search_entry);
    }}
    _box.add(&spinner);
    _box.add(&image);
    _box.add(&arrow);
    _box.add(&calendar);
    _box.set_orientation(gtk::Orientation::Vertical);
    // window.set_decorated(false);
    window.set_decorated(true);
    window.show_all();
    gtk::main();
}
<commit_msg>Add scale value formating<commit_after>#![cfg_attr(not(feature = "gtk_3_10"), allow(unused_variables, unused_mut))]

extern crate gtk;
extern crate gdk;

use gtk::prelude::*;
use gdk::enums::modifier_type;

/// Expands to its argument if GTK+ 3.10 support is configured and to `()` otherwise
#[cfg(not(feature = "gtk_3_10"))]
macro_rules! with_gtk_3_10 {
    ($ex:expr) => (
        ()
    );
    ($bl:block) => {
        ()
    }
}

/// Expands to its argument if GTK+ 3.10 support is configured and to `()` otherwise
#[cfg(feature = "gtk_3_10")]
macro_rules! with_gtk_3_10 {
    ($ex:expr) => (
        $ex
    );
    ($bl:block) => {
        $bl
    }
}

// make moving clones into closures more convenient
macro_rules! clone {
    (@param _) => ( _ );
    (@param $x:ident) => ( $x );
    ($($n:ident),+ => move || $body:expr) => (
        {
            $( let $n = $n.clone(); )+
            move || $body
        }
    );
    ($($n:ident),+ => move |$($p:tt),+| $body:expr) => (
        {
            $( let $n = $n.clone(); )+
            move |$(clone!(@param $p),)+| $body
        }
    );
}

fn about_clicked(button: &gtk::Button) {
    let dialog = gtk::AboutDialog::new();
    if let Some(window) = button.get_toplevel().and_then(|w| w.downcast::<gtk::Window>().ok()) {
        dialog.set_transient_for(Some(&window));
    }

    let crew = [
        "James T. Kirk",
        "Spock",
        "Leonard McCoy",
    ];

    dialog.set_authors(&crew);
    dialog.set_artists(&crew[1..]);

    println!("Authors: {:?}", dialog.get_authors());
    println!("Artists: {:?}", dialog.get_artists());
    println!("Documenters: {:?}", dialog.get_documenters());

    dialog.run();
    dialog.destroy();
}

fn main() {
    if gtk::init().is_err() {
        println!("Failed to initialize GTK.");
        return;
    }
    println!("Major: {}, Minor: {}", gtk::get_major_version(), gtk::get_minor_version());
    let window = gtk::Window::new(gtk::WindowType::Toplevel);
    let frame = gtk::Frame::new(Some("Yep a frame"));
    let _box = gtk::Box::new(gtk::Orientation::Horizontal, 10);
    let v_box = gtk::Box::new(gtk::Orientation::Horizontal, 10);
    let button_box = gtk::ButtonBox::new(gtk::Orientation::Horizontal);
    let label = gtk::Label::new(Some("Yeah a wonderful label too !"));
    let button = gtk::Button::new_with_label("Whattttt a button !");
    let button_about = gtk::Button::new_with_label("About?");
    let button_recent = gtk::Button::new_with_label("Choose a recent one !");
    let button_font = gtk::Button::new_with_label("Choose a font !");
    let app_button = gtk::Button::new_with_label("App ?");
    let file_button = gtk::Button::new_with_label("file ?");
    let font_button = gtk::FontButton::new();
    let toggle_button = gtk::ToggleButton::new_with_label("Toggle Me !");
    let check_button = gtk::CheckButton::new_with_label("Labeled check button");
    let color_button = gtk::ColorButton::new();
    let menu_button = with_gtk_3_10!(
        gtk::MenuButton::new()
    );
    let link_button = gtk::LinkButton::new("www.rust-lang.org");
    let volume_button = gtk::VolumeButton::new();
    let entry = gtk::Entry::new();
    let search_entry = with_gtk_3_10!(
        gtk::SearchEntry::new()
    );
    let separator = gtk::Separator::new(gtk::Orientation::Horizontal);
    let separator2 = gtk::Separator::new(gtk::Orientation::Horizontal);
    let switch = gtk::Switch::new();
    let switch2 = gtk::Switch::new();
    let scale = gtk::Scale::new_with_range(gtk::Orientation::Horizontal, 0., 100., 1.);
    let level_bar = with_gtk_3_10!(
        gtk::LevelBar::new_for_interval(0., 100.)
    );
    let spin_button = gtk::SpinButton::new_with_range(0., 100., 1.);
    let spinner = gtk::Spinner::new();
    let image = gtk::Image::new_from_file("./test/resources/gtk.jpg");
    let progress_bar = gtk::ProgressBar::new();
    let arrow = gtk::Arrow::new(gtk::ArrowType::Right, gtk::ShadowType::EtchedOut);
    let calendar = gtk::Calendar::new();
    let info_bar = gtk::InfoBar::new();
    let tmp_button = with_gtk_3_10!(
        gtk::Button::new_from_icon_name("edit-clear", gtk::IconSize::Button as i32)
    );

    println!("test");

    with_gtk_3_10! {{
        info_bar.set_show_close_button(true);
    }}

    /*info_bar.connect(signals::Response::new(|response_id| {
        info_bar.hide()
    }));*/ //TODO: Why does this not work?

    progress_bar.set_fraction(0.7);
    spinner.start();
    with_gtk_3_10! {{
        level_bar.set_value(37.);
    }}
    switch2.set_active(true);
    frame.set_border_width(10);
    _box.set_border_width(5);
    entry.set_placeholder_text(Some("An Entry with a placeholder !"));
    volume_button.set_orientation(gtk::Orientation::Horizontal);
    label.set_justify(gtk::Justification::Left);
    window.set_title("Yeah a beautiful window with gtk !");
    window.set_position(gtk::WindowPosition::Center);
    window.add(&frame);

    scale.set_digits(1);
    scale.connect_format_value(|scale, value| {
        let digits = scale.get_digits() as usize;
        format!("<{:.*}>", digits, value)
    });

    let entry_clone = entry.clone();
    button.connect_clicked(clone!(window => move |_| {
        let dialog = gtk::Dialog::new_with_buttons(Some("Hello!"), Some(&window), gtk::DIALOG_MODAL,
            &[("No", 0), ("Yes", 1), ("Yes!", 2)]);

        let ret = dialog.run();

        dialog.destroy();

        entry_clone.set_text(&format!("Clicked {}", ret));
    }));

    // use a plain function instead of a closure
    button_about.connect_clicked(about_clicked);

    button_font.connect_clicked(clone!(window => move |_| {
        let dialog = gtk::FontChooserDialog::new(Some("Font chooser test"), Some(&window));

        dialog.run();
        dialog.destroy();
    }));

    button_recent.connect_clicked(clone!(window => move |_| {
        let dialog = gtk::RecentChooserDialog::new(Some("Recent chooser test"), Some(&window));
        dialog.add_buttons(&[
            ("Ok", gtk::ResponseType::Ok as i32),
            ("Cancel", gtk::ResponseType::Cancel as i32)
        ]);

        dialog.run();
        dialog.destroy();
    }));

    file_button.connect_clicked(clone!(window => move |_| {
        //entry.set_text("Clicked!");
        let dialog = gtk::FileChooserDialog::new(Some("Choose a file"), Some(&window),
            gtk::FileChooserAction::Open);
        dialog.add_buttons(&[
            ("Open", gtk::ResponseType::Ok as i32),
            ("Cancel", gtk::ResponseType::Cancel as i32)
        ]);

        dialog.set_select_multiple(true);
        dialog.run();
        let files = dialog.get_filenames();
        dialog.destroy();

        println!("Files: {:?}", files);
    }));

    app_button.connect_clicked(clone!(window => move |_| {
        //entry.set_text("Clicked!");
        let dialog = gtk::AppChooserDialog::new_for_content_type(Some(&window), gtk::DIALOG_MODAL,
            "sh");

        dialog.run();
        dialog.destroy();
    }));

    let entry_clone = entry.clone();
    window.connect_key_press_event(move |_, key| {
        let keyval = key.as_ref().keyval;
        let keystate = key.as_ref().state;

        println!("key pressed: {} / {:?}", keyval, keystate);
        println!("text: {}", entry_clone.get_text().unwrap());

        if keystate.intersects(modifier_type::ControlMask) {
            println!("You pressed Ctrl!");
        }

        Inhibit(false)
    });

    window.connect_delete_event(|_, _| {
        gtk::main_quit();
        Inhibit(false)
    });

    frame.add(&_box);
    with_gtk_3_10! {{
        button_box.add(&tmp_button)
    }};
    button_box.add(&button);
    button_box.add(&button_about);
    button_box.add(&button_font);
    button_box.add(&button_recent);
    button_box.add(&file_button);
    button_box.add(&app_button);
    button_box.add(&font_button);
    button_box.add(&toggle_button);
    button_box.add(&color_button);
    button_box.add(&volume_button);
    v_box.add(&switch);
    with_gtk_3_10! {{
        v_box.add(&menu_button);
    }}
    v_box.add(&switch2);
    v_box.add(&check_button);
    v_box.add(&link_button);
    v_box.add(&spin_button);
    _box.add(&info_bar);
    _box.add(&v_box);
    _box.add(&scale);
    with_gtk_3_10! {{
        _box.add(&level_bar);
    }}
    _box.add(&button_box);
    _box.add(&progress_bar);
    _box.add(&separator);
    _box.add(&label);
    _box.add(&entry);
    _box.add(&separator2);
    with_gtk_3_10! {{
        _box.add(&search_entry);
    }}
    _box.add(&spinner);
    _box.add(&image);
    _box.add(&arrow);
    _box.add(&calendar);
    _box.set_orientation(gtk::Orientation::Vertical);
    // window.set_decorated(false);
    window.set_decorated(true);
    window.show_all();
    gtk::main();
}
<|endoftext|>


<commit_before>use std::{ffi::CStr,
          mem};

use libc;

use crate::{error::{Error,
                    Result},
            os::system::Uname};
use errno::errno;

pub fn uname() -> Result<Uname> { unsafe { uname_libc() } }

unsafe fn uname_libc() -> Result<Uname> {
    let mut utsname: libc::utsname = mem::uninitialized();
    let rv = libc::uname(&mut utsname);
    if rv < 0 {
        let errno = errno();
        let code = errno.0 as i32;
        return Err(Error::UnameFailed(format!("Error {} when calling uname: \
                                               {}",
                                              code, errno)));
    }
    Ok(Uname { sys_name:  CStr::from_ptr(utsname.sysname.as_ptr()).to_string_lossy()
                                                                  .into_owned(),
               node_name: CStr::from_ptr(utsname.nodename.as_ptr()).to_string_lossy()
                                                                   .into_owned(),
               release:   CStr::from_ptr(utsname.release.as_ptr()).to_string_lossy()
                                                                  .into_owned(),
               version:   CStr::from_ptr(utsname.version.as_ptr()).to_string_lossy()
                                                                  .into_owned(),
               machine:   CStr::from_ptr(utsname.machine.as_ptr()).to_string_lossy()
                                                                  .into_owned(), })
}
<commit_msg>Fix deprecation warnings with 1.39.0<commit_after>use crate::{error::{Error,
                    Result},
            os::system::Uname};
use errno::errno;
use libc;
use std::{ffi::CStr,
          mem};

pub fn uname() -> Result<Uname> { unsafe { uname_libc() } }

unsafe fn uname_libc() -> Result<Uname> {
    let mut utsname: libc::utsname = mem::MaybeUninit::uninit().assume_init();
    let rv = libc::uname(&mut utsname);
    if rv < 0 {
        let errno = errno();
        let code = errno.0 as i32;
        return Err(Error::UnameFailed(format!("Error {} when calling uname: \
                                               {}",
                                              code, errno)));
    }
    Ok(Uname { sys_name:  CStr::from_ptr(utsname.sysname.as_ptr()).to_string_lossy()
                                                                  .into_owned(),
               node_name: CStr::from_ptr(utsname.nodename.as_ptr()).to_string_lossy()
                                                                   .into_owned(),
               release:   CStr::from_ptr(utsname.release.as_ptr()).to_string_lossy()
                                                                  .into_owned(),
               version:   CStr::from_ptr(utsname.version.as_ptr()).to_string_lossy()
                                                                  .into_owned(),
               machine:   CStr::from_ptr(utsname.machine.as_ptr()).to_string_lossy()
                                                                  .into_owned(), })
}
<|endoftext|>


<commit_before>extern crate futures;
extern crate slog;
extern crate tokio;

use self::futures::sync::mpsc::{
    UnboundedReceiver,
    UnboundedSender,
};
use self::futures::Stream;
use self::tokio::timer::Interval;
use self::tokio::prelude::*;
use std::sync::{ RwLock, Arc };
use super::network_libp2p::message::{
    NetworkEvent,
    OutgoingMessage,
};
use super::db::DB;
use slog::Logger;

use std::time::{ Duration, Instant };

type NetworkSender = UnboundedSender<OutgoingMessage>;
type NetworkReceiver = UnboundedReceiver<NetworkEvent>;

type SyncSender = UnboundedSender<Vec<u8>>;
type SyncReceiver = UnboundedReceiver<Vec<u8>>;

pub fn start_sync(
    _db: Arc<RwLock<DB>>,
    network_tx: NetworkSender,
    network_rx: NetworkReceiver,
    _sync_tx: SyncSender,
    _sync_rx: SyncReceiver,
    log: Logger) {
    let rx_future = network_rx
        .for_each(move |event| {
            debug!(&log, "Sync receive";
                   "msg" => format!("{:?}", event));
            Ok(())
        })
        .map_err(|_| panic!("rx failed"));

    let poll_future = Interval::new(Instant::now(), Duration::from_secs(2))
        .for_each(move |_| {
            let msg = OutgoingMessage {
                peer: None,
                data: vec![42, 42, 42]
            };
            network_tx.unbounded_send(msg);
            Ok(())
        })
        .map_err(|_| panic!("send failed"));

    let sync_future = poll_future
        .select(rx_future).map_err(|(err, _)| err)
        .and_then(|((), n)| n);

    tokio::run(sync_future);
}
<commit_msg>Tidy "sync" module<commit_after>extern crate futures;
extern crate slog;
extern crate tokio;

use self::futures::sync::mpsc::{
    UnboundedReceiver,
    UnboundedSender,
};
use self::tokio::prelude::*;
use std::sync::{ RwLock, Arc };
use super::network_libp2p::message::{
    NetworkEvent,
    OutgoingMessage,
};
use super::db::DB;
use slog::Logger;

type NetworkSender = UnboundedSender<OutgoingMessage>;
type NetworkReceiver = UnboundedReceiver<NetworkEvent>;

type SyncSender = UnboundedSender<Vec<u8>>;
type SyncReceiver = UnboundedReceiver<Vec<u8>>;

/// Start a syncing tokio future.
///
/// This is effectively a stub function being
/// used to test network functionality.
///
/// Expect a full re-write.
pub fn start_sync(
    _db: Arc<RwLock<DB>>,
    _network_tx: NetworkSender,
    network_rx: NetworkReceiver,
    _sync_tx: SyncSender,
    _sync_rx: SyncReceiver,
    log: Logger) {
    let rx_future = network_rx
        .for_each(move |event| {
            debug!(&log, "Sync receive";
                   "msg" => format!("{:?}", event));
            Ok(())
        })
        .map_err(|_| panic!("rx failed"));

    /*
     * This is an unfinished stub function.
     */

    tokio::run(rx_future);
}
<|endoftext|>


<commit_before>use ncurses;

use theme::ColorPair;
use vec::Vec2;
use view::{View,IdView,SizeRequest};
use event::*;
use printer::Printer;

/// Displays an editable text.
pub struct EditView {
    content: String,
    cursor: usize,
    min_length: usize,
}

impl EditView {
    /// Creates a new, empty edit view.
    pub fn new() -> Self {
        EditView {
            content: String::new(),
            cursor: 0,
            min_length: 1,
        }
    }

    /// Replace the entire content of the view with the given one.
    pub fn set_content<'a>(&mut self, content: &'a str) {
        self.content = content.to_string();
    }

    /// Get the current text.
    pub fn get_content(&self) -> &str {
        &self.content
    }

    /// Sets the current content to the given value. Convenient chainable method.
    pub fn content<'a>(mut self, content: &'a str) -> Self {
        self.set_content(content);
        self
    }

    /// Sets the minimum length for this view.
    /// (This applies to the layout, not the content.)
    pub fn min_length(mut self, min_length: usize) -> Self {
        self.min_length = min_length;

        self
    }

    /// Wraps this view into an IdView with the given id.
    pub fn with_id(self, label: &str) -> IdView<Self> {
        IdView::new(label, self)
    }
}

fn remove_char(s: &mut String, cursor: usize) {
    let i = match s.char_indices().nth(cursor) {
        Some((i,_)) => i,
        None => return,
    };
    s.remove(i);
}

impl View for EditView {
    fn draw(&mut self, printer: &Printer) {
        // let style = if focused { color::HIGHLIGHT } else { color::HIGHLIGHT_INACTIVE };
        let len = self.content.chars().count();
        printer.with_color(ColorPair::Secondary, |printer| {
            printer.with_style(ncurses::A_REVERSE(), |printer| {
                printer.print((0,0), &self.content);
                printer.print_hline((len,0), printer.size.x-len, '_' as u64);
            });

            // Now print cursor
            if printer.focused {
                let c = if self.cursor == len {
                    '_'
                } else {
                    // Get the char from the string... Is it so hard?
                    self.content.chars().nth(self.cursor).expect(&format!("Found no char at cursor {} in {}", self.cursor, self.content))
                };
                printer.print_hline((self.cursor, 0), 1, c as u64);
            }
        });
    }

    fn get_min_size(&self, _: SizeRequest) -> Vec2 {
        Vec2::new(self.min_length, 1)
    }

    fn take_focus(&mut self) -> bool {
        true
    }

    fn on_event(&mut self, event: Event) -> EventResult {

        match event {
            Event::CharEvent(ch) => {
                // Find the byte index of the char at self.cursor

                match self.content.char_indices().nth(self.cursor) {
                    None => self.content.push(ch),
                    Some((i,_)) => self.content.insert(i, ch),
                }
                self.cursor += 1;
                return EventResult::Consumed(None);
            },
            Event::KeyEvent(key) => match key {
                Key::Home => self.cursor = 0,
                Key::End => self.cursor = self.content.chars().count(),
                Key::Left if self.cursor > 0 => self.cursor -= 1,
                Key::Right if self.cursor < self.content.chars().count() => self.cursor += 1,
                Key::Backspace if self.cursor > 0 => { self.cursor -= 1; remove_char(&mut self.content, self.cursor); },
                Key::Del if self.cursor < self.content.chars().count() => { remove_char(&mut self.content, self.cursor); },
                _ => return EventResult::Ignored,

            },
        }

        EventResult::Consumed(None)
    }
}
<commit_msg>Edit view now support content larger than display<commit_after>use ncurses;

use std::cmp::min;

use theme::ColorPair;
use vec::Vec2;
use view::{View,IdView,SizeRequest};
use event::*;
use printer::Printer;

/// Input box where the user can enter and edit text.
pub struct EditView {
    /// Current content
    content: String,
    /// Cursor position in the content
    cursor: usize,
    /// Minimum layout length asked to the parent
    min_length: usize,

    /// When the content is too long for the display, offset it
    offset: usize,
    /// Last display length, to know the possible offset range
    last_length: usize,
    // scrollable: bool,
    // TODO: add a max text length?
}

impl EditView {
    /// Creates a new, empty edit view.
    pub fn new() -> Self {
        EditView {
            content: String::new(),
            cursor: 0,
            offset: 0,
            min_length: 1,
            last_length: 0,
            // scrollable: false,
        }
    }

    /// Replace the entire content of the view with the given one.
    pub fn set_content<'a>(&mut self, content: &'a str) {
        self.offset = 0;
        self.content = content.to_string();
    }

    /// Get the current text.
    pub fn get_content(&self) -> &str {
        &self.content
    }

    /// Sets the current content to the given value. Convenient chainable method.
    pub fn content<'a>(mut self, content: &'a str) -> Self {
        self.set_content(content);
        self
    }

    /// Sets the minimum length for this view.
    /// (This applies to the layout, not the content.)
    pub fn min_length(mut self, min_length: usize) -> Self {
        self.min_length = min_length;

        self
    }

    /// Wraps this view into an IdView with the given id.
    pub fn with_id(self, label: &str) -> IdView<Self> {
        IdView::new(label, self)
    }
}

fn remove_char(s: &mut String, cursor: usize) {
    let i = match s.char_indices().nth(cursor) {
        Some((i,_)) => i,
        None => return,
    };
    s.remove(i);
}

impl View for EditView {
    fn draw(&mut self, printer: &Printer) {
        // let style = if focused { color::HIGHLIGHT } else { color::HIGHLIGHT_INACTIVE };
        let len = self.content.chars().count();
        printer.with_color(ColorPair::Secondary, |printer| {
            printer.with_style(ncurses::A_REVERSE(), |printer| {
                if len < self.last_length {
                    printer.print((0,0), &self.content);
                    printer.print_hline((len,0), printer.size.x-len, '_' as u64);
                } else {
                    let visible_end = min(self.content.len(), self.offset + self.last_length);

                    let content = &self.content[self.offset..visible_end];
                    printer.print((0,0), content);
                    if visible_end - self.offset < printer.size.x {
                        printer.print((printer.size.x-1,0), "_");
                    }
                }
            });

            // Now print cursor
            if printer.focused {
                let c = if self.cursor == len {
                    '_'
                } else {
                    // Get the char from the string... Is it so hard?
                    self.content.chars().nth(self.cursor).expect(&format!("Found no char at cursor {} in {}", self.cursor, self.content))
                };
                printer.print_hline((self.cursor-self.offset, 0), 1, c as u64);
            }
        });
    }

    fn layout(&mut self, size: Vec2) {
        self.last_length = size.x;
    }

    fn get_min_size(&self, _: SizeRequest) -> Vec2 {
        Vec2::new(self.min_length, 1)
    }

    fn take_focus(&mut self) -> bool {
        true
    }

    fn on_event(&mut self, event: Event) -> EventResult {

        match event {
            Event::CharEvent(ch) => {
                // Find the byte index of the char at self.cursor

                match self.content.char_indices().nth(self.cursor) {
                    None => self.content.push(ch),
                    Some((i,_)) => self.content.insert(i, ch),
                }
                // TODO: handle wide (CJK) chars
                self.cursor += 1;
            },
            Event::KeyEvent(key) => match key {
                Key::Home => self.cursor = 0,
                Key::End => self.cursor = self.content.chars().count(),
                Key::Left if self.cursor > 0 => self.cursor -= 1,
                Key::Right if self.cursor < self.content.chars().count() => self.cursor += 1,
                Key::Backspace if self.cursor > 0 => { self.cursor -= 1; remove_char(&mut self.content, self.cursor); },
                Key::Del if self.cursor < self.content.chars().count() => { remove_char(&mut self.content, self.cursor); },
                _ => return EventResult::Ignored,
            },
        }

        // Keep cursor in [offset, offset+last_length] by changing offset
        // So keep offset in [last_length-cursor,cursor]
        // Also call this on resize, but right now it is an event like any other
        if self.cursor >= self.offset + self.last_length {
            self.offset = self.cursor - self.last_length + 1;
        } else if self.cursor < self.offset {
            self.offset = self.cursor;
        }
        if self.offset + self.last_length > self.content.len() + 1{

            self.offset = if self.content.len() > self.last_length {
                self.content.len() - self.last_length + 1
            } else {
                0
            };
        }

        EventResult::Consumed(None)
    }
}
<|endoftext|>


<commit_before>

use visit::IntoNeighbors;
use visit::{VisitMap, Visitable};

/// Strictly monotonically increasing event time for a depth first search.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Default, Hash)]
pub struct Time(pub usize);

/// A depth first search (DFS) visitor event.
#[derive(Copy, Clone, Debug)]
pub enum DfsEvent<N> {
    Discover(N, Time),
    /// An edge of the tree formed by the traversal.
    TreeEdge(N, N),
    /// An edge to an already visited node.
    BackEdge(N, N),
    /// A cross or forward edge.
    ///
    /// For an edge *(u, v)*, if the discover time of *v* is greater than *u*,
    /// then it is a forward edge, else a cross edge.
    CrossForwardEdge(N, N),
    /// All edges from a node have been reported.
    Finish(N, Time),
}

/// Return if the expression is a break value, execute the provided statement
/// if it is a prune value.
macro_rules! try_control {
    ($e:expr, $p:stmt) => {
        match $e {
            x => if x.should_break() {
                return x;
            } else if x.should_prune() {
                $p;
            }
        }
    }
}

/// Control flow for `depth_first_search` callbacks.
#[derive(Copy, Clone, Debug)]
pub enum Control<B> {
    /// Continue the DFS traversal as normal.
    Continue,
    /// Prune the current node from the DFS traversal. No more edges from this
    /// node will be reported to the callback. A `DfsEvent::Finish` for this
    /// node will still be reported. This can be returned in response to any
    /// `DfsEvent`, except `Finish`, which will panic.
    Prune,
    /// Stop the DFS traversal and return the provided value.
    Break(B),
}

impl<B> Control<B> {
    pub fn breaking() -> Control<()> { Control::Break(()) }
    /// Get the value in `Control::Break(_)`, if present.
    pub fn break_value(self) -> Option<B> {
        match self {
            Control::Continue | Control::Prune => None,
            Control::Break(b) => Some(b),
        }
    }
}

/// Control flow for callbacks.
///
/// The empty return value `()` is equivalent to continue.
pub trait ControlFlow {
    fn continuing() -> Self;
    fn should_break(&self) -> bool;
    fn should_prune(&self) -> bool;
}

impl ControlFlow for () {
    fn continuing() { }
    #[inline]
    fn should_break(&self) -> bool { false }
    #[inline]
    fn should_prune(&self) -> bool { false }
}

impl<B> ControlFlow for Control<B> {
    fn continuing() -> Self { Control::Continue }
    fn should_break(&self) -> bool {
        if let Control::Break(_) = *self { true } else { false }
    }
    fn should_prune(&self) -> bool {
        match *self {
            Control::Prune => true,
            Control::Continue | Control::Break(_) => false,
        }
    }
}

impl<E> ControlFlow for Result<(), E> {
    fn continuing() -> Self { Ok(()) }
    fn should_break(&self) -> bool {
        self.is_err()
    }
    fn should_prune(&self) -> bool {
        false
    }
}

/// The default is `Continue`.
impl<B> Default for Control<B> {
    fn default() -> Self { Control::Continue }
}

/// A recursive depth first search.
///
/// Starting points are the nodes in the iterator `starts` (specify just one
/// start vertex *x* by using `Some(x)`).
///
/// The traversal emits discovery and finish events for each reachable vertex,
/// and edge classification of each reachable edge. `visitor` is called for each
/// event, see [`DfsEvent`][de] for possible values.
///
/// If the return value of the visitor is simply `()`, the visit runs until it
/// is finished. If the return value is a `Control<B>`, it can be used to
/// change the control flow of the search. `Control::Break` will stop the
/// the visit early, returning the contained value from the function.
/// `Control::Prune` will stop traversing any additional edges from the current
/// node and proceed immediately to the `Finish` event. Attempting to prune a
/// node from its `Finish` event will cause a panic.
///
/// [de]: enum.DfsEvent.html
///
/// # Example
///
/// Find a path from vertex 0 to 5, and exit the visit as soon as we reach
/// the goal vertex.
///
/// ```
/// use petgraph::prelude::*;
/// use petgraph::graph::node_index as n;
/// use petgraph::visit::depth_first_search;
/// use petgraph::visit::{DfsEvent, Control};
///
/// let gr: Graph<(), ()> = Graph::from_edges(&[
///     (0, 1), (0, 2), (0, 3),
///     (1, 3),
///     (2, 3), (2, 4),
///     (4, 0), (4, 5),
/// ]);
///
/// // record each predecessor, mapping node → node
/// let mut predecessor = vec![NodeIndex::end(); gr.node_count()];
/// let start = n(0);
/// let goal = n(5);
/// depth_first_search(&gr, Some(start), |event| {
///     if let DfsEvent::TreeEdge(u, v) = event {
///         predecessor[v.index()] = u;
///         if v == goal {
///             return Control::Break(v);
///         }
///     }
///     Control::Continue
/// });
///
/// let mut next = goal;
/// let mut path = vec![next];
/// while next != start {
///     let pred = predecessor[next.index()];
///     path.push(pred);
///     next = pred;
/// }
/// path.reverse();
/// assert_eq!(&path, &[n(0), n(2), n(4), n(5)]);
/// ```
pub fn depth_first_search<G, I, F, C>(graph: G, starts: I, mut visitor: F) -> C
    where G: IntoNeighbors + Visitable,
          I: IntoIterator<Item=G::NodeId>,
          F: FnMut(DfsEvent<G::NodeId>) -> C,
          C: ControlFlow,
{
    let time = &mut Time(0);
    let discovered = &mut graph.visit_map();
    let finished = &mut graph.visit_map();

    for start in starts {
        try_control!(dfs_visitor(graph, start, &mut visitor, discovered, finished, time),
                     unreachable!());
    }
    C::continuing()
}

fn dfs_visitor<G, F, C>(graph: G, u: G::NodeId, visitor: &mut F,
                     discovered: &mut G::Map, finished: &mut G::Map,
                     time: &mut Time) -> C
    where G: IntoNeighbors + Visitable,
          F: FnMut(DfsEvent<G::NodeId>) -> C,
          C: ControlFlow,
{
    if !discovered.visit(u) {
        return C::continuing();
    }

    'prune: loop {
        try_control!(visitor(DfsEvent::Discover(u, time_post_inc(time))), break 'prune);
        for v in graph.neighbors(u) {
            if !discovered.is_visited(&v) {
                try_control!(visitor(DfsEvent::TreeEdge(u, v)), continue);
                try_control!(dfs_visitor(graph, v, visitor, discovered, finished, time),
                             unreachable!());
            } else if !finished.is_visited(&v) {
                try_control!(visitor(DfsEvent::BackEdge(u, v)), continue);
            } else {
                try_control!(visitor(DfsEvent::CrossForwardEdge(u, v)), continue);
            }
        }

        break;
    }
    let first_finish = finished.visit(u);
    debug_assert!(first_finish);
    try_control!(visitor(DfsEvent::Finish(u, time_post_inc(time))),
                 panic!("Pruning on the `DfsEvent::Finish` is not supported!"));
    C::continuing()
}

fn time_post_inc(x: &mut Time) -> Time {
    let v = *x;
    x.0 += 1;
    v
}
<commit_msg>Implement ControlFlow for Result<C, E> C: ControlFlow instead of just Result<(), E>.<commit_after>

use visit::IntoNeighbors;
use visit::{VisitMap, Visitable};

/// Strictly monotonically increasing event time for a depth first search.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Default, Hash)]
pub struct Time(pub usize);

/// A depth first search (DFS) visitor event.
#[derive(Copy, Clone, Debug)]
pub enum DfsEvent<N> {
    Discover(N, Time),
    /// An edge of the tree formed by the traversal.
    TreeEdge(N, N),
    /// An edge to an already visited node.
    BackEdge(N, N),
    /// A cross or forward edge.
    ///
    /// For an edge *(u, v)*, if the discover time of *v* is greater than *u*,
    /// then it is a forward edge, else a cross edge.
    CrossForwardEdge(N, N),
    /// All edges from a node have been reported.
    Finish(N, Time),
}

/// Return if the expression is a break value, execute the provided statement
/// if it is a prune value.
macro_rules! try_control {
    ($e:expr, $p:stmt) => {
        match $e {
            x => if x.should_break() {
                return x;
            } else if x.should_prune() {
                $p;
            }
        }
    }
}

/// Control flow for `depth_first_search` callbacks.
#[derive(Copy, Clone, Debug)]
pub enum Control<B> {
    /// Continue the DFS traversal as normal.
    Continue,
    /// Prune the current node from the DFS traversal. No more edges from this
    /// node will be reported to the callback. A `DfsEvent::Finish` for this
    /// node will still be reported. This can be returned in response to any
    /// `DfsEvent`, except `Finish`, which will panic.
    Prune,
    /// Stop the DFS traversal and return the provided value.
    Break(B),
}

impl<B> Control<B> {
    pub fn breaking() -> Control<()> { Control::Break(()) }
    /// Get the value in `Control::Break(_)`, if present.
    pub fn break_value(self) -> Option<B> {
        match self {
            Control::Continue | Control::Prune => None,
            Control::Break(b) => Some(b),
        }
    }
}

/// Control flow for callbacks.
///
/// The empty return value `()` is equivalent to continue.
pub trait ControlFlow {
    fn continuing() -> Self;
    fn should_break(&self) -> bool;
    fn should_prune(&self) -> bool;
}

impl ControlFlow for () {
    fn continuing() { }
    #[inline]
    fn should_break(&self) -> bool { false }
    #[inline]
    fn should_prune(&self) -> bool { false }
}

impl<B> ControlFlow for Control<B> {
    fn continuing() -> Self { Control::Continue }
    fn should_break(&self) -> bool {
        if let Control::Break(_) = *self { true } else { false }
    }
    fn should_prune(&self) -> bool {
        match *self {
            Control::Prune => true,
            Control::Continue | Control::Break(_) => false,
        }
    }
}

impl<C: ControlFlow, E> ControlFlow for Result<C, E> {
    fn continuing() -> Self { Ok(C::continuing()) }
    fn should_break(&self) -> bool {
        self.is_err()
    }
    fn should_prune(&self) -> bool {
        if let Ok(ref c) = *self { c.should_prune() } else { false }
    }
}

/// The default is `Continue`.
impl<B> Default for Control<B> {
    fn default() -> Self { Control::Continue }
}

/// A recursive depth first search.
///
/// Starting points are the nodes in the iterator `starts` (specify just one
/// start vertex *x* by using `Some(x)`).
///
/// The traversal emits discovery and finish events for each reachable vertex,
/// and edge classification of each reachable edge. `visitor` is called for each
/// event, see [`DfsEvent`][de] for possible values.
///
/// If the return value of the visitor is simply `()`, the visit runs until it
/// is finished. If the return value is a `Control<B>`, it can be used to
/// change the control flow of the search. `Control::Break` will stop the
/// the visit early, returning the contained value from the function.
/// `Control::Prune` will stop traversing any additional edges from the current
/// node and proceed immediately to the `Finish` event. Attempting to prune a
/// node from its `Finish` event will cause a panic.
///
/// [de]: enum.DfsEvent.html
///
/// # Example
///
/// Find a path from vertex 0 to 5, and exit the visit as soon as we reach
/// the goal vertex.
///
/// ```
/// use petgraph::prelude::*;
/// use petgraph::graph::node_index as n;
/// use petgraph::visit::depth_first_search;
/// use petgraph::visit::{DfsEvent, Control};
///
/// let gr: Graph<(), ()> = Graph::from_edges(&[
///     (0, 1), (0, 2), (0, 3),
///     (1, 3),
///     (2, 3), (2, 4),
///     (4, 0), (4, 5),
/// ]);
///
/// // record each predecessor, mapping node → node
/// let mut predecessor = vec![NodeIndex::end(); gr.node_count()];
/// let start = n(0);
/// let goal = n(5);
/// depth_first_search(&gr, Some(start), |event| {
///     if let DfsEvent::TreeEdge(u, v) = event {
///         predecessor[v.index()] = u;
///         if v == goal {
///             return Control::Break(v);
///         }
///     }
///     Control::Continue
/// });
///
/// let mut next = goal;
/// let mut path = vec![next];
/// while next != start {
///     let pred = predecessor[next.index()];
///     path.push(pred);
///     next = pred;
/// }
/// path.reverse();
/// assert_eq!(&path, &[n(0), n(2), n(4), n(5)]);
/// ```
pub fn depth_first_search<G, I, F, C>(graph: G, starts: I, mut visitor: F) -> C
    where G: IntoNeighbors + Visitable,
          I: IntoIterator<Item=G::NodeId>,
          F: FnMut(DfsEvent<G::NodeId>) -> C,
          C: ControlFlow,
{
    let time = &mut Time(0);
    let discovered = &mut graph.visit_map();
    let finished = &mut graph.visit_map();

    for start in starts {
        try_control!(dfs_visitor(graph, start, &mut visitor, discovered, finished, time),
                     unreachable!());
    }
    C::continuing()
}

fn dfs_visitor<G, F, C>(graph: G, u: G::NodeId, visitor: &mut F,
                     discovered: &mut G::Map, finished: &mut G::Map,
                     time: &mut Time) -> C
    where G: IntoNeighbors + Visitable,
          F: FnMut(DfsEvent<G::NodeId>) -> C,
          C: ControlFlow,
{
    if !discovered.visit(u) {
        return C::continuing();
    }

    'prune: loop {
        try_control!(visitor(DfsEvent::Discover(u, time_post_inc(time))), break 'prune);
        for v in graph.neighbors(u) {
            if !discovered.is_visited(&v) {
                try_control!(visitor(DfsEvent::TreeEdge(u, v)), continue);
                try_control!(dfs_visitor(graph, v, visitor, discovered, finished, time),
                             unreachable!());
            } else if !finished.is_visited(&v) {
                try_control!(visitor(DfsEvent::BackEdge(u, v)), continue);
            } else {
                try_control!(visitor(DfsEvent::CrossForwardEdge(u, v)), continue);
            }
        }

        break;
    }
    let first_finish = finished.visit(u);
    debug_assert!(first_finish);
    try_control!(visitor(DfsEvent::Finish(u, time_post_inc(time))),
                 panic!("Pruning on the `DfsEvent::Finish` is not supported!"));
    C::continuing()
}

fn time_post_inc(x: &mut Time) -> Time {
    let v = *x;
    x.0 += 1;
    v
}
<|endoftext|>