<commit_before>// This file is part of the uutils coreutils package.
//
// (c) Jian Zeng <anonymousknight96@gmail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// spell-checker:ignore (vars) Passwd cstr fnam gecos ngroups egid

//! Get password/group file entry
//!
//! # Examples:
//!
//! ```
//! use uucore::entries::{self, Locate};
//!
//! let root_group = if cfg!(any(target_os = "linux", target_os = "android")) {
//!     "root"
//! } else {
//!     "wheel"
//! };
//!
//! assert_eq!("root", entries::uid2usr(0).unwrap());
//! assert_eq!(0, entries::usr2uid("root").unwrap());
//! assert!(entries::gid2grp(0).is_ok());
//! assert!(entries::grp2gid(root_group).is_ok());
//!
//! assert!(entries::Passwd::locate(0).is_ok());
//! assert!(entries::Passwd::locate("0").is_ok());
//! assert!(entries::Passwd::locate("root").is_ok());
//!
//! assert!(entries::Group::locate(0).is_ok());
//! assert!(entries::Group::locate("0").is_ok());
//! assert!(entries::Group::locate(root_group).is_ok());
//! ```

#[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
use libc::time_t;
use libc::{c_char, c_int, gid_t, uid_t};
use libc::{getgrgid, getgrnam, getgroups, getpwnam, getpwuid, group, passwd};

use std::borrow::Cow;
use std::ffi::{CStr, CString};
use std::io::Error as IOError;
use std::io::ErrorKind;
use std::io::Result as IOResult;
use std::ptr;

extern "C" {
    fn getgrouplist(
        name: *const c_char,
        gid: gid_t,
        groups: *mut gid_t,
        ngroups: *mut c_int,
    ) -> c_int;
}

pub fn get_groups() -> IOResult<Vec<gid_t>> {
    let ngroups = unsafe { getgroups(0, ptr::null_mut()) };
    if ngroups == -1 {
        return Err(IOError::last_os_error());
    }
    let mut groups = Vec::with_capacity(ngroups as usize);
    let ngroups = unsafe { getgroups(ngroups, groups.as_mut_ptr()) };
    if ngroups == -1 {
        Err(IOError::last_os_error())
    } else {
        unsafe {
            groups.set_len(ngroups as usize);
        }
        Ok(groups)
    }
}

/// The list of group IDs returned from GNU's `groups` and GNU's `id --groups`
/// starts with the effective group ID (egid).
/// This is a wrapper for `get_groups()` to mimic this behavior.
///
/// If `arg_id` is `None` (default), `get_groups_gnu` moves the effective
/// group id (egid) to the first entry in the returned Vector.
/// If `arg_id` is `Some(x)`, `get_groups_gnu` moves the id with value `x`
/// to the first entry in the returned Vector. This might be necessary
/// for `id --groups --real` if `gid` and `egid` are not equal.
///
/// From: https://www.man7.org/linux/man-pages/man3/getgroups.3p.html
/// As implied by the definition of supplementary groups, the
/// effective group ID may appear in the array returned by
/// getgroups() or it may be returned only by getegid().  Duplication
/// may exist, but the application needs to call getegid() to be sure
/// of getting all of the information. Various implementation
/// variations and administrative sequences cause the set of groups
/// appearing in the result of getgroups() to vary in order and as to
/// whether the effective group ID is included, even when the set of
/// groups is the same (in the mathematical sense of ``set''). (The
/// history of a process and its parents could affect the details of
/// the result.)
#[cfg(all(unix, feature = "process"))]
pub fn get_groups_gnu(arg_id: Option<u32>) -> IOResult<Vec<gid_t>> {
    let groups = get_groups()?;
    let egid = arg_id.unwrap_or_else(crate::features::process::getegid);
    Ok(sort_groups(groups, egid))
}

fn sort_groups(mut groups: Vec<gid_t>, egid: gid_t) -> Vec<gid_t> {
    if let Some(index) = groups.iter().position(|&x| x == egid) {
        groups[..=index].rotate_right(1);
    } else {
        groups.insert(0, egid);
    }
    groups
}

#[derive(Copy, Clone)]
pub struct Passwd {
    inner: passwd,
}

macro_rules! cstr2cow {
    ($v:expr) => {
        unsafe { CStr::from_ptr($v).to_string_lossy() }
    };
}

impl Passwd {
    /// AKA passwd.pw_name
    pub fn name(&self) -> Cow<str> {
        cstr2cow!(self.inner.pw_name)
    }

    /// AKA passwd.pw_uid
    pub fn uid(&self) -> uid_t {
        self.inner.pw_uid
    }

    /// AKA passwd.pw_gid
    pub fn gid(&self) -> gid_t {
        self.inner.pw_gid
    }

    /// AKA passwd.pw_gecos
    pub fn user_info(&self) -> Cow<str> {
        cstr2cow!(self.inner.pw_gecos)
    }

    /// AKA passwd.pw_shell
    pub fn user_shell(&self) -> Cow<str> {
        cstr2cow!(self.inner.pw_shell)
    }

    /// AKA passwd.pw_dir
    pub fn user_dir(&self) -> Cow<str> {
        cstr2cow!(self.inner.pw_dir)
    }

    /// AKA passwd.pw_passwd
    pub fn user_passwd(&self) -> Cow<str> {
        cstr2cow!(self.inner.pw_passwd)
    }

    /// AKA passwd.pw_class
    #[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
    pub fn user_access_class(&self) -> Cow<str> {
        cstr2cow!(self.inner.pw_class)
    }

    /// AKA passwd.pw_change
    #[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
    pub fn passwd_change_time(&self) -> time_t {
        self.inner.pw_change
    }

    /// AKA passwd.pw_expire
    #[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
    pub fn expiration(&self) -> time_t {
        self.inner.pw_expire
    }

    pub fn as_inner(&self) -> &passwd {
        &self.inner
    }

    pub fn into_inner(self) -> passwd {
        self.inner
    }

    pub fn belongs_to(&self) -> Vec<gid_t> {
        let mut ngroups: c_int = 8;
        let mut groups = Vec::with_capacity(ngroups as usize);
        let gid = self.inner.pw_gid;
        let name = self.inner.pw_name;
        unsafe {
            if getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups) == -1 {
                groups.resize(ngroups as usize, 0);
                getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups);
            }
            groups.set_len(ngroups as usize);
        }
        groups.truncate(ngroups as usize);
        groups
    }
}

pub struct Group {
    inner: group,
}

impl Group {
    /// AKA group.gr_name
    pub fn name(&self) -> Cow<str> {
        cstr2cow!(self.inner.gr_name)
    }

    /// AKA group.gr_gid
    pub fn gid(&self) -> gid_t {
        self.inner.gr_gid
    }

    pub fn as_inner(&self) -> &group {
        &self.inner
    }

    pub fn into_inner(self) -> group {
        self.inner
    }
}

/// Fetch desired entry.
pub trait Locate<K> {
    fn locate(key: K) -> IOResult<Self>
    where
        Self: ::std::marker::Sized;
}

macro_rules! f {
    ($fnam:ident, $fid:ident, $t:ident, $st:ident) => {
        impl Locate<$t> for $st {
            fn locate(k: $t) -> IOResult<Self> {
                unsafe {
                    let data = $fid(k);
                    if !data.is_null() {
                        Ok($st {
                            inner: ptr::read(data as *const _),
                        })
                    } else {
                        Err(IOError::new(
                            ErrorKind::NotFound,
                            format!("No such id: {}", k),
                        ))
                    }
                }
            }
        }

        impl<'a> Locate<&'a str> for $st {
            fn locate(k: &'a str) -> IOResult<Self> {
                if let Ok(id) = k.parse::<$t>() {
                    let data = unsafe { $fid(id) };
                    if !data.is_null() {
                        Ok($st {
                            inner: unsafe { ptr::read(data as *const _) },
                        })
                    } else {
                        Err(IOError::new(
                            ErrorKind::NotFound,
                            format!("No such id: {}", id),
                        ))
                    }
                } else {
                    unsafe {
                        let data = $fnam(CString::new(k).unwrap().as_ptr());
                        if !data.is_null() {
                            Ok($st {
                                inner: ptr::read(data as *const _),
                            })
                        } else {
                            Err(IOError::new(
                                ErrorKind::NotFound,
                                format!("Not found: {}", k),
                            ))
                        }
                    }
                }
            }
        }
    };
}

f!(getpwnam, getpwuid, uid_t, Passwd);
f!(getgrnam, getgrgid, gid_t, Group);

#[inline]
pub fn uid2usr(id: uid_t) -> IOResult<String> {
    Passwd::locate(id).map(|p| p.name().into_owned())
}

#[inline]
pub fn gid2grp(id: gid_t) -> IOResult<String> {
    Group::locate(id).map(|p| p.name().into_owned())
}

#[inline]
pub fn usr2uid(name: &str) -> IOResult<uid_t> {
    Passwd::locate(name).map(|p| p.uid())
}

#[inline]
pub fn grp2gid(name: &str) -> IOResult<gid_t> {
    Group::locate(name).map(|p| p.gid())
}

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

    #[test]
    fn test_sort_groups() {
        assert_eq!(sort_groups(vec![1, 2, 3], 4), vec![4, 1, 2, 3]);
        assert_eq!(sort_groups(vec![1, 2, 3], 3), vec![3, 1, 2]);
        assert_eq!(sort_groups(vec![1, 2, 3], 2), vec![2, 1, 3]);
        assert_eq!(sort_groups(vec![1, 2, 3], 1), vec![1, 2, 3]);
        assert_eq!(sort_groups(vec![1, 2, 3], 0), vec![0, 1, 2, 3]);
    }

    #[test]
    fn test_entries_get_groups_gnu() {
        if let Ok(mut groups) = get_groups() {
            if let Some(last) = groups.pop() {
                groups.insert(0, last);
                assert_eq!(get_groups_gnu(Some(last)).unwrap(), groups);
            }
        }
    }
}
<commit_msg>uucore: remove unused warning of sort_groups<commit_after>// This file is part of the uutils coreutils package.
//
// (c) Jian Zeng <anonymousknight96@gmail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// spell-checker:ignore (vars) Passwd cstr fnam gecos ngroups egid

//! Get password/group file entry
//!
//! # Examples:
//!
//! ```
//! use uucore::entries::{self, Locate};
//!
//! let root_group = if cfg!(any(target_os = "linux", target_os = "android")) {
//!     "root"
//! } else {
//!     "wheel"
//! };
//!
//! assert_eq!("root", entries::uid2usr(0).unwrap());
//! assert_eq!(0, entries::usr2uid("root").unwrap());
//! assert!(entries::gid2grp(0).is_ok());
//! assert!(entries::grp2gid(root_group).is_ok());
//!
//! assert!(entries::Passwd::locate(0).is_ok());
//! assert!(entries::Passwd::locate("0").is_ok());
//! assert!(entries::Passwd::locate("root").is_ok());
//!
//! assert!(entries::Group::locate(0).is_ok());
//! assert!(entries::Group::locate("0").is_ok());
//! assert!(entries::Group::locate(root_group).is_ok());
//! ```

#[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
use libc::time_t;
use libc::{c_char, c_int, gid_t, uid_t};
use libc::{getgrgid, getgrnam, getgroups, getpwnam, getpwuid, group, passwd};

use std::borrow::Cow;
use std::ffi::{CStr, CString};
use std::io::Error as IOError;
use std::io::ErrorKind;
use std::io::Result as IOResult;
use std::ptr;

extern "C" {
    fn getgrouplist(
        name: *const c_char,
        gid: gid_t,
        groups: *mut gid_t,
        ngroups: *mut c_int,
    ) -> c_int;
}

pub fn get_groups() -> IOResult<Vec<gid_t>> {
    let ngroups = unsafe { getgroups(0, ptr::null_mut()) };
    if ngroups == -1 {
        return Err(IOError::last_os_error());
    }
    let mut groups = Vec::with_capacity(ngroups as usize);
    let ngroups = unsafe { getgroups(ngroups, groups.as_mut_ptr()) };
    if ngroups == -1 {
        Err(IOError::last_os_error())
    } else {
        unsafe {
            groups.set_len(ngroups as usize);
        }
        Ok(groups)
    }
}

/// The list of group IDs returned from GNU's `groups` and GNU's `id --groups`
/// starts with the effective group ID (egid).
/// This is a wrapper for `get_groups()` to mimic this behavior.
///
/// If `arg_id` is `None` (default), `get_groups_gnu` moves the effective
/// group id (egid) to the first entry in the returned Vector.
/// If `arg_id` is `Some(x)`, `get_groups_gnu` moves the id with value `x`
/// to the first entry in the returned Vector. This might be necessary
/// for `id --groups --real` if `gid` and `egid` are not equal.
///
/// From: https://www.man7.org/linux/man-pages/man3/getgroups.3p.html
/// As implied by the definition of supplementary groups, the
/// effective group ID may appear in the array returned by
/// getgroups() or it may be returned only by getegid().  Duplication
/// may exist, but the application needs to call getegid() to be sure
/// of getting all of the information. Various implementation
/// variations and administrative sequences cause the set of groups
/// appearing in the result of getgroups() to vary in order and as to
/// whether the effective group ID is included, even when the set of
/// groups is the same (in the mathematical sense of ``set''). (The
/// history of a process and its parents could affect the details of
/// the result.)
#[cfg(all(unix, feature = "process"))]
pub fn get_groups_gnu(arg_id: Option<u32>) -> IOResult<Vec<gid_t>> {
    let groups = get_groups()?;
    let egid = arg_id.unwrap_or_else(crate::features::process::getegid);
    Ok(sort_groups(groups, egid))
}

#[cfg(all(unix, feature = "process"))]
fn sort_groups(mut groups: Vec<gid_t>, egid: gid_t) -> Vec<gid_t> {
    if let Some(index) = groups.iter().position(|&x| x == egid) {
        groups[..=index].rotate_right(1);
    } else {
        groups.insert(0, egid);
    }
    groups
}

#[derive(Copy, Clone)]
pub struct Passwd {
    inner: passwd,
}

macro_rules! cstr2cow {
    ($v:expr) => {
        unsafe { CStr::from_ptr($v).to_string_lossy() }
    };
}

impl Passwd {
    /// AKA passwd.pw_name
    pub fn name(&self) -> Cow<str> {
        cstr2cow!(self.inner.pw_name)
    }

    /// AKA passwd.pw_uid
    pub fn uid(&self) -> uid_t {
        self.inner.pw_uid
    }

    /// AKA passwd.pw_gid
    pub fn gid(&self) -> gid_t {
        self.inner.pw_gid
    }

    /// AKA passwd.pw_gecos
    pub fn user_info(&self) -> Cow<str> {
        cstr2cow!(self.inner.pw_gecos)
    }

    /// AKA passwd.pw_shell
    pub fn user_shell(&self) -> Cow<str> {
        cstr2cow!(self.inner.pw_shell)
    }

    /// AKA passwd.pw_dir
    pub fn user_dir(&self) -> Cow<str> {
        cstr2cow!(self.inner.pw_dir)
    }

    /// AKA passwd.pw_passwd
    pub fn user_passwd(&self) -> Cow<str> {
        cstr2cow!(self.inner.pw_passwd)
    }

    /// AKA passwd.pw_class
    #[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
    pub fn user_access_class(&self) -> Cow<str> {
        cstr2cow!(self.inner.pw_class)
    }

    /// AKA passwd.pw_change
    #[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
    pub fn passwd_change_time(&self) -> time_t {
        self.inner.pw_change
    }

    /// AKA passwd.pw_expire
    #[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
    pub fn expiration(&self) -> time_t {
        self.inner.pw_expire
    }

    pub fn as_inner(&self) -> &passwd {
        &self.inner
    }

    pub fn into_inner(self) -> passwd {
        self.inner
    }

    pub fn belongs_to(&self) -> Vec<gid_t> {
        let mut ngroups: c_int = 8;
        let mut groups = Vec::with_capacity(ngroups as usize);
        let gid = self.inner.pw_gid;
        let name = self.inner.pw_name;
        unsafe {
            if getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups) == -1 {
                groups.resize(ngroups as usize, 0);
                getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups);
            }
            groups.set_len(ngroups as usize);
        }
        groups.truncate(ngroups as usize);
        groups
    }
}

pub struct Group {
    inner: group,
}

impl Group {
    /// AKA group.gr_name
    pub fn name(&self) -> Cow<str> {
        cstr2cow!(self.inner.gr_name)
    }

    /// AKA group.gr_gid
    pub fn gid(&self) -> gid_t {
        self.inner.gr_gid
    }

    pub fn as_inner(&self) -> &group {
        &self.inner
    }

    pub fn into_inner(self) -> group {
        self.inner
    }
}

/// Fetch desired entry.
pub trait Locate<K> {
    fn locate(key: K) -> IOResult<Self>
    where
        Self: ::std::marker::Sized;
}

macro_rules! f {
    ($fnam:ident, $fid:ident, $t:ident, $st:ident) => {
        impl Locate<$t> for $st {
            fn locate(k: $t) -> IOResult<Self> {
                unsafe {
                    let data = $fid(k);
                    if !data.is_null() {
                        Ok($st {
                            inner: ptr::read(data as *const _),
                        })
                    } else {
                        Err(IOError::new(
                            ErrorKind::NotFound,
                            format!("No such id: {}", k),
                        ))
                    }
                }
            }
        }

        impl<'a> Locate<&'a str> for $st {
            fn locate(k: &'a str) -> IOResult<Self> {
                if let Ok(id) = k.parse::<$t>() {
                    let data = unsafe { $fid(id) };
                    if !data.is_null() {
                        Ok($st {
                            inner: unsafe { ptr::read(data as *const _) },
                        })
                    } else {
                        Err(IOError::new(
                            ErrorKind::NotFound,
                            format!("No such id: {}", id),
                        ))
                    }
                } else {
                    unsafe {
                        let data = $fnam(CString::new(k).unwrap().as_ptr());
                        if !data.is_null() {
                            Ok($st {
                                inner: ptr::read(data as *const _),
                            })
                        } else {
                            Err(IOError::new(
                                ErrorKind::NotFound,
                                format!("Not found: {}", k),
                            ))
                        }
                    }
                }
            }
        }
    };
}

f!(getpwnam, getpwuid, uid_t, Passwd);
f!(getgrnam, getgrgid, gid_t, Group);

#[inline]
pub fn uid2usr(id: uid_t) -> IOResult<String> {
    Passwd::locate(id).map(|p| p.name().into_owned())
}

#[inline]
pub fn gid2grp(id: gid_t) -> IOResult<String> {
    Group::locate(id).map(|p| p.name().into_owned())
}

#[inline]
pub fn usr2uid(name: &str) -> IOResult<uid_t> {
    Passwd::locate(name).map(|p| p.uid())
}

#[inline]
pub fn grp2gid(name: &str) -> IOResult<gid_t> {
    Group::locate(name).map(|p| p.gid())
}

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

    #[test]
    fn test_sort_groups() {
        assert_eq!(sort_groups(vec![1, 2, 3], 4), vec![4, 1, 2, 3]);
        assert_eq!(sort_groups(vec![1, 2, 3], 3), vec![3, 1, 2]);
        assert_eq!(sort_groups(vec![1, 2, 3], 2), vec![2, 1, 3]);
        assert_eq!(sort_groups(vec![1, 2, 3], 1), vec![1, 2, 3]);
        assert_eq!(sort_groups(vec![1, 2, 3], 0), vec![0, 1, 2, 3]);
    }

    #[test]
    fn test_entries_get_groups_gnu() {
        if let Ok(mut groups) = get_groups() {
            if let Some(last) = groups.pop() {
                groups.insert(0, last);
                assert_eq!(get_groups_gnu(Some(last)).unwrap(), groups);
            }
        }
    }
}
<|endoftext|>


<commit_before>// pp-exact
type thing = {x: int, y: int,};

fn main() {
    let sth = {x: 0, y: 1,};
    let sth2 = {y: 9 with sth};
    assert sth.x + sth2.y == 9;
}
<commit_msg>Try to fix pretty-test breakage.<commit_after>// pp-exact
type thing = {x: int, y: int,};

fn main() {
    let sth = {x: 0, y: 1,};
    let sth2 = {y: 9 .. sth};
    assert sth.x + sth2.y == 9;
}
<|endoftext|>


<commit_before>extern crate actix_web;
use actix_web::{server, App, HttpRequest};

fn index(_req: HttpRequest) -> &'static str {
    "Hello world!"
}

fn main() {
    server::new(|| App::new().resource("/", |r| r.f(index)))
        .bind("127.0.0.1:8000")
        .unwrap()
        .run();
}
<commit_msg>Complete the example for actix-web<commit_after>extern crate actix_web;
#[macro_use]
extern crate rust_embed;

use actix_web::{App, HttpRequest, HttpResponse, server};
use actix_web::http::Method;

#[derive(RustEmbed)]
#[folder = "examples/public/"]
struct Asset;

fn handle_embedded_file(path: &str) -> HttpResponse {
  match Asset::get(path) {
    Some(content) => HttpResponse::Ok().body(content),
    None => HttpResponse::NotFound().body("404 Not Found"),
  }
}

fn index(_req: HttpRequest) -> HttpResponse {
  handle_embedded_file("index.html")
}

fn dist(req: HttpRequest) -> HttpResponse {
  let path = &req.path()["/dist/".len()..];
  handle_embedded_file(path)
}

fn main() {
  server::new(|| {
    App::new().route("/", Method::GET, index).route(
      "/dist{_:.*}",
      Method::GET,
      dist,
    )
  }).bind("127.0.0.1:8000")
    .unwrap()
    .run();
}
<|endoftext|>


<commit_before>extern crate imap;
extern crate openssl;

use openssl::ssl::{SslContext, SslMethod};
use imap::client::Client;
use imap::mailbox::Mailbox;

fn main() {
	let mut imap_socket = match Client::secure_connect(("imap.gmail.com", 993), SslContext::new(SslMethod::Sslv23).unwrap()) {
		Ok(s) => s,
		Err(e) => panic!("{}", e)
	};

	if let Err(e) = imap_socket.login("username", "password") {
		println!("Error: {}", e)
	};

	match imap_socket.capability() {
		Ok(capabilities) => {
			for capability in capabilities.iter() {
				println!("{}", capability);
			}
		},
		Err(_) => println!("Error retreiving capabilities")
	};

	match imap_socket.select("INBOX") {
		Ok(Mailbox{flags, exists, recent, unseen, permanent_flags, uid_next, uid_validity}) => {
			println!("flags: {}, exists: {}, recent: {}, unseen: {:?}, permanent_flags: {:?}, uid_next: {:?}, uid_validity: {:?}", flags, exists, recent, unseen, permanent_flags, uid_next, uid_validity);
		},
		Err(_) => println!("Error selecting INBOX")
	};

	match imap_socket.fetch("2", "body[text]") {
		Ok(lines) => {
			for line in lines.iter() {
				print!("{}", line);
			}
		},
		Err(_) => println!("Error Fetching email 2")
	};

	if let Err(e) = imap_socket.logout() {
		println!("Error: {}", e)
	};
}
<commit_msg>Making the basic example more readable<commit_after>extern crate imap;
extern crate openssl;

use openssl::ssl::{SslContext, SslMethod};
use imap::client::Client;
use imap::mailbox::Mailbox;

fn main() {
	let mut imap_socket = Client::secure_connect(("imap.gmail.com", 993), SslContext::new(SslMethod::Sslv23).unwrap()).unwrap();

	imap_socket.login("username", "password").unwrap();

	match imap_socket.capability() {
		Ok(capabilities) => {
			for capability in capabilities.iter() {
				println!("{}", capability);
			}
		},
		Err(_) => println!("Error retreiving capabilities")
	};

	match imap_socket.select("INBOX") {
		Ok(Mailbox{flags, exists, recent, unseen, permanent_flags, uid_next, uid_validity}) => {
			println!("flags: {}, exists: {}, recent: {}, unseen: {:?}, permanent_flags: {:?}, uid_next: {:?}, uid_validity: {:?}", flags, exists, recent, unseen, permanent_flags, uid_next, uid_validity);
		},
		Err(_) => println!("Error selecting INBOX")
	};

	match imap_socket.fetch("2", "body[text]") {
		Ok(lines) => {
			for line in lines.iter() {
				print!("{}", line);
			}
		},
		Err(_) => println!("Error Fetching email 2")
	};

	imap_socket.logout().unwrap();
}
<|endoftext|>


<commit_before>/*
 * libgit2 "fetch" example - shows how to fetch remote data
 *
 * Written by the libgit2 contributors
 *
 * To the extent possible under law, the author(s) have dedicated all copyright
 * and related and neighboring rights to this software to the public domain
 * worldwide. This software is distributed without any warranty.
 *
 * You should have received a copy of the CC0 Public Domain Dedication along
 * with this software. If not, see
 * <http://creativecommons.org/publicdomain/zero/1.0/>.
 */

#![deny(warnings)]

extern crate git2;
extern crate docopt;
extern crate rustc_serialize;

use docopt::Docopt;
use git2::{Repository, RemoteCallbacks, Direction, AutotagOption, FetchOptions};
use std::io::{self, Write};
use std::str;

#[derive(RustcDecodable)]
struct Args {
    arg_remote: Option<String>,
}

fn run(args: &Args) -> Result<(), git2::Error> {
    let repo = try!(Repository::open("."));
    let remote = args.arg_remote.as_ref().map(|s| &s[..]).unwrap_or("origin");

    // Figure out whether it's a named remote or a URL
    println!("Fetcing {} for repo", remote);
    let mut cb = RemoteCallbacks::new();
    let mut remote = try!(repo.find_remote(remote).or_else(|_| {
        repo.remote_anonymous(remote)
    }));
    cb.sideband_progress(|data| {
        print!("remote: {}", str::from_utf8(data).unwrap());
        io::stdout().flush().unwrap();
        true
    });

    // This callback gets called for each remote-tracking branch that gets
    // updated. The message we output depends on whether it's a new one or an
    // update.
    cb.update_tips(|refname, a, b| {
        if a.is_zero() {
            println!("[new]     {:20} {}", b, refname);
        } else {
            println!("[updated] {:10}..{:10} {}", a, b, refname);
        }
        true
    });

    // Here we show processed and total objects in the pack and the amount of
    // received data. Most frontends will probably want to show a percentage and
    // the download rate.
    cb.transfer_progress(|stats| {
        if stats.received_objects() == stats.total_objects() {
            print!("Resolving deltas {}/{}\r", stats.indexed_deltas(),
                   stats.total_deltas());
        } else if stats.total_objects() > 0 {
            print!("Received {}/{} objects ({}) in {} bytes\r",
                   stats.received_objects(),
                   stats.total_objects(),
                   stats.indexed_objects(),
                   stats.received_bytes());
        }
        io::stdout().flush().unwrap();
        true
    });

    // Connect to the remote end specifying that we want to fetch information
    // from it.
    try!(remote.connect(Direction::Fetch));

    // Download the packfile and index it. This function updates the amount of
    // received data and the indexer stats which lets you inform the user about
    // progress.
    let mut fo = FetchOptions::new();
    fo.remote_callbacks(cb);
    try!(remote.download(&[], Some(&mut fo)));

    {
        // If there are local objects (we got a thin pack), then tell the user
        // how many objects we saved from having to cross the network.
        let stats = remote.stats();
        if stats.local_objects() > 0 {
            println!("\rReceived {}/{} objects in {} bytes (used {} local \
                      objects)", stats.indexed_objects(),
                     stats.total_objects(), stats.received_bytes(),
                     stats.local_objects());
        } else {
            println!("\rReceived {}/{} objects in {} bytes",
                     stats.indexed_objects(), stats.total_objects(),
                     stats.received_bytes());
        }
    }

    // Disconnect the underlying connection to prevent from idling.
    remote.disconnect();

    // Update the references in the remote's namespace to point to the right
    // commits. This may be needed even if there was no packfile to download,
    // which can happen e.g. when the branches have been changed but all the
    // needed objects are available locally.
    try!(remote.update_tips(None, true,
                            AutotagOption::Unspecified, None));

    Ok(())
}

fn main() {
    const USAGE: &'static str = "
usage: fetch [options] [<remote>]

Options:
    -h, --help          show this message
";

    let args = Docopt::new(USAGE).and_then(|d| d.decode())
                                 .unwrap_or_else(|e| e.exit());
    match run(&args) {
        Ok(()) => {}
        Err(e) => println!("error: {}", e),
    }
}
<commit_msg>tiny little typo fix<commit_after>/*
 * libgit2 "fetch" example - shows how to fetch remote data
 *
 * Written by the libgit2 contributors
 *
 * To the extent possible under law, the author(s) have dedicated all copyright
 * and related and neighboring rights to this software to the public domain
 * worldwide. This software is distributed without any warranty.
 *
 * You should have received a copy of the CC0 Public Domain Dedication along
 * with this software. If not, see
 * <http://creativecommons.org/publicdomain/zero/1.0/>.
 */

#![deny(warnings)]

extern crate git2;
extern crate docopt;
extern crate rustc_serialize;

use docopt::Docopt;
use git2::{Repository, RemoteCallbacks, Direction, AutotagOption, FetchOptions};
use std::io::{self, Write};
use std::str;

#[derive(RustcDecodable)]
struct Args {
    arg_remote: Option<String>,
}

fn run(args: &Args) -> Result<(), git2::Error> {
    let repo = try!(Repository::open("."));
    let remote = args.arg_remote.as_ref().map(|s| &s[..]).unwrap_or("origin");

    // Figure out whether it's a named remote or a URL
    println!("Fetching {} for repo", remote);
    let mut cb = RemoteCallbacks::new();
    let mut remote = try!(repo.find_remote(remote).or_else(|_| {
        repo.remote_anonymous(remote)
    }));
    cb.sideband_progress(|data| {
        print!("remote: {}", str::from_utf8(data).unwrap());
        io::stdout().flush().unwrap();
        true
    });

    // This callback gets called for each remote-tracking branch that gets
    // updated. The message we output depends on whether it's a new one or an
    // update.
    cb.update_tips(|refname, a, b| {
        if a.is_zero() {
            println!("[new]     {:20} {}", b, refname);
        } else {
            println!("[updated] {:10}..{:10} {}", a, b, refname);
        }
        true
    });

    // Here we show processed and total objects in the pack and the amount of
    // received data. Most frontends will probably want to show a percentage and
    // the download rate.
    cb.transfer_progress(|stats| {
        if stats.received_objects() == stats.total_objects() {
            print!("Resolving deltas {}/{}\r", stats.indexed_deltas(),
                   stats.total_deltas());
        } else if stats.total_objects() > 0 {
            print!("Received {}/{} objects ({}) in {} bytes\r",
                   stats.received_objects(),
                   stats.total_objects(),
                   stats.indexed_objects(),
                   stats.received_bytes());
        }
        io::stdout().flush().unwrap();
        true
    });

    // Connect to the remote end specifying that we want to fetch information
    // from it.
    try!(remote.connect(Direction::Fetch));

    // Download the packfile and index it. This function updates the amount of
    // received data and the indexer stats which lets you inform the user about
    // progress.
    let mut fo = FetchOptions::new();
    fo.remote_callbacks(cb);
    try!(remote.download(&[], Some(&mut fo)));

    {
        // If there are local objects (we got a thin pack), then tell the user
        // how many objects we saved from having to cross the network.
        let stats = remote.stats();
        if stats.local_objects() > 0 {
            println!("\rReceived {}/{} objects in {} bytes (used {} local \
                      objects)", stats.indexed_objects(),
                     stats.total_objects(), stats.received_bytes(),
                     stats.local_objects());
        } else {
            println!("\rReceived {}/{} objects in {} bytes",
                     stats.indexed_objects(), stats.total_objects(),
                     stats.received_bytes());
        }
    }

    // Disconnect the underlying connection to prevent from idling.
    remote.disconnect();

    // Update the references in the remote's namespace to point to the right
    // commits. This may be needed even if there was no packfile to download,
    // which can happen e.g. when the branches have been changed but all the
    // needed objects are available locally.
    try!(remote.update_tips(None, true,
                            AutotagOption::Unspecified, None));

    Ok(())
}

fn main() {
    const USAGE: &'static str = "
usage: fetch [options] [<remote>]

Options:
    -h, --help          show this message
";

    let args = Docopt::new(USAGE).and_then(|d| d.decode())
                                 .unwrap_or_else(|e| e.exit());
    match run(&args) {
        Ok(()) => {}
        Err(e) => println!("error: {}", e),
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]

#[plugin]
extern crate ply_plugins;
extern crate ply;

use ply::{PlyModel,TestObj};
/*
// http://paulbourke.net/dataformats/ply/
static PLY: &'static str = r#"ply
format ascii 1.0
comment author: Greg Turk
comment object: another cube
element vertex 8
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
element face 7
property list uchar int vertex_index
element edge 5
property int vertex1
property int vertex2
property uchar red
property uchar green
property uchar blue
end_header
0 0 0 255 0 0
0 0 1 255 0 0
0 1 1 255 0 0
0 1 0 255 0 0
1 0 0 0 0 255
1 0 1 0 0 255
1 1 1 0 0 255
1 1 0 0 0 255
3 0 1 2
3 0 2 3
4 7 6 5 4
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0
0 1 255 255 255
1 2 255 255 255
2 3 255 255 255
3 0 255 255 255
2 0 0 0 0
"#; */

static PLY: &'static str = r#"ply
format ascii 1.0
comment author: Greg Turk
comment object: another cube
element vertex 8
property float x
property float y
property float z
element face 7
property float x
property float y
property float z
end_header
0 0 0
0 0 1
0 1 1
0 1 0
1 0 0
1 0 1
1 1 1
1 1 0
0 0 1
0 1 1
0 1 0
1 0 0
1 0 1
1 1 1
1 1 0
"#;

#[derive(Debug)]
#[ply_data]
struct S {
	vertex: Vec<ply::Position>,
	face: Vec<ply::Position>,
}

fn main() {
	let res = ply::parser::parse(PLY);
	match res {
		Ok(ply) => {
			println!("Format: {:?}, {:?}", ply.format, ply.version);
			for e in ply.elements.iter() {
				println!("Element \"{}\": {} instances.", e.name, e.count);
				for p in e.props.iter() {
					println!("    Property \"{}\": \t{:?}.", p.name, p.type_);
				}
				println!("  Data: {:?}", e.data);
			}
		//	println!("\nData:\n");
		//	println!("{}", ply.data);

			//let obj: TestObj;
			//println!("Result of object check: {:?}", Object::check(None::<TestObj>, &ply));

		//	let res: Result<TestObj,&'static str> = PlyModel::new(&ply);
			let res2: Result<S, &'static str> = PlyModel::new(&ply);
			println!("Result: {:?}", res2);
		//	match res {
		//		Ok(data) => println!("res: {:?}", data),
		//		Err(e) => println!("Error while parsing: {}", e),
		//	}

		}, Err(e) => println!("E: {}", e),
	}
	println!("Hello!");
}
<commit_msg>Finally working<commit_after>#![feature(plugin)]

#[plugin]
extern crate ply_plugins;
extern crate ply;

use ply::{PlyModel,TestObj};
/*
// http://paulbourke.net/dataformats/ply/
static PLY: &'static str = r#"ply
format ascii 1.0
comment author: Greg Turk
comment object: another cube
element vertex 8
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
element face 7
property list uchar int vertex_index
element edge 5
property int vertex1
property int vertex2
property uchar red
property uchar green
property uchar blue
end_header
0 0 0 255 0 0
0 0 1 255 0 0
0 1 1 255 0 0
0 1 0 255 0 0
1 0 0 0 0 255
1 0 1 0 0 255
1 1 1 0 0 255
1 1 0 0 0 255
3 0 1 2
3 0 2 3
4 7 6 5 4
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0
0 1 255 255 255
1 2 255 255 255
2 3 255 255 255
3 0 255 255 255
2 0 0 0 0
"#; */

static PLY: &'static str = r#"ply
format ascii 1.0
comment author: Greg Turk
comment object: another cube
element vertex 8
property float x
property float y
property float z
element face 7
property float x
property float y
property float z
end_header
0 0 0
0 0 1
0 1 1
0 1 0
1 0 0
1 0 1
1 1 1
1 1 0
0 0 1
0 1 1
0 1 0
1 0 0
1 0 1
1 1 1
1 1 0
"#;

#[derive(Debug)]
#[ply_data]
struct S {
	vertex: Vec<ply::Position>,
	face: Vec<ply::Position>,
	prd: bool,
}

fn main() {
	let res = ply::parser::parse(PLY);
	match res {
		Ok(ply) => {
			println!("Format: {:?}, {:?}", ply.format, ply.version);
			for e in ply.elements.iter() {
				println!("Element \"{}\": {} instances.", e.name, e.count);
				for p in e.props.iter() {
					println!("    Property \"{}\": \t{:?}.", p.name, p.type_);
				}
				println!("  Data: {:?}", e.data);
			}
		//	println!("\nData:\n");
		//	println!("{}", ply.data);

			//let obj: TestObj;
			//println!("Result of object check: {:?}", Object::check(None::<TestObj>, &ply));

		//	let res: Result<TestObj,&'static str> = PlyModel::new(&ply);
			let res2: Result<S, &'static str> = PlyModel::new(&ply);
			println!("Result: {:?}", res2);
		//	match res {
		//		Ok(data) => println!("res: {:?}", data),
		//		Err(e) => println!("Error while parsing: {}", e),
		//	}

		}, Err(e) => println!("E: {}", e),
	}
	println!("Hello!");
}
<|endoftext|>


<commit_before>use super::*;
use serde::de::{Deserialize, Deserializer};
use types::Fork;

#[derive(Debug, Clone, Deserialize)]
pub struct SszStatic {
    pub type_name: String,
    pub serialized: String,
    pub root: String,
    #[serde(skip)]
    pub raw_yaml: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct Value<T> {
    value: T,
}

impl TestDecode for SszStatic {
    fn test_decode(yaml: &String) -> Result<Self, Error> {
        let mut ssz_static: SszStatic = serde_yaml::from_str(&yaml.as_str()).unwrap();

        ssz_static.raw_yaml = yaml.clone();

        Ok(ssz_static)
    }
}

impl SszStatic {
    fn value<T: serde::de::DeserializeOwned>(&self) -> Result<T, Error> {
        serde_yaml::from_str(&self.raw_yaml.as_str()).map_err(|e| {
            Error::FailedToParseTest(format!("Unable to parse {} YAML: {:?}", self.type_name, e))
        })
    }
}

impl Test for TestDocCases<SszStatic> {
    fn test(&self) -> Vec<TestCaseResult> {
        self.test_cases
            .iter()
            .enumerate()
            .map(|(i, tc)| {
                let result = match tc.type_name.as_ref() {
                    "Fork" => ssz_static_test::<Fork>(tc),
                    _ => Err(Error::FailedToParseTest(format!(
                        "Unknown type: {}",
                        tc.type_name
                    ))),
                };

                TestCaseResult::new(i, tc, result)
            })
            .collect()
    }
}

fn ssz_static_test<T>(tc: &SszStatic) -> Result<(), Error>
where
    T: Decode + TestDecode + Debug + PartialEq<T> + serde::de::DeserializeOwned,
{
    let ssz = hex::decode(&tc.serialized[2..])
        .map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;

    let expected = tc.value::<T>()?;

    Ok(())

    /*
    let decoded = T::from_ssz_bytes(&ssz);

    compare_result(decoded, Some(expected))
    */
}
<commit_msg>Fix ssz_static deserialization<commit_after>use super::*;
use serde::de::{Deserialize, Deserializer};
use types::Fork;

#[derive(Debug, Clone, Deserialize)]
pub struct SszStatic {
    pub type_name: String,
    pub serialized: String,
    pub root: String,
    #[serde(skip)]
    pub raw_yaml: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct Value<T> {
    value: T,
}

impl TestDecode for SszStatic {
    fn test_decode(yaml: &String) -> Result<Self, Error> {
        let mut ssz_static: SszStatic = serde_yaml::from_str(&yaml.as_str()).unwrap();

        ssz_static.raw_yaml = yaml.clone();

        Ok(ssz_static)
    }
}

impl SszStatic {
    fn value<T: serde::de::DeserializeOwned>(&self) -> Result<T, Error> {
        let wrapper: Value<T> = serde_yaml::from_str(&self.raw_yaml.as_str()).map_err(|e| {
            Error::FailedToParseTest(format!("Unable to parse {} YAML: {:?}", self.type_name, e))
        })?;

        Ok(wrapper.value)
    }
}

impl Test for TestDocCases<SszStatic> {
    fn test(&self) -> Vec<TestCaseResult> {
        self.test_cases
            .iter()
            .enumerate()
            .map(|(i, tc)| {
                let result = match tc.type_name.as_ref() {
                    "Fork" => ssz_static_test::<Fork>(tc),
                    _ => Err(Error::FailedToParseTest(format!(
                        "Unknown type: {}",
                        tc.type_name
                    ))),
                };

                TestCaseResult::new(i, tc, result)
            })
            .collect()
    }
}

fn ssz_static_test<T>(tc: &SszStatic) -> Result<(), Error>
where
    T: Decode + TestDecode + Debug + PartialEq<T> + serde::de::DeserializeOwned,
{
    let ssz = hex::decode(&tc.serialized[2..])
        .map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;

    let expected = tc.value::<T>()?;

    Ok(())

    /*
    let decoded = T::from_ssz_bytes(&ssz);

    compare_result(decoded, Some(expected))
    */
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::cell::RefCell;
use std::net::SocketAddr;
use std::collections::HashMap;
use rand::random;
use mio::net::TcpStream;

use network::{AppId,Backend,ConnectionError};

pub struct BackendMap {
  pub instances:    HashMap<AppId, BackendList>,
  pub max_failures: usize,
}

impl BackendMap {
  pub fn new() -> BackendMap {
    BackendMap {
      instances:    HashMap::new(),
      max_failures: 3,
    }
  }

  pub fn add_instance(&mut self, app_id: &str, instance_address: &SocketAddr) {
    self.instances.entry(app_id.to_string()).or_insert(BackendList::new()).add_instance(instance_address);
  }

  pub fn remove_instance(&mut self, app_id: &str, instance_address: &SocketAddr) {
    if let Some(instances) = self.instances.get_mut(app_id) {
      instances.remove_instance(instance_address);
    } else {
      error!("Instance was already removed");
    }
  }

  pub fn close_backend_connection(&mut self, app_id: &str, addr: &SocketAddr) {
    if let Some(app_instances) = self.instances.get_mut(app_id) {
      if let Some(ref mut backend) = app_instances.find_instance(addr) {
        (*backend.borrow_mut()).dec_connections();
      }
    }
  }

  pub fn backend_from_app_id(&mut self, app_id: &str) -> Result<(Rc<RefCell<Backend>>,TcpStream),ConnectionError> {
    if let Some(ref mut app_instances) = self.instances.get_mut(app_id) {
      if app_instances.instances.len() == 0 {
        return Err(ConnectionError::NoBackendAvailable);
      }

      for _ in 0..self.max_failures {
        //FIXME: it's probably pretty wasteful to refilter every time here
        let mut instances:Vec<&mut Rc<RefCell<Backend>>> = app_instances.instances.iter_mut().filter(|backend| (*backend.borrow()).can_open(max_failures_per_backend)).collect();
        if instances.is_empty() {
          error!("no more available backends for app {}", app_id);
          return Err(ConnectionError::NoBackendAvailable);
        }
        let rnd = random::<usize>();
        let idx = rnd % instances.len();

        let conn = instances.get_mut(idx).ok_or(ConnectionError::NoBackendAvailable).and_then(|ref mut b| {
          let ref mut backend = *b.borrow_mut();
          info!("Connecting {} -> {:?}", app_id, (backend.address, backend.active_connections, backend.failures));
          let conn = backend.try_connect();
          if backend.failures >= max_failures_per_backend {
            error!("backend {:?} connections failed {} times, disabling it", (backend.address, backend.active_connections), backend.failures);
          }

          conn.map(|c| (b.clone(), c))
        });

        if conn.is_ok() {
          return conn;
        }
      }
      Err(ConnectionError::NoBackendAvailable)
    } else {
      Err(ConnectionError::NoBackendAvailable)
    }
  }

  pub fn backend_from_sticky_session(&mut self, app_id: &str, sticky_session: u32) -> Result<(Rc<RefCell<Backend>>,TcpStream),ConnectionError> {
    let sticky_conn: Option<Result<(Rc<RefCell<Backend>>,TcpStream),ConnectionError>> = self.instances
      .get_mut(app_id)
      .and_then(|app_instances| app_instances.find_sticky(sticky_session))
      .map(|b| {
        let ref mut backend = *b.borrow_mut();
        let conn = backend.try_connect();
        info!("Connecting {} -> {:?} using session {}", app_id, (backend.address, backend.active_connections, backend.failures), sticky_session);
        if backend.failures >= max_failures_per_backend {
          error!("backend {:?} connections failed {} times, disabling it", (backend.address, backend.active_connections), backend.failures);
        }

        conn.map(|c| (b.clone(), c))
    });

    if let Some(res) = sticky_conn {
      return res;
    } else {
      debug!("Couldn't find a backend corresponding to sticky_session {} for app {}", sticky_session, app_id);
      return self.backend_from_app_id(app_id);
    }
  }
}

const max_failures_per_backend: usize = 10;

pub struct BackendList {
  pub instances: Vec<Rc<RefCell<Backend>>>,
  pub next_id:   u32,
}

impl BackendList {
  pub fn new() -> BackendList {
    BackendList {
      instances: Vec::new(),
      next_id:   0,
    }
  }

  pub fn add_instance(&mut self, instance_address: &SocketAddr) {
    if self.instances.iter().find(|b| &(*b.borrow()).address == instance_address).is_none() {
      let backend = Rc::new(RefCell::new(Backend::new(*instance_address, self.next_id)));
      self.instances.push(backend);
      self.next_id += 1;
    }
  }

  pub fn remove_instance(&mut self, instance_address: &SocketAddr) {
    self.instances.retain(|backend| &(*backend.borrow()).address != instance_address);
  }

  pub fn find_instance(&mut self, instance_address: &SocketAddr) -> Option<&mut Rc<RefCell<Backend>>> {
    self.instances.iter_mut().find(|backend| &(*backend.borrow()).address == instance_address)
  }

  pub fn find_sticky(&mut self, sticky_session: u32) -> Option<&mut Rc<RefCell<Backend>>> {
    self.instances.iter_mut().find(|b| {
      let backend = &*b.borrow();
      backend.id == sticky_session && backend.can_open(max_failures_per_backend)
    })
  }

  pub fn available_instances(&mut self) -> Vec<&mut Rc<RefCell<Backend>>> {
    self.instances.iter_mut()
      .filter(|backend| (*backend.borrow()).can_open(max_failures_per_backend))
      .collect()
  }
}
<commit_msg>use the available_instances() method<commit_after>use std::rc::Rc;
use std::cell::RefCell;
use std::net::SocketAddr;
use std::collections::HashMap;
use rand::random;
use mio::net::TcpStream;

use network::{AppId,Backend,ConnectionError};

pub struct BackendMap {
  pub instances:    HashMap<AppId, BackendList>,
  pub max_failures: usize,
}

impl BackendMap {
  pub fn new() -> BackendMap {
    BackendMap {
      instances:    HashMap::new(),
      max_failures: 3,
    }
  }

  pub fn add_instance(&mut self, app_id: &str, instance_address: &SocketAddr) {
    self.instances.entry(app_id.to_string()).or_insert(BackendList::new()).add_instance(instance_address);
  }

  pub fn remove_instance(&mut self, app_id: &str, instance_address: &SocketAddr) {
    if let Some(instances) = self.instances.get_mut(app_id) {
      instances.remove_instance(instance_address);
    } else {
      error!("Instance was already removed");
    }
  }

  pub fn close_backend_connection(&mut self, app_id: &str, addr: &SocketAddr) {
    if let Some(app_instances) = self.instances.get_mut(app_id) {
      if let Some(ref mut backend) = app_instances.find_instance(addr) {
        (*backend.borrow_mut()).dec_connections();
      }
    }
  }

  pub fn backend_from_app_id(&mut self, app_id: &str) -> Result<(Rc<RefCell<Backend>>,TcpStream),ConnectionError> {
    if let Some(ref mut app_instances) = self.instances.get_mut(app_id) {
      if app_instances.instances.len() == 0 {
        return Err(ConnectionError::NoBackendAvailable);
      }

      for _ in 0..self.max_failures {
        //FIXME: it's probably pretty wasteful to refilter every time here
        let mut instances:Vec<&mut Rc<RefCell<Backend>>> = app_instances.available_instances();
        if instances.is_empty() {
          error!("no more available backends for app {}", app_id);
          return Err(ConnectionError::NoBackendAvailable);
        }
        let rnd = random::<usize>();
        let idx = rnd % instances.len();

        let conn = instances.get_mut(idx).ok_or(ConnectionError::NoBackendAvailable).and_then(|ref mut b| {
          let ref mut backend = *b.borrow_mut();
          info!("Connecting {} -> {:?}", app_id, (backend.address, backend.active_connections, backend.failures));
          let conn = backend.try_connect();
          if backend.failures >= max_failures_per_backend {
            error!("backend {:?} connections failed {} times, disabling it", (backend.address, backend.active_connections), backend.failures);
          }

          conn.map(|c| (b.clone(), c))
        });

        if conn.is_ok() {
          return conn;
        }
      }
      Err(ConnectionError::NoBackendAvailable)
    } else {
      Err(ConnectionError::NoBackendAvailable)
    }
  }

  pub fn backend_from_sticky_session(&mut self, app_id: &str, sticky_session: u32) -> Result<(Rc<RefCell<Backend>>,TcpStream),ConnectionError> {
    let sticky_conn: Option<Result<(Rc<RefCell<Backend>>,TcpStream),ConnectionError>> = self.instances
      .get_mut(app_id)
      .and_then(|app_instances| app_instances.find_sticky(sticky_session))
      .map(|b| {
        let ref mut backend = *b.borrow_mut();
        let conn = backend.try_connect();
        info!("Connecting {} -> {:?} using session {}", app_id, (backend.address, backend.active_connections, backend.failures), sticky_session);
        if backend.failures >= max_failures_per_backend {
          error!("backend {:?} connections failed {} times, disabling it", (backend.address, backend.active_connections), backend.failures);
        }

        conn.map(|c| (b.clone(), c))
    });

    if let Some(res) = sticky_conn {
      return res;
    } else {
      debug!("Couldn't find a backend corresponding to sticky_session {} for app {}", sticky_session, app_id);
      return self.backend_from_app_id(app_id);
    }
  }
}

const max_failures_per_backend: usize = 10;

pub struct BackendList {
  pub instances: Vec<Rc<RefCell<Backend>>>,
  pub next_id:   u32,
}

impl BackendList {
  pub fn new() -> BackendList {
    BackendList {
      instances: Vec::new(),
      next_id:   0,
    }
  }

  pub fn add_instance(&mut self, instance_address: &SocketAddr) {
    if self.instances.iter().find(|b| &(*b.borrow()).address == instance_address).is_none() {
      let backend = Rc::new(RefCell::new(Backend::new(*instance_address, self.next_id)));
      self.instances.push(backend);
      self.next_id += 1;
    }
  }

  pub fn remove_instance(&mut self, instance_address: &SocketAddr) {
    self.instances.retain(|backend| &(*backend.borrow()).address != instance_address);
  }

  pub fn find_instance(&mut self, instance_address: &SocketAddr) -> Option<&mut Rc<RefCell<Backend>>> {
    self.instances.iter_mut().find(|backend| &(*backend.borrow()).address == instance_address)
  }

  pub fn find_sticky(&mut self, sticky_session: u32) -> Option<&mut Rc<RefCell<Backend>>> {
    self.instances.iter_mut().find(|b| {
      let backend = &*b.borrow();
      backend.id == sticky_session && backend.can_open(max_failures_per_backend)
    })
  }

  pub fn available_instances(&mut self) -> Vec<&mut Rc<RefCell<Backend>>> {
    self.instances.iter_mut()
      .filter(|backend| (*backend.borrow()).can_open(max_failures_per_backend))
      .collect()
  }
}
<|endoftext|>


<commit_before>use std::path::PathBuf;
use std::path::Path;
use std::borrow::Borrow;
use std::ops::Deref;

use semver::Version;
use std::fmt::{Display, Debug, Formatter};
use std::fmt::Error as FmtError;
use std::result::Result as RResult;

use error::StoreErrorKind as SEK;
use store::Result;
use store::Store;

/// The Index into the Store
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId {
    store_location: PathBuf,
    id: PathBuf,
}

impl StoreId {

    pub fn storified(self, store: &Store) -> StoreId {
        if self.starts_with(store.path()) {
            debug!("Not storifying {:?}, because it is already.", self);
            self
        } else {
            debug!("Create new store id out of: {:?} and {:?}", store.path(), self.id);

            let new_id = StoreId { store_location: store.path().clone(), self.id };

            debug!("Created: '{:?}'", new_id);
            new_id
        }
    }

}

impl Into<PathBuf> for StoreId {

    fn into(self) -> PathBuf {
        self.0
    }

}

impl Display for StoreId {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        match self.0.to_str() {
            Some(s) => write!(fmt, "{}", s),
            None    => write!(fmt, "{}", self.0.to_string_lossy()),
        }
    }

}

impl Deref for StoreId {
    type Target = PathBuf;

    fn deref(&self) -> &PathBuf {
        &self.0
    }

}

impl From<PathBuf> for StoreId {

    fn from(pb: PathBuf) -> StoreId {
        StoreId(pb)
    }

}

impl From<String> for StoreId {

    fn from(string: String) -> StoreId {
        StoreId(string.into())
    }

}

impl AsRef<Path> for StoreId {

    fn as_ref(&self) -> &Path {
        self.0.as_ref()
    }

}

impl Borrow<Path> for StoreId {

    fn borrow(&self) -> &Path {
        self.0.borrow()
    }

}

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
pub trait IntoStoreId {
    fn into_storeid(self) -> StoreId;
}

impl IntoStoreId for PathBuf {
    fn into_storeid(self) -> StoreId {
        StoreId(self)
    }
}

impl IntoStoreId for StoreId {
    fn into_storeid(self) -> StoreId {
        self
    }
}

pub fn build_entry_path(store: &Store, path_elem: &str) -> Result<PathBuf> {
    debug!("Checking path element for version");
    if path_elem.split('~').last().map_or(false, |v| Version::parse(v).is_err()) {
        debug!("Version cannot be parsed from {:?}", path_elem);
        debug!("Path does not contain version!");
        return Err(SEK::StorePathLacksVersion.into());
    }
    debug!("Version checking succeeded");

    debug!("Building path from {:?}", path_elem);
    let mut path = store.path().clone();

    if path_elem.starts_with('/') {
        path.push(&path_elem[1..]);
    } else {
        path.push(path_elem);
    }

    Ok(path)
}

#[macro_export]
macro_rules! module_entry_path_mod {
    ($name:expr, $version:expr) => (
        #[deny(missing_docs,
                missing_copy_implementations,
                trivial_casts, trivial_numeric_casts,
                unsafe_code,
                unstable_features,
                unused_import_braces, unused_qualifications,
                unused_imports)]
        /// A helper module to create valid module entry paths
        pub mod module_path {
            use semver::Version;
            use std::convert::AsRef;
            use std::path::Path;
            use std::path::PathBuf;

            use $crate::storeid::StoreId;

            /// A Struct giving you the ability to choose store entries assigned
            /// to it.
            ///
            /// It is created through a call to `new`.
            pub struct ModuleEntryPath(PathBuf);

            impl ModuleEntryPath {
                /// Path has to be a valid UTF-8 string or this will panic!
                pub fn new<P: AsRef<Path>>(pa: P) -> ModuleEntryPath {
                    let mut path = PathBuf::new();
                    path.push(format!("{}", $name));
                    path.push(pa.as_ref().clone());
                    let version = Version::parse($version).unwrap();
                    let name = pa.as_ref().file_name().unwrap()
                        .to_str().unwrap();
                    path.set_file_name(format!("{}~{}",
                                               name,
                                               version));
                    ModuleEntryPath(path)
                }
            }

            impl $crate::storeid::IntoStoreId for ModuleEntryPath {
                fn into_storeid(self) -> $crate::storeid::StoreId {
                    StoreId::from(self.0)
                }
            }
        }
    )
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = StoreId>>,
}

impl Debug for StoreIdIterator {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "StoreIdIterator")
    }

}

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
        StoreIdIterator {
            iter: iter,
        }
    }

}

impl Iterator for StoreIdIterator {
    type Item = StoreId;

    fn next(&mut self) -> Option<StoreId> {
        self.iter.next()
    }

}

#[cfg(test)]
mod test {

    use storeid::IntoStoreId;

    module_entry_path_mod!("test", "0.2.0-alpha+leet1337");

    #[test]
    fn correct_path() {
        let p = module_path::ModuleEntryPath::new("test");

        assert_eq!(p.into_storeid().to_str().unwrap(), "test/test~0.2.0-alpha+leet1337");
    }

}
<commit_msg>Rewrite Into<PathBuf> for StoreId<commit_after>use std::path::PathBuf;
use std::path::Path;
use std::borrow::Borrow;
use std::ops::Deref;

use semver::Version;
use std::fmt::{Display, Debug, Formatter};
use std::fmt::Error as FmtError;
use std::result::Result as RResult;

use error::StoreErrorKind as SEK;
use store::Result;
use store::Store;

/// The Index into the Store
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId {
    store_location: PathBuf,
    id: PathBuf,
}

impl StoreId {

    pub fn storified(self, store: &Store) -> StoreId {
        if self.starts_with(store.path()) {
            debug!("Not storifying {:?}, because it is already.", self);
            self
        } else {
            debug!("Create new store id out of: {:?} and {:?}", store.path(), self.id);

            let new_id = StoreId { store_location: store.path().clone(), self.id };

            debug!("Created: '{:?}'", new_id);
            new_id
        }
    }

}

impl Into<PathBuf> for StoreId {

    fn into(self) -> PathBuf {
        let mut base = self.store_location;
        base.push(self.id);
        base
    }

}

impl Display for StoreId {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        match self.0.to_str() {
            Some(s) => write!(fmt, "{}", s),
            None    => write!(fmt, "{}", self.0.to_string_lossy()),
        }
    }

}

impl Deref for StoreId {
    type Target = PathBuf;

    fn deref(&self) -> &PathBuf {
        &self.0
    }

}

impl From<PathBuf> for StoreId {

    fn from(pb: PathBuf) -> StoreId {
        StoreId(pb)
    }

}

impl From<String> for StoreId {

    fn from(string: String) -> StoreId {
        StoreId(string.into())
    }

}

impl AsRef<Path> for StoreId {

    fn as_ref(&self) -> &Path {
        self.0.as_ref()
    }

}

impl Borrow<Path> for StoreId {

    fn borrow(&self) -> &Path {
        self.0.borrow()
    }

}

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
pub trait IntoStoreId {
    fn into_storeid(self) -> StoreId;
}

impl IntoStoreId for PathBuf {
    fn into_storeid(self) -> StoreId {
        StoreId(self)
    }
}

impl IntoStoreId for StoreId {
    fn into_storeid(self) -> StoreId {
        self
    }
}

pub fn build_entry_path(store: &Store, path_elem: &str) -> Result<PathBuf> {
    debug!("Checking path element for version");
    if path_elem.split('~').last().map_or(false, |v| Version::parse(v).is_err()) {
        debug!("Version cannot be parsed from {:?}", path_elem);
        debug!("Path does not contain version!");
        return Err(SEK::StorePathLacksVersion.into());
    }
    debug!("Version checking succeeded");

    debug!("Building path from {:?}", path_elem);
    let mut path = store.path().clone();

    if path_elem.starts_with('/') {
        path.push(&path_elem[1..]);
    } else {
        path.push(path_elem);
    }

    Ok(path)
}

#[macro_export]
macro_rules! module_entry_path_mod {
    ($name:expr, $version:expr) => (
        #[deny(missing_docs,
                missing_copy_implementations,
                trivial_casts, trivial_numeric_casts,
                unsafe_code,
                unstable_features,
                unused_import_braces, unused_qualifications,
                unused_imports)]
        /// A helper module to create valid module entry paths
        pub mod module_path {
            use semver::Version;
            use std::convert::AsRef;
            use std::path::Path;
            use std::path::PathBuf;

            use $crate::storeid::StoreId;

            /// A Struct giving you the ability to choose store entries assigned
            /// to it.
            ///
            /// It is created through a call to `new`.
            pub struct ModuleEntryPath(PathBuf);

            impl ModuleEntryPath {
                /// Path has to be a valid UTF-8 string or this will panic!
                pub fn new<P: AsRef<Path>>(pa: P) -> ModuleEntryPath {
                    let mut path = PathBuf::new();
                    path.push(format!("{}", $name));
                    path.push(pa.as_ref().clone());
                    let version = Version::parse($version).unwrap();
                    let name = pa.as_ref().file_name().unwrap()
                        .to_str().unwrap();
                    path.set_file_name(format!("{}~{}",
                                               name,
                                               version));
                    ModuleEntryPath(path)
                }
            }

            impl $crate::storeid::IntoStoreId for ModuleEntryPath {
                fn into_storeid(self) -> $crate::storeid::StoreId {
                    StoreId::from(self.0)
                }
            }
        }
    )
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = StoreId>>,
}

impl Debug for StoreIdIterator {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "StoreIdIterator")
    }

}

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
        StoreIdIterator {
            iter: iter,
        }
    }

}

impl Iterator for StoreIdIterator {
    type Item = StoreId;

    fn next(&mut self) -> Option<StoreId> {
        self.iter.next()
    }

}

#[cfg(test)]
mod test {

    use storeid::IntoStoreId;

    module_entry_path_mod!("test", "0.2.0-alpha+leet1337");

    #[test]
    fn correct_path() {
        let p = module_path::ModuleEntryPath::new("test");

        assert_eq!(p.into_storeid().to_str().unwrap(), "test/test~0.2.0-alpha+leet1337");
    }

}
<|endoftext|>


<commit_before>//! To run a LOGO program, run:
//!     cargo run --example logo_interpreter -- my_logo_program.txt

extern crate turtle;

use turtle::Turtle;
use std::env;
use std::fs::File;
use std::io::{self, BufRead, BufReader};

fn main() {
    let mut turtle = Turtle::new();

    let args: Vec<String> = env::args().collect();

    if args.len() != 2 {
        println!("Interactive LOGO Mode.\nType the commands in stdin.\nPress '^C' (cmd/ctrl+C) to exit");
        let stdin = io::stdin();
        interpret(&mut turtle, stdin)
    }
    else {
        let path = &args[1];
        let file = File::open(path).expect("Could not open provided program");
        interpret(&mut turtle, file)
    }
}

fn interpret<R: io::Read>(turtle: &mut Turtle, input: R) {
    let mut reader = BufReader::new(input);
    loop {
        let mut buffer = String::new();
        let read_bytes = reader.read_line(&mut buffer)
            .expect("Unable read input");
        if read_bytes == 0 {
            // Reached EOF, break loop
            break;
        }
        let cmd_args = buffer.split_whitespace();
        handle_command(turtle, cmd_args);
    }
}

fn handle_command<'a, A: Iterator<Item = &'a str>>(turtle: &mut Turtle, mut args: A) {
    while let Some(command) = args.next() {
        match command {
            "fd" | "forward" => {
                let distance = parse_distance(args.next()
                    .expect("Expected a distance value after fd/forward command"));
                turtle.forward(distance);
            },
            "bk" | "back" => {
                let distance = parse_distance(args.next()
                    .expect("Expect a distance value after bk/back command"));
                turtle.backward(distance);
            },
            "lt" | "left" => {
                let distance = parse_distance(args.next()
                    .expect("Expect a distance value after lt/left command"));
                turtle.left(distance);
            },
            "rt" | "right" => {
                let distance = parse_distance(args.next()
                    .expect("Expect a distance value after rt/right command"));
                turtle.right(distance);
            },
            _ => unimplemented!("Use of invalid or unsupported LOGO command"),
        }
    }
}

fn parse_distance(s: &str) -> f64 {
    let dist: f64 = s.parse().expect("Not a valid number");
    dist
}
<commit_msg>Added some logo commands to interpreter<commit_after>//! To run a LOGO program, run:
//!     cargo run --example logo_interpreter -- my_logo_program.txt

extern crate turtle;

use turtle::Turtle;
use std::env;
use std::fs::File;
use std::io::{self, BufRead, BufReader};

fn main() {
    let mut turtle = Turtle::new();

    let args: Vec<String> = env::args().collect();

    if args.len() != 2 {
        println!("Interactive LOGO Mode.\nType the commands in stdin.\nPress '^C' (cmd/ctrl+C) to exit");
        let stdin = io::stdin();
        interpret(&mut turtle, stdin)
    }
    else {
        let path = &args[1];
        let file = File::open(path).expect("Could not open provided program");
        interpret(&mut turtle, file)
    }
}

fn interpret<R: io::Read>(turtle: &mut Turtle, input: R) {
    let mut reader = BufReader::new(input);
    loop {
        let mut buffer = String::new();
        let read_bytes = reader.read_line(&mut buffer)
            .expect("Unable read input");
        if read_bytes == 0 {
            // Reached EOF, break loop
            break;
        }
        let cmd_args = buffer.split_whitespace();
        handle_command(turtle, cmd_args);
    }
}

fn handle_command<'a, A: Iterator<Item = &'a str>>(turtle: &mut Turtle, mut args: A) {
    while let Some(command) = args.next() {
        match command {
            "fd" | "forward" => {
                let distance = parse_distance(args.next()
                    .expect("Expected a distance value after fd/forward command"));
                turtle.forward(distance);
            },
            "bk" | "back" => {
                let distance = parse_distance(args.next()
                    .expect("Expect a distance value after bk/back command"));
                turtle.backward(distance);
            },
            "lt" | "left" => {
                let distance = parse_distance(args.next()
                    .expect("Expect a distance value after lt/left command"));
                turtle.left(distance);
            },
            "rt" | "right" => {
                let distance = parse_distance(args.next()
                    .expect("Expect a distance value after rt/right command"));
                turtle.right(distance);
            },
            "home" => {
                turtle.home();
            },
            "setx" => {
                let x_pos = parse_distance(args.next()
                    .expect("No expression found"));
                turtle.set_x(x_pos);
            },
            "sety" => {
                let y_pos = parse_distance(args.next()
                    .expect("No expression found"));
                turtle.set_y(y_pos);
            },
            "setheading" | "seth" => {
                let expr = parse_distance(args.next()
                    .expect("No expression found"));
                turtle.set_heading(expr);
            },
            "showturtle" | "st" => {
                turtle.show();
            },
            "hideturtle" | "ht" => {
                turtle.hide();
            },
            "clean" => {
                turtle.clear();
            },
            "clearscreen" | "cs" => {
                turtle.clear();
                turtle.home();
            },
            "pendown" | "pd" => {
                turtle.pen_down();
            },
            "penup" | "pu" => {
                turtle.pen_up();
            },
            "setpensize" | "setwidth" | "setpw" => {
                let value = parse_distance(args.next()
                    .expect("No value found"));
                turtle.set_pen_size(value);
            },
            _ => unimplemented!("Use of invalid or unsupported LOGO command"),
        }
    }
}

fn parse_distance(s: &str) -> f64 {
    let dist: f64 = s.parse().expect("Not a valid number");
    dist
}
<|endoftext|>