<commit_before>//! List projects
//!
//! https://docs.gitlab.com/ce/api/projects.html
//!
//! # List projects
//!
//! Get a list of projects for which the authenticated user is a member.
//!
//! ```text
//! GET /projects
//! ```
//!
//! Parameters:
//!
//! | Attribute | Type | Required | Description |
//! | --------- | ---- | -------- | ----------- |
//! | `archived` | boolean | no | Limit by archived status |
//! | `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` |
//! | `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` |
//! | `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` |
//! | `search` | string | no | Return list of authorized projects matching the search criteria |
//! | `simple` | boolean | no | Return only the ID, URL, name, and path of each project |
//!

use serde_json;
use serde_urlencoded;

use BuildQuery;
use Projects;

pub mod all;
pub mod id_branches;
pub mod id_branch;
pub mod id_events;
pub mod id_hooks_id;
pub mod id_hooks;
pub mod id;
pub mod owned;
pub mod search;
pub mod starred;
pub mod visible;

#[cfg(feature = "serde_derive")]
include!("serde_types.in.rs");

#[cfg(feature = "serde_codegen")]
include!(concat!(env!("OUT_DIR"), "/projects/serde_types.rs"));

#[derive(Debug, Clone)]
pub struct ProjectsLister<'a> {
    gl: &'a ::GitLab,
    internal: ProjectListerInternal,
}

impl<'a> ProjectsLister<'a> {
    pub fn new(gl: &'a ::GitLab) -> ProjectsLister {
        ProjectsLister {
            gl: gl,
            internal: ProjectListerInternal {
                archived: None,
                visibility: None,
                order_by: None,
                sort: None,
                search: None,
                simple: None,
            },
        }
    }

    pub fn archived(&'a mut self, archived: bool) -> &'a mut ProjectsLister {
        self.internal.archived = Some(archived);
        self
    }

    pub fn visibility(&'a mut self, visibility: ::ListingVisibility) -> &'a mut ProjectsLister {
        self.internal.visibility = Some(visibility);
        self
    }

    pub fn order_by(&'a mut self, order_by: ListingOrderBy) -> &'a mut ProjectsLister {
        self.internal.order_by = Some(order_by);
        self
    }

    pub fn sort(&'a mut self, sort: ::ListingSort) -> &'a mut ProjectsLister {
        self.internal.sort = Some(sort);
        self
    }

    pub fn search(&'a mut self, search: String) -> &'a mut ProjectsLister {
        self.internal.search = Some(search);
        self
    }

    pub fn simple(&'a mut self, simple: bool) -> &'a mut ProjectsLister {
        self.internal.simple = Some(simple);
        self
    }

    /// Commit the lister: Query GitLab and return a list of projects.
    pub fn list(&self) -> Projects {
        // let query = serde_urlencoded::to_string(&self);
        let query = self.build_query();
        debug!("query: {:?}", query);

        let projects: Result<Projects, serde_json::Error> = self.gl.get(&query);

        projects.unwrap()
    }
}

impl<'a> BuildQuery for ProjectsLister<'a> {
    fn build_query(&self) -> String {

        let encoded = serde_urlencoded::to_string(&self.internal).unwrap();
        let mut query = String::from("projects");
        if !encoded.is_empty() {
            query.push_str("?");
            query.push_str(&encoded);
        }

        query
    }
}

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

    #[test]
    fn build_query_default() {
        let expected_string = "projects";

        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let projects_lister = gl.projects();
        let query = projects_lister.build_query();
        assert_eq!(query, expected_string);

        let query = gl.projects().build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_archived() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?archived=true";

        let mut projects_lister = gl.projects();
        let query = projects_lister.archived(true).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().archived(true).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?archived=false";

        let mut projects_lister = gl.projects();
        let query = projects_lister.archived(false).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().archived(false).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_visibility() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?visibility=public";
        let mut projects_lister = gl.projects();
        let query = projects_lister.visibility(::ListingVisibility::Public).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().visibility(::ListingVisibility::Public).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?visibility=internal";
        let mut projects_lister = gl.projects();
        let query = projects_lister.visibility(::ListingVisibility::Internal).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().visibility(::ListingVisibility::Internal).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?visibility=private";
        let mut projects_lister = gl.projects();
        let query = projects_lister.visibility(::ListingVisibility::Private).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().visibility(::ListingVisibility::Private).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_order_by() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?order_by=id";
        let mut projects_lister = gl.projects();
        let query = projects_lister.order_by(ListingOrderBy::Id).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().order_by(ListingOrderBy::Id).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=name";
        let mut projects_lister = gl.projects();
        let query = projects_lister.order_by(ListingOrderBy::Name).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().order_by(ListingOrderBy::Name).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=path";
        let mut projects_lister = gl.projects();
        let query = projects_lister.order_by(ListingOrderBy::Path).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().order_by(ListingOrderBy::Path).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=created_at";
        let mut projects_lister = gl.projects();
        let query = projects_lister.order_by(ListingOrderBy::CreatedAt).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().order_by(ListingOrderBy::CreatedAt).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=updated_at";
        let mut projects_lister = gl.projects();
        let query = projects_lister.order_by(ListingOrderBy::UpdatedAt).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().order_by(ListingOrderBy::UpdatedAt).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=last_activity_at";
        let mut projects_lister = gl.projects();
        let query = projects_lister.order_by(ListingOrderBy::LastActivityAt).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().order_by(ListingOrderBy::LastActivityAt).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_sort() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?sort=asc";
        let mut projects_lister = gl.projects();
        let query = projects_lister.sort(::ListingSort::Asc).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().sort(::ListingSort::Asc).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?sort=desc";
        let mut projects_lister = gl.projects();
        let query = projects_lister.sort(::ListingSort::Desc).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().sort(::ListingSort::Desc).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_search() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?search=SearchPattern";
        let mut projects_lister = gl.projects();
        let query = projects_lister.search(String::from("SearchPattern")).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().search(String::from("SearchPattern")).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_simple() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?simple=true";
        let mut projects_lister = gl.projects();
        let query = projects_lister.simple(true).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().simple(true).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?simple=false";
        let mut projects_lister = gl.projects();
        let query = projects_lister.simple(false).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().simple(false).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn groups_build_query_multiple() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?archived=true&simple=true";
        let mut projects_lister = gl.projects();
        let query = projects_lister.archived(true).simple(true).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().archived(true).simple(true).build_query();
        assert_eq!(query, expected_string);
    }
}
<commit_msg>Add `ProjectsLister::owned()`<commit_after>//! List projects
//!
//! https://docs.gitlab.com/ce/api/projects.html
//!
//! # List projects
//!
//! Get a list of projects for which the authenticated user is a member.
//!
//! ```text
//! GET /projects
//! ```
//!
//! Parameters:
//!
//! | Attribute | Type | Required | Description |
//! | --------- | ---- | -------- | ----------- |
//! | `archived` | boolean | no | Limit by archived status |
//! | `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` |
//! | `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` |
//! | `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` |
//! | `search` | string | no | Return list of authorized projects matching the search criteria |
//! | `simple` | boolean | no | Return only the ID, URL, name, and path of each project |
//!

use serde_json;
use serde_urlencoded;

use BuildQuery;
use Projects;

pub mod all;
pub mod id_branches;
pub mod id_branch;
pub mod id_events;
pub mod id_hooks_id;
pub mod id_hooks;
pub mod id;
pub mod owned;
pub mod search;
pub mod starred;
pub mod visible;

#[cfg(feature = "serde_derive")]
include!("serde_types.in.rs");

#[cfg(feature = "serde_codegen")]
include!(concat!(env!("OUT_DIR"), "/projects/serde_types.rs"));

#[derive(Debug, Clone)]
pub struct ProjectsLister<'a> {
    gl: &'a ::GitLab,
    internal: ProjectListerInternal,
}

impl<'a> ProjectsLister<'a> {
    pub fn new(gl: &'a ::GitLab) -> ProjectsLister {
        ProjectsLister {
            gl: gl,
            internal: ProjectListerInternal {
                archived: None,
                visibility: None,
                order_by: None,
                sort: None,
                search: None,
                simple: None,
            },
        }
    }

    pub fn owned(&self) -> owned::ProjectsLister {
        // assert_eq!(self, ProjectsLister::new(self.gl));
        owned::ProjectsLister::new(self.gl)
    }

    pub fn archived(&'a mut self, archived: bool) -> &'a mut ProjectsLister {
        self.internal.archived = Some(archived);
        self
    }

    pub fn visibility(&'a mut self, visibility: ::ListingVisibility) -> &'a mut ProjectsLister {
        self.internal.visibility = Some(visibility);
        self
    }

    pub fn order_by(&'a mut self, order_by: ListingOrderBy) -> &'a mut ProjectsLister {
        self.internal.order_by = Some(order_by);
        self
    }

    pub fn sort(&'a mut self, sort: ::ListingSort) -> &'a mut ProjectsLister {
        self.internal.sort = Some(sort);
        self
    }

    pub fn search(&'a mut self, search: String) -> &'a mut ProjectsLister {
        self.internal.search = Some(search);
        self
    }

    pub fn simple(&'a mut self, simple: bool) -> &'a mut ProjectsLister {
        self.internal.simple = Some(simple);
        self
    }

    /// Commit the lister: Query GitLab and return a list of projects.
    pub fn list(&self) -> Projects {
        // let query = serde_urlencoded::to_string(&self);
        let query = self.build_query();
        debug!("query: {:?}", query);

        let projects: Result<Projects, serde_json::Error> = self.gl.get(&query);

        projects.unwrap()
    }
}

impl<'a> BuildQuery for ProjectsLister<'a> {
    fn build_query(&self) -> String {

        let encoded = serde_urlencoded::to_string(&self.internal).unwrap();
        let mut query = String::from("projects");
        if !encoded.is_empty() {
            query.push_str("?");
            query.push_str(&encoded);
        }

        query
    }
}

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

    #[test]
    fn build_query_default() {
        let expected_string = "projects";

        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let projects_lister = gl.projects();
        let query = projects_lister.build_query();
        assert_eq!(query, expected_string);

        let query = gl.projects().build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_archived() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?archived=true";

        let mut projects_lister = gl.projects();
        let query = projects_lister.archived(true).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().archived(true).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?archived=false";

        let mut projects_lister = gl.projects();
        let query = projects_lister.archived(false).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().archived(false).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_visibility() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?visibility=public";
        let mut projects_lister = gl.projects();
        let query = projects_lister.visibility(::ListingVisibility::Public).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().visibility(::ListingVisibility::Public).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?visibility=internal";
        let mut projects_lister = gl.projects();
        let query = projects_lister.visibility(::ListingVisibility::Internal).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().visibility(::ListingVisibility::Internal).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?visibility=private";
        let mut projects_lister = gl.projects();
        let query = projects_lister.visibility(::ListingVisibility::Private).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().visibility(::ListingVisibility::Private).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_order_by() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?order_by=id";
        let mut projects_lister = gl.projects();
        let query = projects_lister.order_by(ListingOrderBy::Id).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().order_by(ListingOrderBy::Id).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=name";
        let mut projects_lister = gl.projects();
        let query = projects_lister.order_by(ListingOrderBy::Name).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().order_by(ListingOrderBy::Name).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=path";
        let mut projects_lister = gl.projects();
        let query = projects_lister.order_by(ListingOrderBy::Path).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().order_by(ListingOrderBy::Path).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=created_at";
        let mut projects_lister = gl.projects();
        let query = projects_lister.order_by(ListingOrderBy::CreatedAt).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().order_by(ListingOrderBy::CreatedAt).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=updated_at";
        let mut projects_lister = gl.projects();
        let query = projects_lister.order_by(ListingOrderBy::UpdatedAt).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().order_by(ListingOrderBy::UpdatedAt).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=last_activity_at";
        let mut projects_lister = gl.projects();
        let query = projects_lister.order_by(ListingOrderBy::LastActivityAt).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().order_by(ListingOrderBy::LastActivityAt).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_sort() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?sort=asc";
        let mut projects_lister = gl.projects();
        let query = projects_lister.sort(::ListingSort::Asc).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().sort(::ListingSort::Asc).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?sort=desc";
        let mut projects_lister = gl.projects();
        let query = projects_lister.sort(::ListingSort::Desc).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().sort(::ListingSort::Desc).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_search() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?search=SearchPattern";
        let mut projects_lister = gl.projects();
        let query = projects_lister.search(String::from("SearchPattern")).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().search(String::from("SearchPattern")).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_simple() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?simple=true";
        let mut projects_lister = gl.projects();
        let query = projects_lister.simple(true).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().simple(true).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?simple=false";
        let mut projects_lister = gl.projects();
        let query = projects_lister.simple(false).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().simple(false).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn groups_build_query_multiple() {
        let gl = ::GitLab::new(&"localhost", "XXXXXXXXXXXXXXXXXXXX");
        // let gl: ::GitLab = Default::default();

        let expected_string = "projects?archived=true&simple=true";
        let mut projects_lister = gl.projects();
        let query = projects_lister.archived(true).simple(true).build_query();
        assert_eq!(query, expected_string);
        let query = gl.projects().archived(true).simple(true).build_query();
        assert_eq!(query, expected_string);
    }
}
<|endoftext|>


<commit_before>use std::os::getenv;

struct HttpContext{
    request: Request,
    response: Response
}

impl HttpContext{
    fn create() -> HttpContext{
        HttpContext{
            request: Request::populate(),
            response: Response::new()
        }
    }
}

struct Request {
    path: ~str,
    querystring: ~str
}

impl Request {
    fn populate() -> Request {
        Request{
            path: getenv("PATH_INFO").unwrap_or(~""),
            querystring: getenv("QUERY_STRING").unwrap_or(~"")
        }
    }
}

struct Response{
    contenttype: ~str,
    body: ~str
}

impl Response{
    fn new() -> Response{
        Response{contenttype: ~"text/plain", body: ~""}
    }
}

struct Route {
    path: ~str,
    handler: ~fn(@mut HttpContext)
}

struct Router{
    routes: ~[Route],
}

impl Router{
    fn new() -> Router{
        Router{routes: ~[]}
    }
    fn add(&mut self, r: ~Route){
        self.routes.push(*r);
    }
    fn execute(&self, c: @mut HttpContext) {
        for route in self.routes.iter(){
            if(route.path == c.request.path){
                (route.handler)(c);
            }
        }
    }
    fn controller<T>(@mut self, creator: ~fn(@mut HttpContext) -> T) -> ControllerBox<T>
    {
        ControllerBox{
            router: self,
            route: ~Route{path: ~"", handler: default_handler},
            creator: Some(creator)
        }
    }
}

trait HttpController{

}

struct ControllerBox<T>{
    router: @mut Router,
    route: ~Route,
    creator: Option<~fn(@mut HttpContext) -> T>
}

impl<T> ControllerBox<T>{
    fn handles(@mut self, path: ~str) -> @mut ControllerBox<T>{
        self.route.path=path;
        self
    }
    fn with(@mut self, invoker: ~fn(&mut T)) -> @mut ControllerBox<T>{
        let tmp=self.creator.take();

        self.router.add(~Route{path: self.route.path.clone(), handler:
         |c| {
            match tmp {
                None => (),
                Some(ref t) => {
                    let mut ctrl=(*t)(c);
                    invoker(&mut ctrl);
                }
            };
        }});
        self
    }
}
/*
struct Meh{
    biz: ~fn(int) -> int
}

impl Meh{
    fn foo(@mut self
}
*/

struct TestController{
    context: @mut HttpContext
}

impl TestController{
    fn new(c: @mut HttpContext) -> TestController{
        TestController{ context: c}
    }
    fn index(&mut self) {
        self.context.response.body.push_str("test index");
    }
}

fn default_handler(context: @mut HttpContext){
    context.response.body.push_str("404 not found");
}

fn index(context: @mut HttpContext){
    context.response.body.push_str("yay index");
}

fn foo(context: @mut HttpContext){
    context.response.body.push_str("yay foo");
}

fn main() {
    let mut context=@mut HttpContext::create();
    let mut router=@mut Router::new();
    router.add(~Route{path: ~"", handler: index});
    router.add(~Route{path: ~"/foo", handler: foo});

    let mut test = @mut router.controller(|c| TestController::new(c));
    test.handles(~"/test").with(|c| c.index());

    router.execute(context);

    println(context.response.contenttype);
    println("");
    println(context.response.body);
}<commit_msg>Huge clean up to not use any @ managed pointers This also ended up making my pointer ownership structure quite sane<commit_after>use std::os::getenv;
use std::rc::RcMut;

struct HttpContext{
    request: Request,
    response: Response
}

impl HttpContext{
    fn create() -> HttpContext{
        HttpContext{
            request: Request::populate(),
            response: Response::new()
        }
    }
}

struct Request {
    path: ~str,
    querystring: ~str
}

impl Request {
    fn populate() -> Request {
        Request{
            path: getenv("PATH_INFO").unwrap_or(~""),
            querystring: getenv("QUERY_STRING").unwrap_or(~"")
        }
    }
}

struct Response{
    contenttype: ~str,
    body: ~str
}

impl Response{
    fn new() -> Response{
        Response{contenttype: ~"text/plain", body: ~""}
    }
}

struct Route {
    path: ~str,
    handler: ~fn(&mut ControllerContext)
}

struct Router{
    routes: ~[Route],
}

impl Router{
    fn new() -> Router{
        Router{routes: ~[]}
    }
    fn add(&mut self, r: ~Route){
        self.routes.push(*r);
    }
    fn execute(&mut self, c: &mut HttpContext) {
        for route in self.routes.iter(){
            if(route.path == c.request.path){
                (route.handler)(&mut ControllerContext{http: c, router: self});
            }
        }
    }
    fn controller<'r,T>(&'r mut self, creator: ~fn(&mut ControllerContext) -> T) -> ControllerBox<'r,T>
    {
        ControllerBox{
            router: self,
            route: ~Route{path: ~"", handler: default_handler},
            creator: Some(creator)
        }
    }
}

struct ControllerContext<'self>
{
    http: &'self mut HttpContext,
    router: &'self Router
}

trait HttpController{

}

struct ControllerBox<'self,T>{
    router: &'self mut Router,
    route: ~Route,
    creator: Option<~fn(&mut ControllerContext) -> T>
}

impl<'self,T> ControllerBox<'self,T>{
    fn handles(&'self mut self, path: ~str) -> &'self mut ControllerBox<'self,T>{
        self.route.path=path;
        self
    }
    fn with(&'self mut self, invoker: ~fn(&mut T, &mut ControllerContext)) -> &'self mut ControllerBox<'self,T>{
        let tmp=self.creator.take();

        self.router.add(~Route{path: self.route.path.clone(), handler:
         |c| {
            match tmp {
                None => (),
                Some(ref t) => {
                    let mut ctrl=(*t)(c);
                    invoker(&mut ctrl, c);
                }
            };
        }});
        self
    }
}
/*
struct Meh{
    biz: ~fn(int) -> int
}

impl Meh{
    fn foo(@mut self
}
*/

struct TestController;

impl TestController{
    fn new() -> TestController{
    TestController
    }
    fn index(&mut self, context: &mut ControllerContext) {
        context.http.response.body.push_str("test index");
    }
}

fn default_handler(context: &mut ControllerContext){
    context.http.response.body.push_str("404 not found");
}

fn index(context: &mut ControllerContext){
    context.http.response.body.push_str("yay index");
}

fn foo(context: &mut ControllerContext){
    context.http.response.body.push_str("yay foo");
}

fn main() {
    let mut context=HttpContext::create();
    let mut router=Router::new();
    router.add(~Route{path: ~"", handler: index});
    router.add(~Route{path: ~"/foo", handler: foo});
    {
        let mut test = router.controller(|c| TestController::new());
        test.handles(~"/test").with(|c,ctx| c.index(ctx));
    }

    router.execute(&mut context); //possible borrowing more than once

    println(context.response.contenttype);
    println("");
    println(context.response.body);
}<|endoftext|>


<commit_before>/*!
   Base OrbTk widget library.
*/

pub mod prelude;

pub(crate) use orbtk_core as api;
pub(crate) use orbtk_orbclient as shell;
pub(crate) use orbtk_proc_macros as proc_macros;
pub(crate) use orbtk_tinyskia as render;

pub use self::button::*;
pub use self::canvas::*;
pub use self::check_box::*;
pub use self::combo_box::*;
pub use self::container::*;
pub use self::cursor::*;
pub use self::font_icon_block::*;
pub use self::grid::*;
pub use self::image_widget::*;
pub use self::items_widget::*;
pub use self::list_view::*;
pub use self::master_detail::*;
pub use self::numeric_box::*;
pub use self::pager::*;
pub use self::password_box::*;
pub use self::popup::*;
pub use self::progress_bar::*;
pub use self::scroll_bar::*;
pub use self::scroll_indicator::*;
pub use self::scroll_viewer::*;
pub use self::slider::*;
pub use self::stack::*;
pub use self::switch::*;
pub use self::tab_widget::*;
pub use self::text_block::*;
pub use self::text_box::*;
pub use self::toggle_button::*;
pub use self::window::*;

pub mod behaviors;
mod button;
mod canvas;
mod check_box;
mod combo_box;
mod container;
mod cursor;
mod font_icon_block;
mod grid;
mod image_widget;
mod items_widget;
mod list_view;
mod master_detail;
mod numeric_box;
mod pager;
mod password_box;
mod popup;
mod progress_bar;
mod scroll_bar;
mod scroll_indicator;
mod scroll_viewer;
mod slider;
mod stack;
mod switch;
mod tab_widget;
mod text_block;
mod text_box;
pub mod themes;
mod toggle_button;
mod window;
<commit_msg>orbtk_widgets: update documentation strings<commit_after>/*!
   Base OrbTk widget library.
*/

/// This module pre-selects commonly used OrbTk crates and put them into scope.
pub mod prelude;

pub(crate) use orbtk_core as api;
pub(crate) use orbtk_orbclient as shell;
pub(crate) use orbtk_proc_macros as proc_macros;
pub(crate) use orbtk_tinyskia as render;

pub use self::button::*;
pub use self::canvas::*;
pub use self::check_box::*;
pub use self::combo_box::*;
pub use self::container::*;
pub use self::cursor::*;
pub use self::font_icon_block::*;
pub use self::grid::*;
pub use self::image_widget::*;
pub use self::items_widget::*;
pub use self::list_view::*;
pub use self::master_detail::*;
pub use self::numeric_box::*;
pub use self::pager::*;
pub use self::password_box::*;
pub use self::popup::*;
pub use self::progress_bar::*;
pub use self::scroll_bar::*;
pub use self::scroll_indicator::*;
pub use self::scroll_viewer::*;
pub use self::slider::*;
pub use self::stack::*;
pub use self::switch::*;
pub use self::tab_widget::*;
pub use self::text_block::*;
pub use self::text_box::*;
pub use self::toggle_button::*;
pub use self::window::*;

pub mod behaviors;
mod button;
mod canvas;
mod check_box;
mod combo_box;
mod container;
mod cursor;
mod font_icon_block;
mod grid;
mod image_widget;
mod items_widget;
mod list_view;
mod master_detail;
mod numeric_box;
mod pager;
mod password_box;
mod popup;
mod progress_bar;
mod scroll_bar;
mod scroll_indicator;
mod scroll_viewer;
mod slider;
mod stack;
mod switch;
mod tab_widget;
mod text_block;
mod text_box;
pub mod themes;
mod toggle_button;
mod window;
<|endoftext|>


<commit_before>#![no_std]
#![allow(dead_code)]

#[macro_use]
extern crate derive_more;

#[derive(
    AddAssign,
    MulAssign,
    Add,
    Mul,
    Not,
    Index,
    Display,
    FromStr,
    Into,
    IntoRef,
    IntoRefMut,
    From,
    IndexMut,
    Sum,
    DerefToInner,
    DerefMutToInner,
    Constructor
)]
struct MyInts(u64);

#[derive(Iterator)]
struct MyVec<'a>(::core::slice::Iter<'a, i32>);

#[derive(
    From,
    FromStr,
    Display,
    Index,
    Not,
    Add,
    Mul,
    Sum,
    IndexMut,
    AddAssign,
    DerefToInner,
    DerefMutToInner,
    IntoIterator,
    IntoIteratorRef,
    Constructor
)]
struct Wrapped<T: Clone>(T);

#[derive(Iterator, Deref, DerefMut)]
struct Wrapped2<T: Clone>(T);

#[derive(From, Not, Add, Mul, AddAssign, Constructor, Sum)]
struct WrappedDouble<T: Clone, U: Clone>(T, U);

#[derive(Add, Not, TryInto)]
enum MixedInts {
    SmallInt(i32),
    BigInt(i64),
    TwoSmallInts(i32, i32),
    NamedSmallInts { x: i32, y: i32 },
    UnsignedOne(u32),
    UnsignedTwo(u32),
}

#[derive(Not, Add)]
enum EnumWithUnit {
    SmallInt(i32),
    Unit,
}
<commit_msg>Add extra test to no_std<commit_after>#![no_std]
#![allow(dead_code)]

#[macro_use]
extern crate derive_more;

#[derive(
    AddAssign,
    MulAssign,
    Add,
    Mul,
    Not,
    Index,
    Display,
    FromStr,
    Into,
    IntoRef,
    IntoRefMut,
    From,
    IndexMut,
    Sum,
    DerefToInner,
    DerefMutToInner,
    Constructor
)]
struct MyInts(u64);

#[derive(Iterator)]
struct MyVec<'a>(::core::slice::Iter<'a, i32>);

#[derive(
    From,
    FromStr,
    Display,
    Index,
    Not,
    Add,
    Mul,
    Sum,
    IndexMut,
    AddAssign,
    DerefToInner,
    DerefMutToInner,
    IntoIterator,
    IntoIteratorRef,
    IntoIteratorRefMut,
    Constructor
)]
struct Wrapped<T: Clone>(T);

#[derive(Iterator, Deref, DerefMut)]
struct Wrapped2<T: Clone>(T);

#[derive(From, Not, Add, Mul, AddAssign, Constructor, Sum)]
struct WrappedDouble<T: Clone, U: Clone>(T, U);

#[derive(Add, Not, TryInto)]
enum MixedInts {
    SmallInt(i32),
    BigInt(i64),
    TwoSmallInts(i32, i32),
    NamedSmallInts { x: i32, y: i32 },
    UnsignedOne(u32),
    UnsignedTwo(u32),
}

#[derive(Not, Add)]
enum EnumWithUnit {
    SmallInt(i32),
    Unit,
}
<|endoftext|>


<commit_before>extern crate petgraph;

use petgraph::{
    OGraph,
};

use petgraph::ograph::min_spanning_tree;

#[test]
fn mst() {
    let mut gr = OGraph::<_, f32>::new();
    let a = gr.add_node("A");
    let b = gr.add_node("B");
    let c = gr.add_node("C");
    let d = gr.add_node("D");
    let e = gr.add_node("E");
    let f = gr.add_node("F");
    let g = gr.add_node("gr");
    gr.add_edge(a, b, 7.);
    gr.add_edge(a, d, 5.);
    gr.add_edge(d, b, 9.);
    gr.add_edge(b, c, 8.);
    gr.add_edge(b, e, 7.);
    gr.add_edge(c, e, 5.);
    gr.add_edge(d, e, 15.);
    gr.add_edge(d, f, 6.);
    gr.add_edge(f, e, 8.);
    gr.add_edge(f, g, 11.);
    gr.add_edge(e, g, 9.);

    let mst = min_spanning_tree(&gr);
    println!("MST is:\n{}", mst);
    assert!(mst.node_count() == gr.node_count());
    assert!(mst.edge_count() == gr.node_count() - 1);

    let one_of = |&: a: bool, b: bool| {
        (a && !b) || (!a && b)
    };
    let have_one = |&: x, y| {
        one_of(mst.find_edge(x, y).is_some(), mst.find_edge(y, x).is_some())
    };

    assert!(have_one(a, b));
    assert!(have_one(a, d));
    assert!(have_one(b, e));
    assert!(have_one(e, c));
    assert!(have_one(e, g));
    assert!(have_one(d, f));

    assert!(mst.find_edge(d, b).is_none());
    assert!(mst.find_edge(b, c).is_none());

    // check the exact edges are there
}
<commit_msg>Test disjoint case in mst.<commit_after>extern crate petgraph;

use petgraph::{
    OGraph,
};

use petgraph::ograph::min_spanning_tree;

#[test]
fn mst() {
    let mut gr = OGraph::<_, f32>::new();
    let a = gr.add_node("A");
    let b = gr.add_node("B");
    let c = gr.add_node("C");
    let d = gr.add_node("D");
    let e = gr.add_node("E");
    let f = gr.add_node("F");
    let g = gr.add_node("G");
    gr.add_edge(a, b, 7.);
    gr.add_edge(a, d, 5.);
    gr.add_edge(d, b, 9.);
    gr.add_edge(b, c, 8.);
    gr.add_edge(b, e, 7.);
    gr.add_edge(c, e, 5.);
    gr.add_edge(d, e, 15.);
    gr.add_edge(d, f, 6.);
    gr.add_edge(f, e, 8.);
    gr.add_edge(f, g, 11.);
    gr.add_edge(e, g, 9.);

    // add a disjoint part
    let h = gr.add_node("H");
    let i = gr.add_node("I");
    let j = gr.add_node("J");
    gr.add_edge(h, i, 1.);
    gr.add_edge(h, j, 3.);
    gr.add_edge(i, j, 1.);

    let mst = min_spanning_tree(&gr);
    println!("MST is:\n{}", mst);
    assert!(mst.node_count() == gr.node_count());
    // |E| = |N| - 2  because ther are two disconnected components.
    assert!(mst.edge_count() == gr.node_count() - 2);

    let one_of = |&: a: bool, b: bool| {
        (a && !b) || (!a && b)
    };
    let have_one = |&: x, y| {
        one_of(mst.find_edge(x, y).is_some(), mst.find_edge(y, x).is_some())
    };

    // check the exact edges are there
    assert!(have_one(a, b));
    assert!(have_one(a, d));
    assert!(have_one(b, e));
    assert!(have_one(e, c));
    assert!(have_one(e, g));
    assert!(have_one(d, f));

    assert!(have_one(h, i));
    assert!(have_one(i, j));

    assert!(mst.find_edge(d, b).is_none());
    assert!(mst.find_edge(b, c).is_none());

}
<|endoftext|>


<commit_before>use super::{ImageId, Image, MultiImage, Buffer};
use std::{slice, ptr};
use std::path::PathBuf;
use std::os::raw::c_char;
use std::ffi::CStr;
use image;

#[no_mangle]
pub extern "C" fn image_free_id(id: *mut ImageId) {
    let _ = unsafe { Box::from_raw(id) };
}

#[no_mangle]
pub extern "C" fn image_free(id: *mut Image) {
    let _ = unsafe { Box::from_raw(id) };
}

#[no_mangle]
pub extern "C" fn image_free_multi(id: *mut MultiImage) {
    let _ = unsafe { Box::from_raw(id) };
}

#[no_mangle]
pub extern "C" fn image_open_path(path: *const c_char) -> *mut ImageId {
    let path: &CStr = unsafe { CStr::from_ptr(path) };
    let path: &str = match path.to_str() {
        Ok(path) => path,
        Err(_) => return ptr::null_mut(),
    };
    Box::into_raw(Box::new(ImageId::File(PathBuf::from(path))))
}

#[no_mangle]
pub extern "C" fn image_open_buffer(buf: *const u8, len: usize) -> *mut ImageId {
    let slice = unsafe { slice::from_raw_parts(buf, len) };
    let id = ImageId::Borrowed(slice as *const [u8]);
    Box::into_raw(Box::new(id))
}

#[no_mangle]
pub extern "C" fn image_open_buffer_copy(buf: *const u8, len: usize) -> *mut ImageId {
    let slice = unsafe { slice::from_raw_parts(buf, len) };
    let mut vec = Vec::with_capacity(len);
    unsafe { vec.set_len(len) };
    (&mut vec[..]).copy_from_slice(slice);
    let id = ImageId::Owned(Buffer::Boxed(vec.into_boxed_slice()));
    Box::into_raw(Box::new(id))
}

#[no_mangle]
pub extern "C" fn image_open_buffer_owned(buf: *const u8, len: usize, free: fn(*const u8, usize)) -> *mut ImageId {
    let id = ImageId::Owned(Buffer::Allocated(buf, len, free));
    Box::into_raw(Box::new(id))
}

#[no_mangle]
pub extern "C" fn image_load_png(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::PNG) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_jpg(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::JPEG) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_gif(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::GIF) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_webp(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::WEBP) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_ppm(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::PPM) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_bmp(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::BMP) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_ico(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::ICO) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_multi_gif(id: *mut ImageId) -> *mut MultiImage {
    let id = unsafe { Box::from_raw(id) };
    Box::into_raw(match MultiImage::new(*id) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_get_frame(image: *const Image) -> *const image::Frame {
    unsafe { &(*image).frame }
}

#[no_mangle]
pub extern "C" fn image_get_frame_multi(image: *mut MultiImage, index: u32, delay: *mut u16) -> *const image::Frame {
    let image: &mut MultiImage = unsafe { &mut *image };
    let frame = match image.request_frame(index as usize) {
        Some(frame) => {
            frame as *const _
        },
        None => return ptr::null(),
    };
    unsafe { *delay = image.delay };
    frame
}

#[no_mangle]
pub extern "C" fn image_get_size(image: *const Image, width: *mut u32, height: *mut u32) {
    unsafe {
        let image: &Image = &*image;
        *width = image.frame.buffer().width();
        *height = image.frame.buffer().height();
    }
}

#[no_mangle]
pub extern "C" fn image_get_multi_size(image: *const MultiImage, width: *mut u32, height: *mut u32) {
    unsafe {
        let image: &MultiImage = &*image;
        *width = image.width;
        *height = image.height;
    }
}

#[no_mangle]
pub extern "C" fn image_get_frame_buffer(frame: *const image::Frame, buffer: *mut *const u8) {
    unsafe {
        let frame: &image::Frame = &*frame;
        *buffer = (&frame.buffer()[(0, 0)]) as *const image::Rgba<u8> as *const u8
    }
}

<commit_msg>copyright header<commit_after>// The MIT License (MIT)
// Copyright (c) 2016 Connor Hilarides
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

use super::{ImageId, Image, MultiImage, Buffer};
use std::{slice, ptr};
use std::path::PathBuf;
use std::os::raw::c_char;
use std::ffi::CStr;
use image;

#[no_mangle]
pub extern "C" fn image_free_id(id: *mut ImageId) {
    let _ = unsafe { Box::from_raw(id) };
}

#[no_mangle]
pub extern "C" fn image_free(id: *mut Image) {
    let _ = unsafe { Box::from_raw(id) };
}

#[no_mangle]
pub extern "C" fn image_free_multi(id: *mut MultiImage) {
    let _ = unsafe { Box::from_raw(id) };
}

#[no_mangle]
pub extern "C" fn image_open_path(path: *const c_char) -> *mut ImageId {
    let path: &CStr = unsafe { CStr::from_ptr(path) };
    let path: &str = match path.to_str() {
        Ok(path) => path,
        Err(_) => return ptr::null_mut(),
    };
    Box::into_raw(Box::new(ImageId::File(PathBuf::from(path))))
}

#[no_mangle]
pub extern "C" fn image_open_buffer(buf: *const u8, len: usize) -> *mut ImageId {
    let slice = unsafe { slice::from_raw_parts(buf, len) };
    let id = ImageId::Borrowed(slice as *const [u8]);
    Box::into_raw(Box::new(id))
}

#[no_mangle]
pub extern "C" fn image_open_buffer_copy(buf: *const u8, len: usize) -> *mut ImageId {
    let slice = unsafe { slice::from_raw_parts(buf, len) };
    let mut vec = Vec::with_capacity(len);
    unsafe { vec.set_len(len) };
    (&mut vec[..]).copy_from_slice(slice);
    let id = ImageId::Owned(Buffer::Boxed(vec.into_boxed_slice()));
    Box::into_raw(Box::new(id))
}

#[no_mangle]
pub extern "C" fn image_open_buffer_owned(buf: *const u8, len: usize, free: fn(*const u8, usize)) -> *mut ImageId {
    let id = ImageId::Owned(Buffer::Allocated(buf, len, free));
    Box::into_raw(Box::new(id))
}

#[no_mangle]
pub extern "C" fn image_load_png(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::PNG) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_jpg(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::JPEG) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_gif(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::GIF) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_webp(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::WEBP) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_ppm(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::PPM) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_bmp(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::BMP) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_ico(id: *const ImageId) -> *mut Image {
    let id = unsafe { &*id };
    Box::into_raw(match Image::load(id, image::ICO) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_load_multi_gif(id: *mut ImageId) -> *mut MultiImage {
    let id = unsafe { Box::from_raw(id) };
    Box::into_raw(match MultiImage::new(*id) {
        Ok(img) => Box::new(img),
        Err(_) => return ptr::null_mut(),
    })
}

#[no_mangle]
pub extern "C" fn image_get_frame(image: *const Image) -> *const image::Frame {
    unsafe { &(*image).frame }
}

#[no_mangle]
pub extern "C" fn image_get_frame_multi(image: *mut MultiImage, index: u32, delay: *mut u16) -> *const image::Frame {
    let image: &mut MultiImage = unsafe { &mut *image };
    let frame = match image.request_frame(index as usize) {
        Some(frame) => {
            frame as *const _
        },
        None => return ptr::null(),
    };
    unsafe { *delay = image.delay };
    frame
}

#[no_mangle]
pub extern "C" fn image_get_size(image: *const Image, width: *mut u32, height: *mut u32) {
    unsafe {
        let image: &Image = &*image;
        *width = image.frame.buffer().width();
        *height = image.frame.buffer().height();
    }
}

#[no_mangle]
pub extern "C" fn image_get_multi_size(image: *const MultiImage, width: *mut u32, height: *mut u32) {
    unsafe {
        let image: &MultiImage = &*image;
        *width = image.width;
        *height = image.height;
    }
}

#[no_mangle]
pub extern "C" fn image_get_frame_buffer(frame: *const image::Frame, buffer: *mut *const u8) {
    unsafe {
        let frame: &image::Frame = &*frame;
        *buffer = (&frame.buffer()[(0, 0)]) as *const image::Rgba<u8> as *const u8
    }
}

<|endoftext|>


<commit_before>extern crate thunderdome;

#[cfg(test)]
mod parser_tests {
    use thunderdome::parser::*;
    use thunderdome::steps::*;

    fn validate(q: &str) -> Option<ParsedGraphQuery> {
        let result = pre_parse(q);
        assert!(result.is_ok());
        result.ok()
    }

    #[test]
    fn global_graph_query() {
        validate("g.V");
    }

    #[test]
    fn vertex_query() {
        validate("g.v(1)");
        validate("g.v(1,2)");
        validate("g.v(1, 2)");
    }

    #[test]
    fn simple_step_test() {
        validate("g.v(1).outV()");
        let result = validate("g.v(1).outV().inE()").unwrap();
        assert_eq!(result.steps.len(), 2);

        let step1 = result.steps.get(0).unwrap();
        assert_eq!(step1.name, "outV".to_string());

        let step2 = result.steps.get(1).unwrap();
        assert_eq!(step2.name, "inE".to_string());
    }

    #[test]
    fn test_args() {
        let result = validate("g.v(1).outV('edge').has('age', 30)").unwrap();
        let step1 = result.steps.get(0).unwrap();
        assert_eq!(step1.name, "outV".to_string());
        // make sure the arg is edge.  should be a string and unquoted
        match step1.args.get(0).unwrap() {
            &Arg::String(ref x) if *x == "edge".to_string() => {},
            &Arg::String(ref x) => panic!("{}", x),
            x => { panic!("wrong type") }
        }
    }
    #[test]
    fn test_args_numbers() {
        // maybe a weird offset command?
        validate("g.V().limit(10, 20)");
        let result = validate("g.V().limit(10.0)").unwrap();
        match result.steps.get(1).unwrap().args.get(0).unwrap() {
            &Arg::Float(ref x) if *x == 10.0 => { },
            _ => { panic!("OH NOES")}
        }
    }
}
<commit_msg>removed step special case"<commit_after>extern crate thunderdome;

#[cfg(test)]
mod parser_tests {
    use thunderdome::parser::*;
    use thunderdome::steps::*;

    fn validate(q: &str) -> Option<ParsedGraphQuery> {
        let result = pre_parse(q);
        assert!(result.is_ok());
        result.ok()
    }

    #[test]
    fn global_graph_query() {
        validate("g.V()");
    }

    #[test]
    fn vertex_query() {
        validate("g.v(1)");
        validate("g.v(1,2)");
        validate("g.v(1, 2)");
    }

    #[test]
    fn simple_step_test() {
        validate("g.v(1).outV()");
        let result = validate("g.v(1).outV().inE()").unwrap();
        assert_eq!(result.steps.len(), 3);

        let step1 = result.steps.get(1).unwrap();
        assert_eq!(step1.name, "outV".to_string());

        let step2 = result.steps.get(2).unwrap();
        assert_eq!(step2.name, "inE".to_string());
    }

    #[test]
    fn test_args() {
        let result = validate("g.v(1).outV('edge').has('age', 30)").unwrap();
        let step1 = result.steps.get(1).unwrap();
        assert_eq!(step1.name, "outV".to_string());
        // make sure the arg is edge.  should be a string and unquoted
        match step1.args.get(0).unwrap() {
            &Arg::String(ref x) if *x == "edge".to_string() => {},
            &Arg::String(ref x) => panic!("{}", x),
            x => { panic!("wrong type") }
        }
    }
    #[test]
    fn test_args_numbers() {
        // maybe a weird offset command?
        validate("g.V().limit(10, 20)");
        let result = validate("g.V().limit(10.0)").unwrap();
        match result.steps.get(1).unwrap().args.get(0).unwrap() {
            &Arg::Float(ref x) if *x == 10.0 => { },
            _ => { panic!("OH NOES")}
        }
    }
}
<|endoftext|>


<commit_before>use std::f64;
use std::iter;
use std::slice;

use itertools::Itertools;

use bio::stats::logprobs::{self, LogProb};

#[derive(Debug, Clone)]
pub struct CDF<T: PartialOrd> {
    inner: Vec<(T, LogProb)>
}

impl<T: PartialOrd> CDF<T> {
    pub fn new(mut entries: Vec<(T, LogProb)>) -> Self {
        entries.sort_by(|&(ref a, _), &(ref b, _)| a.partial_cmp(b).unwrap());
        for i in 1..entries.len() {
            if entries[i].0 == entries[i - 1].0 {
                entries[i - 1].1 = logprobs::add(entries[i - 1].1, entries[i].1);
                entries.remove(i);
            }
            else {
                entries[i].1 = logprobs::add(entries[i - 1].1, entries[i].1);
            }
        }
        let mut cdf = CDF {
            inner: entries
        };

        if relative_eq!(cdf.total_prob(), 0.0) && cdf.total_prob() > 0.0 {
            cdf.inner.last_mut().unwrap().1 = 0.0;
        }

        cdf
    }

    pub fn sample(mut self, n: usize) -> Self {
        if self.inner.len() <= n {
            println!("not sampling");
            self
        }
        else {
            let s = self.inner.len() / (n - 1);
            let last = self.inner.pop().unwrap();
            let mut inner = self.inner.into_iter().step(s).collect_vec();
            inner.push(last);
            CDF {
                inner: inner
            }
        }
    }

    pub fn get(&self, value: &T) -> Option<LogProb> {
        if self.inner.is_empty() {
            None
        }
        else {
            Some(match self.inner.binary_search_by(|e| e.0.partial_cmp(value).unwrap()) {
                Ok(i) => self.inner[i].1,
                Err(i) => if i > 0 { self.inner[i - 1].1 } else { f64::NEG_INFINITY }
            })
        }
    }

    pub fn get_pmf(&self, value: &T) -> Option<LogProb> {
        if self.inner.is_empty() {
            None
        }
        else {
            Some(match self.inner.binary_search_by(|e| e.0.partial_cmp(value).unwrap()) {
                Ok(i) => if i > 0 { logprobs::sub(self.inner[i].1, self.inner[i - 1].1) } else { self.inner[0].1 },
                Err(i) => if i > 0 { self.inner[i - 1].1 } else { f64::NEG_INFINITY }
            })
        }
    }

    pub fn total_prob(&self) -> LogProb {
        self.inner.last().unwrap().1
    }

    pub fn len(&self) -> usize {
        self.inner.len()
    }
}

impl<T: Clone + PartialOrd> CDF<T> {
    pub fn iter_pmf(&self) -> CDFPMFIter<T> {
        fn cdf_to_pmf<G: Clone>(last_prob: &mut LogProb, e: &(G, LogProb)) -> Option<(G, LogProb)> {
            let &(ref value, cdf_prob) = e;
            let prob = logprobs::sub(cdf_prob, *last_prob);
            *last_prob = cdf_prob;
            Some((value.clone(), prob))
        }
        self.inner.iter().scan(f64::NEG_INFINITY, cdf_to_pmf)
    }
}

pub type CDFPMFIter<'a, T> = iter::Scan<slice::Iter<'a, (T, LogProb)>, LogProb, fn(&mut LogProb, &(T, LogProb)) -> Option<(T, LogProb)>>;

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

    use itertools::Itertools;

    #[test]
    fn test_cdf() {
        let mut pmf = Vec::new();
        for i in 0..10 {
            pmf.push((i, 0.1f64.ln()));
        }

        let cdf = CDF::new(pmf.clone());
        for (value, prob) in pmf {
            assert_ulps_eq!(prob, cdf.get_pmf(&value).unwrap(), epsilon = 0.0000000000001);
        }
        assert_relative_eq!(cdf.total_prob(), 1.0f64.ln());
        assert_relative_eq!(cdf.get(&1).unwrap(), 0.2f64.ln());
    }
}
<commit_msg>Use while loop for calculating CDF.<commit_after>use std::f64;
use std::iter;
use std::slice;

use itertools::Itertools;

use bio::stats::logprobs::{self, LogProb};

#[derive(Debug, Clone)]
pub struct CDF<T: PartialOrd> {
    inner: Vec<(T, LogProb)>
}

impl<T: PartialOrd> CDF<T> {
    pub fn new(mut entries: Vec<(T, LogProb)>) -> Self {
        entries.sort_by(|&(ref a, _), &(ref b, _)| a.partial_cmp(b).unwrap());
        let mut i = 1;
        while i < entries.len() {
            if entries[i].0 == entries[i - 1].0 {
                entries[i - 1].1 = logprobs::add(entries[i - 1].1, entries[i].1);
                entries.remove(i);
            }
            else {
                entries[i].1 = logprobs::add(entries[i - 1].1, entries[i].1);
            }
            i += 1;
        }
        let mut cdf = CDF {
            inner: entries
        };

        if relative_eq!(cdf.total_prob(), 0.0) && cdf.total_prob() > 0.0 {
            cdf.inner.last_mut().unwrap().1 = 0.0;
        }

        cdf
    }

    pub fn sample(mut self, n: usize) -> Self {
        if self.inner.len() <= n {
            println!("not sampling");
            self
        }
        else {
            let s = self.inner.len() / (n - 1);
            let last = self.inner.pop().unwrap();
            let mut inner = self.inner.into_iter().step(s).collect_vec();
            inner.push(last);
            CDF {
                inner: inner
            }
        }
    }

    pub fn get(&self, value: &T) -> Option<LogProb> {
        if self.inner.is_empty() {
            None
        }
        else {
            Some(match self.inner.binary_search_by(|e| e.0.partial_cmp(value).unwrap()) {
                Ok(i) => self.inner[i].1,
                Err(i) => if i > 0 { self.inner[i - 1].1 } else { f64::NEG_INFINITY }
            })
        }
    }

    pub fn get_pmf(&self, value: &T) -> Option<LogProb> {
        if self.inner.is_empty() {
            None
        }
        else {
            Some(match self.inner.binary_search_by(|e| e.0.partial_cmp(value).unwrap()) {
                Ok(i) => if i > 0 { logprobs::sub(self.inner[i].1, self.inner[i - 1].1) } else { self.inner[0].1 },
                Err(i) => if i > 0 { self.inner[i - 1].1 } else { f64::NEG_INFINITY }
            })
        }
    }

    pub fn total_prob(&self) -> LogProb {
        self.inner.last().unwrap().1
    }

    pub fn len(&self) -> usize {
        self.inner.len()
    }
}

impl<T: Clone + PartialOrd> CDF<T> {
    pub fn iter_pmf(&self) -> CDFPMFIter<T> {
        fn cdf_to_pmf<G: Clone>(last_prob: &mut LogProb, e: &(G, LogProb)) -> Option<(G, LogProb)> {
            let &(ref value, cdf_prob) = e;
            let prob = logprobs::sub(cdf_prob, *last_prob);
            *last_prob = cdf_prob;
            Some((value.clone(), prob))
        }
        self.inner.iter().scan(f64::NEG_INFINITY, cdf_to_pmf)
    }
}

pub type CDFPMFIter<'a, T> = iter::Scan<slice::Iter<'a, (T, LogProb)>, LogProb, fn(&mut LogProb, &(T, LogProb)) -> Option<(T, LogProb)>>;

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

    use itertools::Itertools;

    #[test]
    fn test_cdf() {
        let mut pmf = Vec::new();
        for i in 0..10 {
            pmf.push((i, 0.1f64.ln()));
        }

        let cdf = CDF::new(pmf.clone());
        for (value, prob) in pmf {
            assert_ulps_eq!(prob, cdf.get_pmf(&value).unwrap(), epsilon = 0.0000000000001);
        }
        assert_relative_eq!(cdf.total_prob(), 1.0f64.ln());
        assert_relative_eq!(cdf.get(&1).unwrap(), 0.2f64.ln());
    }
}
<|endoftext|>


<commit_before>use crate::Msg;
use chrono::{NaiveDate};
use seed::prelude::*;

struct NewsItem {
    pub content: Vec<Node<Msg>>,
    pub date: NaiveDate,
}

const NUM_NEWS_ITEMS :usize = 2;
fn get_news_items() -> [NewsItem; NUM_NEWS_ITEMS] {
    [
        NewsItem{
            content: vec![
                a!["Ethereum bounty contracts", attrs!{At::Class => "link", At::Href => "https://github.com/craigmayhew/ethereum-contracts"}],
                span!["have now been added for anyone that would like to try to push the boundaries of human knowledge.
                The first contract is a competition for the correct solution to a³+b³+c³ = 33.
                Tweet me if you need assistance using these contracts!"]
            ],
            date: NaiveDate::from_ymd(2019, 1, 22)
        },
        NewsItem{
            content: vec![
                div!["huh"]
            ],
            date: NaiveDate::from_ymd(2019, 1, 22)
        }
    ]
}

pub fn render() -> seed::dom_types::Node<Msg> {
    let news_items = get_news_items();
    let mut table_rows = vec![div![]; NUM_NEWS_ITEMS];
    for i in 0..news_items.len() {
        let news_item = &news_items[i];
        table_rows[i] = tr![
            td![news_item.date.to_string()],
            td![news_item.content.to_vec()]
        ];
    };

    div![
        h1!["News"],
        br![],
        br![],
        br![],
        table![table_rows]
    ]
}<commit_msg>Simplified home page to use raw html, it'll do for now!<commit_after>use crate::Msg;
use chrono::{NaiveDate};
use seed::prelude::*;

pub fn render() -> seed::dom_types::Node<Msg> {
    div![
        h1!["News"],
        br![],
        br![],
        br![],
        El::from_html("

Date	News

28th July 2019	bigprimes.net has been rewritten from the ground up using rust!

22nd January 2019	Ethereum bounty contracts have now been added for anyone that would like to try to push the boundaries of human knowledge. The first contract is a competition for the correct solution to a³+b³+c³ = 33. Tweet me if you need assistance using these contracts!

10th March 2018	Added torrents for the first million primes and first billion prime numbers.

12th November 2017	Site is now running on AWS Lambda, but can still fallback to regular VM hosting if ever needed. Site is now ~40% covered by unit tests.

13th November 2016	Site source code has been converted to PHP7 with Silex framework. Some methods have also been moved to cpp from PHP https://github.com/craigmayhew/bigprimes.net/

28th February 2014	You can now find the websites php source code here https://github.com/craigmayhew/bigprimes.net/

19th November 2011	Thank you to Yu Kwong Yiu Wilson for the donation!

13th July 2011	We are retiring the distributed computing client. Thank you all for your help and processing cycles.
        Watch this space for an open source GPU client coming soon...

10th February 2010	We have added a page that shows the sum of the digits of prime numbers. Click here

1st February 2010	Thanks to everyone for donating computer time, we are now upto 1.4 billion primes. We now also have a facebook group where you get news updates and show your support for the project!

28th September 2009	Thanks for all your help! We made it to one billion prime numbers! Please keep on donating processor time as we still have plenty of storage for the prime numbers. here. Our database is now more than double the size (300 million primes) and we've put in the capacity to keep growing. To view our current progress please visit the status page.

18th August 2009	It's been a while but we have been very busy. We've put together a distributed computing client written in javascript. If you wish to donate computing time and process some primes then please go here. Our database is now more than double the size (300 million primes) and we've put in the capacity to keep growing. To view our current progress please visit the status page.

17th July 2008	We've now added a Forum which can be found on the navigation links on the left.

14th July 2008	Someone named Kirk just emailed me to say the download links wern't working. I've now fixed this. Thanks Kirk!

4th July 2008	Added much faster code to the cruncher so that we can handle more of your page loads! Lots of little updates and some reorganizing of the site.

23rd June 2007	Added the Downloads section.

11th February 2007	Added the Fibonacci number archive containing the first 70331 Fibonacci numbers.

16th January 2007	Added the 44th Mersenne Prime number to the archive.

12th January 2007	The Archives are now more organized.

28th September 2005	We have managed to archive the first 100 million prime numbers.

20th May 2005	We have managed to archive the first 75 million prime numbers.

16th May 2005	We have managed to archive the first 50 million prime numbers.

14th May 2005	We have managed to archive the first 10 million prime numbers.

13th May 2005	We have managed to archive the first 1 million prime numbers.

"),
    ]
}<|endoftext|>


<commit_before>/// A prime generator object, using Eratosthenes' sieve.

#[warn(non_camel_case_types)]
#[warn(non_snake_case)]
#[warn(unnecessary_qualification)]
#[warn(non_uppercase_statics)]
#[warn(missing_doc)]

/// A prime generator object, using Eratosthenes' sieve.

//use std::iter::Iterator;
use std::ops::Index;
use std::slice;
use std::iter;

fn sqrt_floor(n : uint) -> uint {
    (n as f64).sqrt().floor() as uint
}

/// A prime generator, using the Sieve of Eratosthenes.
pub struct PrimeSet {
    lst : Vec<uint>
}

/// An iterator over generated primes. Created by PrimeSet::iter or
/// PrimeSet::generator
pub struct PrimeSetIter<'a> {
    p : &'a mut PrimeSet,
    n : uint,
    expand : bool
}

impl PrimeSet {
    /// A new prime penerator, primed with 2 and 3
    pub fn new() -> PrimeSet {
        PrimeSet{lst:vec!(2,3)}
    }

    /// Finds one more prime, and adds it to the list
    pub fn expand(&mut self) {
        let mut l = self.lst[self.lst.len()-1] + 2;
        let mut sql = sqrt_floor(l);
        let mut remainder = 0;
        loop {
            for &n in self.lst.iter() {
                remainder = l % n;
                if remainder == 0 || n > sql {
                    break;
                }
            };

            if remainder != 0 {
                self.lst.push(l);
                break;
            };

            l += 2;
            sql = sqrt_floor(l);
        }
    }

    /// Number of primes found so far
    pub fn len(&self) -> uint {
        self.lst.len()
    }

    /// Return all primes found so far as a slice
    pub fn list<'a>(&'a self) -> &'a [uint] {
        self.lst.as_slice()
    }

    /// Iterator over all primes not yet found
    pub fn generator<'a>(&'a mut self) -> PrimeSetIter<'a> {
        let myn = self.len();
        PrimeSetIter{p:self, n:myn, expand:true}
    }

    /// Iterator over all primes, starting with 2
    pub fn iter<'a>(&'a mut self) -> PrimeSetIter<'a> {
        PrimeSetIter{p:self, n:0, expand:true}
    }

    //~ pub fn iter_once(&'self mut self) -> PrimeSetIter<'self> {
        //~ PrimeSetIter{p:self, n:0, expand:false}
    //~ }

    /// Iterator over just the primes found so far
    pub fn iter_vec<'a>(&'a self) -> slice::Items<'a, uint> {
        self.lst.iter()
    }

    /// Find the next largest prime from a number
    pub fn find(&mut self, n: uint) -> (uint, uint) {
        while n > *(self.lst.last().unwrap_or(&0)){
            self.expand();
        }
        self.find_vec(n).unwrap()
    }

    /// Check if a number is prime
    pub fn is_prime(&mut self, n: uint) -> bool {
        if n <= 1 {return false;}
        if n == 2 {return true;} // otherwise we get 2 % 2 == 0!
        for m in self.iter() {
            if n % m == 0 {return false;};
            if m*m > n {return true;};
        }
        fail!("This iterator should not be empty.");
    }

    /// Find the next largest prime from a number, if it is within the already-found list
    /// Returns (idx, prime)
    /// Note that if n is prime, then the output will be (idx, n)
    pub fn find_vec(&self, n: uint) -> Option<(uint, uint)> {
        if n > *(self.lst.last().unwrap_or(&0)){ return None;}

        let mut base : uint = 0;
        let mut lim : uint = self.len();

        while lim != 0 {
            let ix = base + (lim >> 1);
            match self.lst[ix].cmp(&n) {
                Equal => return Some((ix, self.lst[ix])),
                Less => {
                    base = ix + 1;
                    lim -= 1;
                }
                Greater => ()
            }
            lim >>= 1;
        }
        return Some((base, self.lst[base]));
    }
}

impl Index<uint, uint> for PrimeSet {
    fn index(&self, index: &uint) -> &uint {
        self.lst.index(index)
    }
}

impl<'a> Iterator<uint> for PrimeSetIter<'a> {
    fn next(&mut self) -> Option<uint> {
        while self.n >= self.p.len(){
            match self.expand {
                true => self.p.expand(),
                false => return None
            }
        }
        self.n += 1;

        let m = self.p.lst[self.n-1];

        Some(m)
    }
}

/// Find the first factor (other than 1) of a number
fn firstfac(x: uint) -> uint {
    let m = ((x as f64).sqrt()).ceil() as uint;
    if x % 2 == 0 { return 2; };
    for n in iter::range_step(3, m + 1, 2) {
        if x % n == 0 { return n; };
    }
    return x;
}

/// Find all prime factors of a number
pub fn factors(x: uint) -> Vec<uint> {
    let mut lst: Vec<uint> = Vec::new();
    let mut curn = x;
    loop  {
        let m = firstfac(curn);
        lst = lst.append_one(m);
        if m == curn { break  } else { curn /= m };
    }
    return lst
}

/// Find all unique prime factors of a number
pub fn factors_uniq(x: uint) -> Vec<uint> {
    let mut lst: Vec<uint> = Vec::new();
    let mut curn = x;
    loop  {
        let m = firstfac(curn);
        lst = lst.append_one(m);
        if curn == m { break ; }
        while curn % m == 0 { curn /= m; }
        if curn == 1 { break ; }
    }
    return lst
}

/// Test whether a number is prime. Checks every odd number up to sqrt(n).
pub fn is_prime(n : uint) -> bool {
    if n <= 1 {return false;}
    firstfac(n) == n
}

#[test]
fn test_iter(){
    let mut pset = PrimeSet::new();
    let first_few = [2u,3,5,7,11,13,17,19,23];
    for (m, &n) in pset.iter().zip(first_few.iter()) {
        assert_eq!(m, n);
        break;
    }
}

#[test]
fn test_primes(){
    let mut pset = PrimeSet::new();

    // note: some are repeated, because the pset list grows as it goes

    assert!(!pset.is_prime(1));
    assert!(!is_prime(1));
    assert!(pset.is_prime(2));
    assert!(is_prime(2));
    assert!(pset.is_prime(13));
    assert!(is_prime(13));
    assert!(!pset.is_prime(45));
    assert!(!is_prime(45));
    assert!(!pset.is_prime(13*13));
    assert!(!is_prime(13*13));
    assert!(pset.is_prime(13));
    assert!(pset.is_prime(7));
    assert!(is_prime(7));
    assert!(!pset.is_prime(9));
    assert!(!is_prime(9));
    assert!(pset.is_prime(5));
    assert!(is_prime(5));
}
<commit_msg>Added get() function to primesieve<commit_after>/// A prime generator object, using Eratosthenes' sieve.

#[warn(non_camel_case_types)]
#[warn(non_snake_case)]
#[warn(unnecessary_qualification)]
#[warn(non_uppercase_statics)]
#[warn(missing_doc)]

/// A prime generator object, using Eratosthenes' sieve.

//use std::iter::Iterator;
use std::ops::Index;
use std::slice;
use std::iter;

fn sqrt_floor(n : uint) -> uint {
    (n as f64).sqrt().floor() as uint
}

/// A prime generator, using the Sieve of Eratosthenes.
pub struct PrimeSet {
    lst : Vec<uint>
}

/// An iterator over generated primes. Created by PrimeSet::iter or
/// PrimeSet::generator
pub struct PrimeSetIter<'a> {
    p : &'a mut PrimeSet,
    n : uint,
    expand : bool
}

impl PrimeSet {
    /// A new prime penerator, primed with 2 and 3
    pub fn new() -> PrimeSet {
        PrimeSet{lst:vec!(2,3)}
    }

    /// Finds one more prime, and adds it to the list
    pub fn expand(&mut self) {
        let mut l = self.lst[self.lst.len()-1] + 2;
        let mut sql = sqrt_floor(l);
        let mut remainder = 0;
        loop {
            for &n in self.lst.iter() {
                remainder = l % n;
                if remainder == 0 || n > sql {
                    break;
                }
            };

            if remainder != 0 {
                self.lst.push(l);
                break;
            };

            l += 2;
            sql = sqrt_floor(l);
        }
    }

    /// Number of primes found so far
    pub fn len(&self) -> uint {
        self.lst.len()
    }

    /// Return all primes found so far as a slice
    pub fn list<'a>(&'a self) -> &'a [uint] {
        self.lst.as_slice()
    }

    /// Iterator over all primes not yet found
    pub fn generator<'a>(&'a mut self) -> PrimeSetIter<'a> {
        let myn = self.len();
        PrimeSetIter{p:self, n:myn, expand:true}
    }

    /// Iterator over all primes, starting with 2
    pub fn iter<'a>(&'a mut self) -> PrimeSetIter<'a> {
        PrimeSetIter{p:self, n:0, expand:true}
    }

    //~ pub fn iter_once(&'self mut self) -> PrimeSetIter<'self> {
        //~ PrimeSetIter{p:self, n:0, expand:false}
    //~ }

    /// Iterator over just the primes found so far
    pub fn iter_vec<'a>(&'a self) -> slice::Items<'a, uint> {
        self.lst.iter()
    }

    /// Find the next largest prime from a number
    pub fn find(&mut self, n: uint) -> (uint, uint) {
        while n > *(self.lst.last().unwrap_or(&0)){
            self.expand();
        }
        self.find_vec(n).unwrap()
    }

    /// Check if a number is prime
    pub fn is_prime(&mut self, n: uint) -> bool {
        if n <= 1 {return false;}
        if n == 2 {return true;} // otherwise we get 2 % 2 == 0!
        for m in self.iter() {
            if n % m == 0 {return false;};
            if m*m > n {return true;};
        }
        fail!("This iterator should not be empty.");
    }

    /// Find the next largest prime from a number, if it is within the already-found list
    /// Returns (idx, prime)
    /// Note that if n is prime, then the output will be (idx, n)
    pub fn find_vec(&self, n: uint) -> Option<(uint, uint)> {
        if n > *(self.lst.last().unwrap_or(&0)){ return None;}

        let mut base : uint = 0;
        let mut lim : uint = self.len();

        while lim != 0 {
            let ix = base + (lim >> 1);
            match self.lst[ix].cmp(&n) {
                Equal => return Some((ix, self.lst[ix])),
                Less => {
                    base = ix + 1;
                    lim -= 1;
                }
                Greater => ()
            }
            lim >>= 1;
        }
        return Some((base, self.lst[base]));
    }

    pub fn get(&mut self, index : &uint) -> &uint {
		for _ in range(0, (*index as int) + 1 - (self.lst.len() as int)){
			self.expand();
		}
        self.lst.index(index)
	}

}

impl Index<uint, uint> for PrimeSet {
    fn index(&self, index: &uint) -> &uint {
        self.lst.index(index)
    }
}

impl<'a> Iterator<uint> for PrimeSetIter<'a> {
    fn next(&mut self) -> Option<uint> {
        while self.n >= self.p.len(){
            match self.expand {
                true => self.p.expand(),
                false => return None
            }
        }
        self.n += 1;

        let m = self.p.lst[self.n-1];

        Some(m)
    }
}

/// Find the first factor (other than 1) of a number
fn firstfac(x: uint) -> uint {
    let m = ((x as f64).sqrt()).ceil() as uint;
    if x % 2 == 0 { return 2; };
    for n in iter::range_step(3, m + 1, 2) {
        if x % n == 0 { return n; };
    }
    return x;
}

/// Find all prime factors of a number
pub fn factors(x: uint) -> Vec<uint> {
    let mut lst: Vec<uint> = Vec::new();
    let mut curn = x;
    loop  {
        let m = firstfac(curn);
        lst = lst.append_one(m);
        if m == curn { break  } else { curn /= m };
    }
    return lst
}

/// Find all unique prime factors of a number
pub fn factors_uniq(x: uint) -> Vec<uint> {
    let mut lst: Vec<uint> = Vec::new();
    let mut curn = x;
    loop  {
        let m = firstfac(curn);
        lst = lst.append_one(m);
        if curn == m { break ; }
        while curn % m == 0 { curn /= m; }
        if curn == 1 { break ; }
    }
    return lst
}

/// Test whether a number is prime. Checks every odd number up to sqrt(n).
pub fn is_prime(n : uint) -> bool {
    if n <= 1 {return false;}
    firstfac(n) == n
}

#[test]
fn test_iter(){
    let mut pset = PrimeSet::new();
    let first_few = [2u,3,5,7,11,13,17,19,23];
    for (m, &n) in pset.iter().zip(first_few.iter()) {
        assert_eq!(m, n);
        break;
    }
}

#[test]
fn test_primes(){
    let mut pset = PrimeSet::new();

    // note: some are repeated, because the pset list grows as it goes

    assert!(!pset.is_prime(1));
    assert!(!is_prime(1));
    assert!(pset.is_prime(2));
    assert!(is_prime(2));
    assert!(pset.is_prime(13));
    assert!(is_prime(13));
    assert!(!pset.is_prime(45));
    assert!(!is_prime(45));
    assert!(!pset.is_prime(13*13));
    assert!(!is_prime(13*13));
    assert!(pset.is_prime(13));
    assert!(pset.is_prime(7));
    assert!(is_prime(7));
    assert!(!pset.is_prime(9));
    assert!(!is_prime(9));
    assert!(pset.is_prime(5));
    assert!(is_prime(5));
}
<|endoftext|>


<commit_before>use std::ffi::CString;
use std::io;
use std::path::Path;
use std::marker::PhantomData;
use libc::{c_int, size_t, c_char};
use libc::c_void;
use crate::get_error;
use std::mem::transmute;

use crate::sys;

/// A structure that provides an abstract interface to stream I/O.
pub struct RWops<'a> {
    raw: *mut sys::SDL_RWops,
    _marker: PhantomData<&'a ()>
}

impl<'a> RWops<'a> {
    pub unsafe fn raw(&self) -> *mut sys::SDL_RWops { self.raw }

    pub unsafe fn from_ll<'b>(raw: *mut sys::SDL_RWops) -> RWops<'b> {
        RWops {
            raw,
            _marker: PhantomData
        }
    }

    /// Creates an SDL file stream.
    pub fn from_file<P: AsRef<Path>>(path: P, mode: &str) -> Result<RWops <'static>, String> {
        let raw = unsafe {
            let path_c = CString::new(path.as_ref().to_str().unwrap()).unwrap();
            let mode_c = CString::new(mode).unwrap();
            sys::SDL_RWFromFile(path_c.as_ptr() as *const c_char, mode_c.as_ptr() as *const c_char)
        };

        if raw.is_null() {
            Err(get_error())
        } else {
            Ok(RWops {
                raw,
                _marker: PhantomData
            })
        }
    }

    /// Prepares a read-only memory buffer for use with `RWops`.
    ///
    /// This method can only fail if the buffer size is zero.
    pub fn from_bytes(buf: &'a [u8]) -> Result<RWops <'a>, String> {
        let raw = unsafe {
            sys::SDL_RWFromConstMem(buf.as_ptr() as *const c_void, buf.len() as c_int)
        };

        if raw.is_null() {
            Err(get_error())
        } else {
            Ok(RWops {
                raw,
                _marker: PhantomData
            })
        }
    }

    /// Reads a `Read` object into a buffer and then passes it to `RWops.from_bytes`.
    ///
    /// The buffer must be provided to this function and must live as long as the
    /// `RWops`, but the `RWops` does not take ownership of it.
    pub fn from_read<T>(r: &mut T, buffer: &'a mut Vec<u8>) -> Result<RWops<'a>, String>
        where T: io::Read + Sized {
        match r.read_to_end(buffer) {
            Ok(_size) => RWops::from_bytes(buffer),
            Err(ioerror) => {
                let msg = format!("IO error: {}", ioerror);
                Err(msg)
            }
        }
    }

    /// Prepares a read-write memory buffer for use with `RWops`.
    ///
    /// This method can only fail if the buffer size is zero.
    pub fn from_bytes_mut(buf: &'a mut [u8]) -> Result<RWops <'a>, String> {
        let raw = unsafe {
            sys::SDL_RWFromMem(buf.as_ptr() as *mut c_void, buf.len() as c_int)
        };

        if raw.is_null() {
            Err(get_error())
        } else {
            Ok(RWops {
                raw,
                _marker: PhantomData
            })
        }
    }

    /// Gets the stream's total size in bytes.
    ///
    /// Returns `None` if the stream size can't be determined
    /// (either because it doesn't make sense for the stream type, or there was an error).
    pub fn len(&self) -> Option<usize> {
        let result = unsafe { ((*self.raw).size.unwrap())(self.raw) };

        match result {
            -1 => None,
            v => Some(v as usize)
        }
    }

    // Tells if the stream is empty
    pub fn is_empty(&self) -> bool {
        match self.len() {
            Some(s) => s == 0,
            None => true,
        }
    }
}

impl<'a> Drop for RWops<'a> {
    fn drop(&mut self) {
        let ret = unsafe { ((*self.raw).close.unwrap())(self.raw) };
        if ret != 0 {
            panic!(get_error());
        }
    }
}

impl<'a> io::Read for RWops<'a> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let out_len = buf.len() as size_t;
        // FIXME: it's better to use as_mut_ptr().
        // number of objects read, or 0 at error or end of file.
        let ret = unsafe {
            ((*self.raw).read.unwrap())(self.raw, buf.as_ptr() as *mut c_void, 1, out_len as u64)
        };
        Ok(ret as usize)
    }
}

impl<'a> io::Write for RWops<'a> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let in_len = buf.len() as size_t;
        let ret = unsafe {
            ((*self.raw).write.unwrap())(self.raw, buf.as_ptr() as *const c_void, 1, in_len as u64)
        };
        Ok(ret as usize)
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl<'a> io::Seek for RWops<'a> {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        // whence code is different from SeekStyle
        let (whence, offset) = match pos {
            io::SeekFrom::Start(pos) => (sys::RW_SEEK_SET, pos as i64),
            io::SeekFrom::End(pos) => (sys::RW_SEEK_END, pos),
            io::SeekFrom::Current(pos) => (sys::RW_SEEK_CUR, pos)
        };
        let ret = unsafe {
            ((*self.raw).seek.unwrap())(self.raw, offset, transmute(whence))
        };
        if ret == -1 {
            Err(io::Error::last_os_error())
        } else {
            Ok(ret as u64)
        }
    }
}
<commit_msg>solves #980<commit_after>use std::ffi::CString;
use std::io;
use std::path::Path;
use std::marker::PhantomData;
use libc::{c_int, size_t, c_char};
use libc::c_void;
use crate::get_error;
use std::mem::transmute;

use crate::sys;

/// A structure that provides an abstract interface to stream I/O.
pub struct RWops<'a> {
    raw: *mut sys::SDL_RWops,
    _marker: PhantomData<&'a ()>
}

impl<'a> RWops<'a> {
    pub unsafe fn raw(&self) -> *mut sys::SDL_RWops { self.raw }

    pub unsafe fn from_ll<'b>(raw: *mut sys::SDL_RWops) -> RWops<'b> {
        RWops {
            raw,
            _marker: PhantomData
        }
    }

    /// Creates an SDL file stream.
    pub fn from_file<P: AsRef<Path>>(path: P, mode: &str) -> Result<RWops <'static>, String> {
        let raw = unsafe {
            let path_c = CString::new(path.as_ref().to_str().unwrap()).unwrap();
            let mode_c = CString::new(mode).unwrap();
            sys::SDL_RWFromFile(path_c.as_ptr() as *const c_char, mode_c.as_ptr() as *const c_char)
        };

        if raw.is_null() {
            Err(get_error())
        } else {
            Ok(RWops {
                raw,
                _marker: PhantomData
            })
        }
    }

    /// Prepares a read-only memory buffer for use with `RWops`.
    ///
    /// This method can only fail if the buffer size is zero.
    pub fn from_bytes(buf: &'a [u8]) -> Result<RWops <'a>, String> {
        let raw = unsafe {
            sys::SDL_RWFromConstMem(buf.as_ptr() as *const c_void, buf.len() as c_int)
        };

        if raw.is_null() {
            Err(get_error())
        } else {
            Ok(RWops {
                raw,
                _marker: PhantomData
            })
        }
    }

    /// Reads a `Read` object into a buffer and then passes it to `RWops.from_bytes`.
    ///
    /// The buffer must be provided to this function and must live as long as the
    /// `RWops`, but the `RWops` does not take ownership of it.
    pub fn from_read<T>(r: &mut T, buffer: &'a mut Vec<u8>) -> Result<RWops<'a>, String>
        where T: io::Read + Sized {
        match r.read_to_end(buffer) {
            Ok(_size) => RWops::from_bytes(buffer),
            Err(ioerror) => {
                let msg = format!("IO error: {}", ioerror);
                Err(msg)
            }
        }
    }

    /// Prepares a read-write memory buffer for use with `RWops`.
    ///
    /// This method can only fail if the buffer size is zero.
    pub fn from_bytes_mut(buf: &'a mut [u8]) -> Result<RWops <'a>, String> {
        let raw = unsafe {
            sys::SDL_RWFromMem(buf.as_ptr() as *mut c_void, buf.len() as c_int)
        };

        if raw.is_null() {
            Err(get_error())
        } else {
            Ok(RWops {
                raw,
                _marker: PhantomData
            })
        }
    }

    /// Gets the stream's total size in bytes.
    ///
    /// Returns `None` if the stream size can't be determined
    /// (either because it doesn't make sense for the stream type, or there was an error).
    pub fn len(&self) -> Option<usize> {
        let result = unsafe { ((*self.raw).size.unwrap())(self.raw) };

        match result {
            -1 => None,
            v => Some(v as usize)
        }
    }

    // Tells if the stream is empty
    pub fn is_empty(&self) -> bool {
        match self.len() {
            Some(s) => s == 0,
            None => true,
        }
    }
}

impl<'a> Drop for RWops<'a> {
    fn drop(&mut self) {
        let ret = unsafe { ((*self.raw).close.unwrap())(self.raw) };
        if ret != 0 {
            panic!(get_error());
        }
    }
}

impl<'a> io::Read for RWops<'a> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let out_len = buf.len() as size_t;
        // FIXME: it's better to use as_mut_ptr().
        // number of objects read, or 0 at error or end of file.
        let ret = unsafe {
            ((*self.raw).read.unwrap())(self.raw, buf.as_ptr() as *mut c_void, 1, out_len as sys::size_t)
        };
        Ok(ret as usize)
    }
}

impl<'a> io::Write for RWops<'a> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let in_len = buf.len() as size_t;
        let ret = unsafe {
            ((*self.raw).write.unwrap())(self.raw, buf.as_ptr() as *const c_void, 1, in_len as sys::size_t)
        };
        Ok(ret as usize)
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl<'a> io::Seek for RWops<'a> {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        // whence code is different from SeekStyle
        let (whence, offset) = match pos {
            io::SeekFrom::Start(pos) => (sys::RW_SEEK_SET, pos as i64),
            io::SeekFrom::End(pos) => (sys::RW_SEEK_END, pos),
            io::SeekFrom::Current(pos) => (sys::RW_SEEK_CUR, pos)
        };
        let ret = unsafe {
            ((*self.raw).seek.unwrap())(self.raw, offset, transmute(whence))
        };
        if ret == -1 {
            Err(io::Error::last_os_error())
        } else {
            Ok(ret as u64)
        }
    }
}
<|endoftext|>


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

use std::mem;
use std::thread;
use std::thread::JoinHandle;
use std::sync::{Arc, Mutex};
use std::net::{TcpListener, TcpStream};
use std::sync::mpsc::{channel, Sender, Receiver};

pub use super::rustc_serialize::*;

use self::types::*;
use self::socket::Socket;
use self::eventloop::EventLoop;
use self::resources::ResourcePool;

pub mod types;
pub mod socket;
pub mod stats;

mod eventloop;
mod resources;
mod workerthread;

pub struct FpWrapper {
    fp: EventFunctionPtr
}

impl FpWrapper {
    pub fn new(fp: EventFunctionPtr) -> FpWrapper {
        FpWrapper {
            fp: fp
        }
    }

    pub fn run(&self, sockets: SocketList, socket: Socket, buffer: Vec<u8>) {
        (*self.fp)(sockets, socket, buffer)
    }
}

#[allow(dead_code)]
pub struct Server {
    /// Epoll event loop
    eloop_prox: EventLoop,
    /// Incoming connection listener
    conn_prox: JoinHandle<()>,
    /// On data receiver from event loop
    data_rx: Receiver<EventTuple>,
    /// Called when data is received from event loop
    fp_wrapper: Arc<FpWrapper>
}

impl Server {

    /// Creates a new server
    pub fn new(address: &str) -> Server {
        let conn_addr = address.to_string();

        // Communication channel for the event loop to bubble
        // up messages to the server receiver
        let (tx, rx): (Sender<EventTuple>, Receiver<EventTuple>) = channel();

        // Create the event loop
        let eloop = EventLoop::new(tx);

        // Channel for TcpListener to send new connections to EventLoop
        let eloop_tx = eloop.sender();

        // Start listening for incoming connections
        let listener = thread::Builder::new()
            .name("TcpListener".to_string())
            .spawn(move||{
                Server::listen(conn_addr, eloop_tx);
            }).unwrap();

        Server {
            conn_prox: listener,
            eloop_prox: eloop,
            data_rx: rx,
            fp_wrapper: Arc::new(FpWrapper::new(Box::new(Server::default_execute)))
        }
    }

    /// Listens for incoming connections and sends them to the event loop
    fn listen(address: String, eloop_tx: Sender<TcpStream>) {
        let listener = TcpListener::bind(&address[..]).unwrap();
        for stream in listener.incoming() {
            match stream {
                Ok(stream) => {
                    trace!("New connection received");
                    let _ = eloop_tx.send(stream);
                }
                Err(e) => {
                    warn!("Error encountered during TCP connection: {}", e);
                }
            }
        }
        drop(listener);
    }

    /// Registers the function to execute when data is received
    pub fn on_data_received(&mut self, execute: EventFunctionPtr) {
        trace!("registering on_data_received handler");
        self.fp_wrapper = Arc::new(FpWrapper::new(execute));
    }

    /// Starts the server listening to the event loop
    pub fn begin(&mut self) {
        trace!("server begin");

        // Setup server statistics
        let mut locked_data = Mutex::new(stats::GeneralData::new());
        stats::init(&mut locked_data);
        trace!("stats initialized");

        let mut r_pool = ResourcePool::new();
        loop {
            match self.data_rx.recv() {
                Ok((sockets, socket, buff)) => {
                    trace!("data received, sending to resource pool");
                    let mut fp_wrapper = self.fp_wrapper.clone();

                    // Request for server statistics
                    if buff.len() == 5 && buff[0] == 0x0D {
                        trace!("request for server statistics");
                        fp_wrapper = Arc::new(FpWrapper::new(Box::new(Server::request_for_server_stats)));
                    }

                    r_pool.run(fp_wrapper, sockets, socket, buff);
                }
                Err(e) => {
                    error!("Err(e) hit on event loop Receiver: {}", e);
                    break;
                }
            };
        }
    }

    /// Default execute function
    #[allow(unused_variables)]
    fn default_execute(sockets: SocketList, socket: Socket, buffer: Vec<u8>) {
        debug!("default data handler executed...?");
    }

    /// Request for server stats
    #[allow(unused_variables)]
    fn request_for_server_stats(sockets: SocketList, socket: Socket, buffer: Vec<u8>) {
        trace!("request_for_server_stats");

        let mut sec_interval;
        let u8_ptr = buffer.as_ptr();
        unsafe {
            let f32_ptr: *const f32 = mem::transmute(u8_ptr.offset(1));
            sec_interval = *f32_ptr;
        }

        match stats::as_serialized_buffer(sec_interval) {
            Ok(ref mut buf) => {
                trace!("Serialized ok, writing response");
                // Yeah, this is dumb...
                // FIXME - Find a way to accept a mutable reference to a socket, or
                // maybe go through and make the streams implement copy?
                let mut socket = socket.clone();
                let _ = socket.write(buf);
            }
            Err(_) => { }
        };
    }
}
<commit_msg>Debugging buffer length<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the
// terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not
// distributed with this file, You can
// obtain one at
// http://mozilla.org/MPL/2.0/.
//
// This Source Code Form is "Incompatible
// With Secondary Licenses", as defined by
// the Mozilla Public License, v. 2.0.

use std::mem;
use std::thread;
use std::thread::JoinHandle;
use std::sync::{Arc, Mutex};
use std::net::{TcpListener, TcpStream};
use std::sync::mpsc::{channel, Sender, Receiver};

pub use super::rustc_serialize::*;

use self::types::*;
use self::socket::Socket;
use self::eventloop::EventLoop;
use self::resources::ResourcePool;

pub mod types;
pub mod socket;
pub mod stats;

mod eventloop;
mod resources;
mod workerthread;

pub struct FpWrapper {
    fp: EventFunctionPtr
}

impl FpWrapper {
    pub fn new(fp: EventFunctionPtr) -> FpWrapper {
        FpWrapper {
            fp: fp
        }
    }

    pub fn run(&self, sockets: SocketList, socket: Socket, buffer: Vec<u8>) {
        (*self.fp)(sockets, socket, buffer)
    }
}

#[allow(dead_code)]
pub struct Server {
    /// Epoll event loop
    eloop_prox: EventLoop,
    /// Incoming connection listener
    conn_prox: JoinHandle<()>,
    /// On data receiver from event loop
    data_rx: Receiver<EventTuple>,
    /// Called when data is received from event loop
    fp_wrapper: Arc<FpWrapper>
}

impl Server {

    /// Creates a new server
    pub fn new(address: &str) -> Server {
        let conn_addr = address.to_string();

        // Communication channel for the event loop to bubble
        // up messages to the server receiver
        let (tx, rx): (Sender<EventTuple>, Receiver<EventTuple>) = channel();

        // Create the event loop
        let eloop = EventLoop::new(tx);

        // Channel for TcpListener to send new connections to EventLoop
        let eloop_tx = eloop.sender();

        // Start listening for incoming connections
        let listener = thread::Builder::new()
            .name("TcpListener".to_string())
            .spawn(move||{
                Server::listen(conn_addr, eloop_tx);
            }).unwrap();

        Server {
            conn_prox: listener,
            eloop_prox: eloop,
            data_rx: rx,
            fp_wrapper: Arc::new(FpWrapper::new(Box::new(Server::default_execute)))
        }
    }

    /// Listens for incoming connections and sends them to the event loop
    fn listen(address: String, eloop_tx: Sender<TcpStream>) {
        let listener = TcpListener::bind(&address[..]).unwrap();
        for stream in listener.incoming() {
            match stream {
                Ok(stream) => {
                    trace!("New connection received");
                    let _ = eloop_tx.send(stream);
                }
                Err(e) => {
                    warn!("Error encountered during TCP connection: {}", e);
                }
            }
        }
        drop(listener);
    }

    /// Registers the function to execute when data is received
    pub fn on_data_received(&mut self, execute: EventFunctionPtr) {
        trace!("registering on_data_received handler");
        self.fp_wrapper = Arc::new(FpWrapper::new(execute));
    }

    /// Starts the server listening to the event loop
    pub fn begin(&mut self) {
        trace!("server begin");

        // Setup server statistics
        let mut locked_data = Mutex::new(stats::GeneralData::new());
        stats::init(&mut locked_data);
        trace!("stats initialized");

        let mut r_pool = ResourcePool::new();
        loop {
            match self.data_rx.recv() {
                Ok((sockets, socket, buff)) => {
                    trace!("data received, sending to resource pool");
                    let mut fp_wrapper = self.fp_wrapper.clone();

                    // Request for server statistics
                    if buff.len() == 5 && buff[0] == 0x0D {
                        trace!("request for server statistics");
                        fp_wrapper = Arc::new(FpWrapper::new(Box::new(Server::request_for_server_stats)));
                    }

                    r_pool.run(fp_wrapper, sockets, socket, buff);
                }
                Err(e) => {
                    error!("Err(e) hit on event loop Receiver: {}", e);
                    break;
                }
            };
        }
    }

    /// Default execute function
    #[allow(unused_variables)]
    fn default_execute(sockets: SocketList, socket: Socket, buffer: Vec<u8>) {
        debug!("default data handler executed...?");
    }

    /// Request for server stats
    #[allow(unused_variables)]
    fn request_for_server_stats(sockets: SocketList, socket: Socket, buffer: Vec<u8>) {
        trace!("request_for_server_stats");

        let mut sec_interval;
        let u8_ptr = buffer.as_ptr();
        unsafe {
            let f32_ptr: *const f32 = mem::transmute(u8_ptr.offset(1));
            sec_interval = *f32_ptr;
        }

        match stats::as_serialized_buffer(sec_interval) {
            Ok(ref mut buf) => {
                trace!("Writing response, buf.len(): {}", buf.len());
                // Yeah, this is dumb...
                // FIXME - Find a way to accept a mutable reference to a socket, or
                // maybe go through and make the streams implement copy?
                let mut socket = socket.clone();
                let _ = socket.write(buf);
            }
            Err(_) => { }
        };
    }
}
<|endoftext|>