<commit_before>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! An efficient, low-level, bindless graphics API for Rust. See [the
//! blog](http://gfx-rs.github.io/) for explanations and annotated examples.

#![feature(alloc, core, libc, unsafe_destructor)]

extern crate alloc;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate log;
extern crate libc;
extern crate draw_state;

/// public re-exported traits
pub mod traits {
    pub use device::{Device, Factory};
    pub use render::ext::device::DeviceExt;
    pub use render::ext::factory::FactoryExt;
    pub use render::mesh::ToSlice;
}

// draw state re-exports
pub use draw_state::{DrawState, BlendPreset};

// public re-exports
pub use render::{Renderer, DrawError};
pub use render::batch;
pub use render::ext::device::Graphics;
pub use render::ext::shade::{ShaderSource, ProgramError};
pub use render::mesh::{Attribute, Mesh, VertexFormat};
pub use render::mesh::Error as MeshError;
pub use render::mesh::{Slice, ToSlice, SliceKind};
pub use render::shade;
pub use render::target::{Frame, Plane};
pub use render::ParamStorage;
pub use device::{Device, SubmitInfo, Factory, Resources};
pub use device::{attrib, tex};
pub use device::as_byte_slice;
pub use device::{BufferRole, BufferInfo, BufferUsage};
pub use device::{VertexCount, InstanceCount};
pub use device::PrimitiveType;
pub use device::draw::CommandBuffer;
pub use device::shade::{ProgramInfo, UniformValue};
pub use draw_state::target::*;
pub use draw_state::state;

pub use device::handle::Buffer as BufferHandle;
pub use device::handle::RawBuffer as RawBufferHandle;
pub use device::handle::Shader as ShaderHandle;
pub use device::handle::Program as ProgramHandle;
pub use device::handle::Surface as SurfaceHandle;
pub use device::handle::Texture as TextureHandle;
pub use device::handle::Sampler as SamplerHandle;

pub mod render;
pub mod device;
<commit_msg>Reexporting IndexBufferHandle<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! An efficient, low-level, bindless graphics API for Rust. See [the
//! blog](http://gfx-rs.github.io/) for explanations and annotated examples.

#![feature(alloc, core, libc, unsafe_destructor)]

extern crate alloc;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate log;
extern crate libc;
extern crate draw_state;

/// public re-exported traits
pub mod traits {
    pub use device::{Device, Factory};
    pub use render::ext::device::DeviceExt;
    pub use render::ext::factory::FactoryExt;
    pub use render::mesh::ToSlice;
}

// draw state re-exports
pub use draw_state::{DrawState, BlendPreset};

// public re-exports
pub use render::{Renderer, DrawError};
pub use render::batch;
pub use render::ext::device::Graphics;
pub use render::ext::shade::{ShaderSource, ProgramError};
pub use render::mesh::{Attribute, Mesh, VertexFormat};
pub use render::mesh::Error as MeshError;
pub use render::mesh::{Slice, ToSlice, SliceKind};
pub use render::shade;
pub use render::target::{Frame, Plane};
pub use render::ParamStorage;
pub use device::{Device, SubmitInfo, Factory, Resources};
pub use device::{attrib, tex};
pub use device::as_byte_slice;
pub use device::{BufferRole, BufferInfo, BufferUsage};
pub use device::{VertexCount, InstanceCount};
pub use device::PrimitiveType;
pub use device::draw::CommandBuffer;
pub use device::shade::{ProgramInfo, UniformValue};
pub use draw_state::target::*;
pub use draw_state::state;

pub use device::handle::Buffer as BufferHandle;
pub use device::handle::IndexBuffer as IndexBufferHandle;
pub use device::handle::RawBuffer as RawBufferHandle;
pub use device::handle::Shader as ShaderHandle;
pub use device::handle::Program as ProgramHandle;
pub use device::handle::Surface as SurfaceHandle;
pub use device::handle::Texture as TextureHandle;
pub use device::handle::Sampler as SamplerHandle;

pub mod render;
pub mod device;
<|endoftext|>


<commit_before>//! This library can be used to acquire oauth2.0 authentication for services.
//!
//! For your application to use this library, you will have to obtain an application
//! id and secret by
//! [following this guide](https://developers.google.com/youtube/registering_an_application) (for
//! Google services) respectively the documentation of the API provider you want to connect to.
//!
//! # Device Flow Usage
//! As the `DeviceFlow` involves polling, the `DeviceFlowHelper` should be used
//! as means to adhere to the protocol, and remain resilient to all kinds of errors
//! that can occour on the way.
//!
//! # Service account "flow"
//! When using service account credentials, no user interaction is required. The access token
//! can be obtained automatically using the private key of the client (which you can download
//! from the API provider). See `examples/service_account/` for an example on how to use service
//! account credentials. See
//! [developers.google.com](https://developers.google.com/identity/protocols/OAuth2ServiceAccount)
//! for a detailed description of the protocol. This crate implements OAuth for Service Accounts
//! based on the Google APIs; it may or may not work with other providers.
//!
//! # Installed Flow Usage
//! The `InstalledFlow` involves showing a URL to the user (or opening it in a browser)
//! and then either prompting the user to enter a displayed code, or make the authorizing
//! website redirect to a web server spun up by this library and running on localhost.
//!
//! In order to use the interactive method, use the `InstalledInteractive` `FlowType`;
//! for the redirect method, use `InstalledRedirect`, with the port number to let the
//! server listen on.
//!
//! You can implement your own `AuthenticatorDelegate` in order to customize the flow;
//! the `InstalledFlow` uses the `present_user_url` method.
//!
//! The returned `Token` is stored permanently in the given token storage in order to
//! authorize future API requests to the same scopes.
//!
//! ```test_harness,no_run
//! #[macro_use]
//! extern crate serde_derive;
//!
//! extern crate hyper;
//! extern crate yup_oauth2 as oauth2;
//! extern crate serde;
//! extern crate serde_json;
//!
//! use oauth2::{Authenticator, DefaultAuthenticatorDelegate, PollInformation, ConsoleApplicationSecret, MemoryStorage, GetToken};
//! use serde_json as json;
//! use std::default::Default;
//! # const SECRET: &'static str = "{\"installed\":{\"auth_uri\":\"https://accounts.google.com/o/oauth2/auth\",\"client_secret\":\"UqkDJd5RFwnHoiG5x5Rub8SI\",\"token_uri\":\"https://accounts.google.com/o/oauth2/token\",\"client_email\":\"\",\"redirect_uris\":[\"urn:ietf:wg:oauth:2.0:oob\",\"oob\"],\"client_x509_cert_url\":\"\",\"client_id\":\"14070749909-vgip2f1okm7bkvajhi9jugan6126io9v.apps.googleusercontent.com\",\"auth_provider_x509_cert_url\":\"https://www.googleapis.com/oauth2/v1/certs\"}}";
//!
//! # #[test] fn device() {
//! let secret = json::from_str::<ConsoleApplicationSecret>(SECRET).unwrap().installed.unwrap();
//! let res = Authenticator::new(&secret, DefaultAuthenticatorDelegate,
//!                         hyper::Client::new(),
//!                         <MemoryStorage as Default>::default(), None)
//!                         .token(&["https://www.googleapis.com/auth/youtube.upload"]);
//! match res {
//!     Ok(t) => {
//!     // now you can use t.access_token to authenticate API calls within your
//!     // given scopes. It will not be valid forever, but Authenticator will automatically
//!     // refresh the token for you.
//!     },
//!     Err(err) => println!("Failed to acquire token: {}", err),
//! }
//! # }
//! ```
//!
#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;

extern crate base64;
extern crate chrono;
extern crate hyper;
extern crate hyper_rustls;
extern crate rustls;

#[cfg(test)]
extern crate log;
#[cfg(test)]
extern crate yup_hyper_mock;
extern crate url;
extern crate itertools;

mod authenticator;
mod authenticator_delegate;
mod device;
mod helper;
mod installed;
mod refresh;
mod service_account;
mod storage;
mod types;

pub use device::{GOOGLE_DEVICE_CODE_URL, DeviceFlow};
pub use refresh::{RefreshFlow, RefreshResult};
pub use types::{Token, FlowType, ApplicationSecret, ConsoleApplicationSecret, Scheme, TokenType};
pub use installed::{InstalledFlow, InstalledFlowReturnMethod};
pub use storage::{TokenStorage, NullStorage, MemoryStorage, DiskTokenStorage};
pub use authenticator::{Authenticator, Retry, GetToken};
pub use authenticator_delegate::{AuthenticatorDelegate, DefaultAuthenticatorDelegate, PollError,
                                 PollInformation};
pub use helper::*;
pub use service_account::*;

<commit_msg>docs: update the example to use the hyper tls connector<commit_after>//! This library can be used to acquire oauth2.0 authentication for services.
//!
//! For your application to use this library, you will have to obtain an application
//! id and secret by
//! [following this guide](https://developers.google.com/youtube/registering_an_application) (for
//! Google services) respectively the documentation of the API provider you want to connect to.
//!
//! # Device Flow Usage
//! As the `DeviceFlow` involves polling, the `DeviceFlowHelper` should be used
//! as means to adhere to the protocol, and remain resilient to all kinds of errors
//! that can occour on the way.
//!
//! # Service account "flow"
//! When using service account credentials, no user interaction is required. The access token
//! can be obtained automatically using the private key of the client (which you can download
//! from the API provider). See `examples/service_account/` for an example on how to use service
//! account credentials. See
//! [developers.google.com](https://developers.google.com/identity/protocols/OAuth2ServiceAccount)
//! for a detailed description of the protocol. This crate implements OAuth for Service Accounts
//! based on the Google APIs; it may or may not work with other providers.
//!
//! # Installed Flow Usage
//! The `InstalledFlow` involves showing a URL to the user (or opening it in a browser)
//! and then either prompting the user to enter a displayed code, or make the authorizing
//! website redirect to a web server spun up by this library and running on localhost.
//!
//! In order to use the interactive method, use the `InstalledInteractive` `FlowType`;
//! for the redirect method, use `InstalledRedirect`, with the port number to let the
//! server listen on.
//!
//! You can implement your own `AuthenticatorDelegate` in order to customize the flow;
//! the `InstalledFlow` uses the `present_user_url` method.
//!
//! The returned `Token` is stored permanently in the given token storage in order to
//! authorize future API requests to the same scopes.
//!
//! ```test_harness,no_run
//! #[macro_use]
//! extern crate serde_derive;
//!
//! extern crate hyper;
//! extern crate hyper_rustls;
//! extern crate yup_oauth2 as oauth2;
//! extern crate serde;
//! extern crate serde_json;
//!
//! use oauth2::{Authenticator, DefaultAuthenticatorDelegate, PollInformation, ConsoleApplicationSecret, MemoryStorage, GetToken};
//! use serde_json as json;
//! use std::default::Default;
//! use hyper::{Client, net::HttpsConnector};
//! use hyper_rustls::TlsClient;
//! # const SECRET: &'static str = "{\"installed\":{\"auth_uri\":\"https://accounts.google.com/o/oauth2/auth\",\"client_secret\":\"UqkDJd5RFwnHoiG5x5Rub8SI\",\"token_uri\":\"https://accounts.google.com/o/oauth2/token\",\"client_email\":\"\",\"redirect_uris\":[\"urn:ietf:wg:oauth:2.0:oob\",\"oob\"],\"client_x509_cert_url\":\"\",\"client_id\":\"14070749909-vgip2f1okm7bkvajhi9jugan6126io9v.apps.googleusercontent.com\",\"auth_provider_x509_cert_url\":\"https://www.googleapis.com/oauth2/v1/certs\"}}";
//!
//! # #[test] fn device() {
//! let secret = json::from_str::<ConsoleApplicationSecret>(SECRET).unwrap().installed.unwrap();
//! let res = Authenticator::new(&secret, DefaultAuthenticatorDelegate,
//!                         Client::with_connector(HttpsConnector::new(TlsClient::new())),
//!                         <MemoryStorage as Default>::default(), None)
//!                         .token(&["https://www.googleapis.com/auth/youtube.upload"]);
//! match res {
//!     Ok(t) => {
//!     // now you can use t.access_token to authenticate API calls within your
//!     // given scopes. It will not be valid forever, but Authenticator will automatically
//!     // refresh the token for you.
//!     },
//!     Err(err) => println!("Failed to acquire token: {}", err),
//! }
//! # }
//! ```
//!
#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;

extern crate base64;
extern crate chrono;
extern crate hyper;
extern crate hyper_rustls;
extern crate rustls;

#[cfg(test)]
extern crate log;
#[cfg(test)]
extern crate yup_hyper_mock;
extern crate url;
extern crate itertools;

mod authenticator;
mod authenticator_delegate;
mod device;
mod helper;
mod installed;
mod refresh;
mod service_account;
mod storage;
mod types;

pub use device::{GOOGLE_DEVICE_CODE_URL, DeviceFlow};
pub use refresh::{RefreshFlow, RefreshResult};
pub use types::{Token, FlowType, ApplicationSecret, ConsoleApplicationSecret, Scheme, TokenType};
pub use installed::{InstalledFlow, InstalledFlowReturnMethod};
pub use storage::{TokenStorage, NullStorage, MemoryStorage, DiskTokenStorage};
pub use authenticator::{Authenticator, Retry, GetToken};
pub use authenticator_delegate::{AuthenticatorDelegate, DefaultAuthenticatorDelegate, PollError,
                                 PollInformation};
pub use helper::*;
pub use service_account::*;

<|endoftext|>


<commit_before>#![crate_name = "memcache"]
#![crate_type = "rlib"]

extern crate hash_ring;

use std::io::Error;
use std::convert::From;

#[derive(Debug)]
pub enum MemcacheError {
    InternalIoError(Error),
    ServerError
}

impl From<Error> for MemcacheError {
    fn from(err: Error) -> MemcacheError {
        MemcacheError::InternalIoError(err)
    }
}

pub type MemcacheResult<T> = Result<T, MemcacheError>;

// Trait defining Memcache protocol both for multi server connection using `Client` as
// well as single connection using `Connection`.
trait Commands {
    fn flush(&mut self) -> MemcacheResult<()>;
    fn delete(&mut self, key: &str) -> MemcacheResult<bool>;
    fn get(&mut self, key: &str) -> MemcacheResult<Option<(Vec<u8>, u16)>>;
    fn set(&mut self, key: &str, value: &[u8], exptime: isize, flags: u16) -> MemcacheResult<bool>;
    fn incr(&mut self, key: &str, value: u64) -> MemcacheResult<Option<(isize)>>;
    fn decr(&mut self, key: &str, value: u64) -> MemcacheResult<Option<(isize)>>;
}

mod connection;
mod client;
<commit_msg>add buf_stream feature to the crate<commit_after>#![feature(buf_stream)]

#![crate_name = "memcache"]
#![crate_type = "rlib"]

extern crate hash_ring;

use std::io::Error;
use std::convert::From;

#[derive(Debug)]
pub enum MemcacheError {
    InternalIoError(Error),
    ServerError
}

impl From<Error> for MemcacheError {
    fn from(err: Error) -> MemcacheError {
        MemcacheError::InternalIoError(err)
    }
}

pub type MemcacheResult<T> = Result<T, MemcacheError>;

// Trait defining Memcache protocol both for multi server connection using `Client` as
// well as single connection using `Connection`.
trait Commands {
    fn flush(&mut self) -> MemcacheResult<()>;
    fn delete(&mut self, key: &str) -> MemcacheResult<bool>;
    fn get(&mut self, key: &str) -> MemcacheResult<Option<(Vec<u8>, u16)>>;
    fn set(&mut self, key: &str, value: &[u8], exptime: isize, flags: u16) -> MemcacheResult<bool>;
    fn incr(&mut self, key: &str, value: u64) -> MemcacheResult<Option<(isize)>>;
    fn decr(&mut self, key: &str, value: u64) -> MemcacheResult<Option<(isize)>>;
}

mod connection;
mod client;
<|endoftext|>


<commit_before>// Copyright (c) 2017 FaultyRAM
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT
// or http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! A helper library for Google Code Jam solutions.
//!
//! In the Google Code Jam, solving a problem typically requires the following steps:
//!
//! 1. Open an input file containing a series of test cases.
//! 2. Open an output file where solutions will be written.
//! 2. Read the first line from the input file, which consists solely of an unsigned integer
//!    specifying the number of test cases in the input file.
//! 3. For each test case, perform the following steps:
//!    1. Obtain the corresponding test data by reading one or more lines from the input file (it
//!       may be a fixed number, or specified within the test data itself).
//!    2. Perform some logic using the test data, in order to obtain a set of results.
//!    3. Write the string `"Case #N:"` (where `N` is the number of completed test cases) followed
//!       by the results obtained in the previous step, formatted as the problem requires.
//!
//! Writing code to handle all of the above is tedious and time-consuming, in a situation where
//! every microsecond counts. `gcj-helper` is designed to handle the boilerplate, so you can focus
//! on writing solutions instead.
//!
//! # Example
//!
//! ```rust
//! use gcj_helper::TestEngine;
//! use std::io::Write;
//! TestEngine::new("./foo.in", "./foo.out").run(|io_helper| {
//!     let line = io_helper.read_line();
//!     writeln!(io_helper, " {}", line).unwrap(); // `"Case #N: foo\n"`
//! });
//! ```

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", forbid(clippy))]
#![cfg_attr(feature = "clippy", forbid(clippy_internal))]
#![cfg_attr(feature = "clippy", forbid(clippy_pedantic))]
#![cfg_attr(feature = "clippy", forbid(clippy_restrictions))]
#![forbid(warnings)]
#![forbid(box_pointers)]
#![forbid(fat_ptr_transmutes)]
#![forbid(missing_copy_implementations)]
#![forbid(missing_debug_implementations)]
#![forbid(missing_docs)]
#![forbid(trivial_casts)]
#![forbid(trivial_numeric_casts)]
#![forbid(unsafe_code)]
#![forbid(unused_extern_crates)]
#![forbid(unused_import_braces)]
#![deny(unused_qualifications)]
#![forbid(unused_results)]
#![forbid(variant_size_differences)]

use std::{env, io};
use std::fmt::Arguments;
use std::fs::{File, OpenOptions};
use std::io::{BufRead, BufReader, LineWriter, Lines, Write};
use std::ops::{Add, AddAssign};
use std::path::Path;

/// Facilitates the execution of problem solving code.
///
/// In order to handle test cases, you need to create a new `TestEngine`, then call
/// `TestEngine::run()`, which accepts an `Fn(&mut IoHelper)` that is called once per test case.
/// Creating a `TestEngine` is cheap; no files are opened until you call `TestEngine::run()`.
#[derive(Debug)]
pub struct TestEngine<I: AsRef<Path>, O: AsRef<Path>> {
    /// A path to an input file.
    input_file_path: I,
    /// A path to an output file.
    output_file_path: O,
}

/// Provides I/O support for problem solving code.
///
/// The `IoHelper` type allows reading from an input file and writing to an output file.
/// `IoHelper::read_line()` reads the next line of text from the input file, and `io::Write` is
/// implemented for `IoHelper` such that data is written to the output file.
#[derive(Debug)]
pub struct IoHelper {
    /// An iterator over the lines of an input file.
    input: Lines<BufReader<File>>,
    /// An output file.
    output: LineWriter<File>,
    /// The current test case.
    current_case: usize,
    /// The total number of test cases to handle.
    case_count: usize,
}

impl<I: AsRef<Path>, O: AsRef<Path>> TestEngine<I, O> {
    /// Creates a new test engine using the specified input and output file paths.
    ///
    /// Calling this method is cheap; no files are opened until `TestEngine::run()` is called.
    pub fn new(input_file_path: I, output_file_path: O) -> TestEngine<I, O> {
        TestEngine {
            input_file_path: input_file_path,
            output_file_path: output_file_path,
        }
    }

    /// Consumes the test engine, calling a closure once for each test case.
    pub fn run<F: Fn(&mut IoHelper)>(self, f: F) {
        let io_helper = IoHelper::new(self);
        io_helper.run(f);
    }
}

impl TestEngine<String, String> {
    /// Creates a new test engine using input and output file paths obtained from command line
    /// arguments.
    ///
    /// Calling this method is cheap; no files are opened until `TestEngine::run()` is called.
    ///
    /// # Panics
    ///
    /// This method panics if either the input file path or output file path is missing.
    pub fn from_args() -> TestEngine<String, String> {
        let mut args = env::args();
        let input_file_path = args.nth(1).expect("input file path not specified");
        let output_file_path = args.next().expect("output file path not specified");
        Self::new(input_file_path, output_file_path)
    }
}

impl Default for TestEngine<String, String> {
    fn default() -> TestEngine<String, String> {
        Self::from_args()
    }
}

impl IoHelper {
    /// Reads a line of text from the input file.
    ///
    /// # Panics
    ///
    /// This method panics if reading fails for any reason, such as having reached the end of the
    /// input file.
    pub fn read_line(&mut self) -> String {
        self.input
            .next()
            .expect("reached end of file")
            .expect("could not read from input file")
    }

    /// Returns the current test case number.
    pub fn current_case(&self) -> usize {
        self.current_case
    }

    /// Returns the total number of test cases in the input file.
    pub fn case_count(&self) -> usize {
        self.case_count
    }

    /// Creates a new I/O helper.
    fn new<I: AsRef<Path>, O: AsRef<Path>>(test_engine: TestEngine<I, O>) -> IoHelper {
        let mut io_helper = IoHelper {
            input: Self::open_input_file(test_engine.input_file_path),
            output: Self::open_output_file(test_engine.output_file_path),
            current_case: 1,
            case_count: 0,
        };
        io_helper.init_test_case_count();
        io_helper
    }

    /// Consumes the I/O helper, calling a closure once for each test case.
    fn run<F: Fn(&mut IoHelper)>(mut self, f: F) {
        while self.current_case <= self.case_count {
            let current_case_s = self.current_case_string();
            let _ = self.write(current_case_s.as_bytes())
                .expect("could not write current test case string to output file");
            (f)(&mut self);
            self.current_case.add_assign(1);
        }
    }

    /// Creates an iterator over the lines of an input file.
    fn open_input_file<P: AsRef<Path>>(path: P) -> Lines<BufReader<File>> {
        BufReader::new(OpenOptions::new()
            .read(true)
            .open(path)
            .expect("could not open input file for reading")).lines()
    }

    /// Creates an output file.
    fn open_output_file<P: AsRef<Path>>(path: P) -> LineWriter<File> {
        LineWriter::new(OpenOptions::new()
                            .write(true)
                            .truncate(true)
                            .create(true)
                            .open(path)
                            .expect("could not open output file for writing"))
    }

    /// Obtains the number of test cases to examine from the input file.
    fn init_test_case_count(&mut self) {
        let line = self.read_line();
        self.case_count =
            usize::from_str_radix(&line, 10).expect("could not parse test case count");
    }

    /// Creates a string identifying the current test case.
    fn current_case_string(&mut self) -> String {
        let case_str = "Case #";
        let case_s = self.current_case.to_string();
        let case_str_colon = ":";
        let mut out = String::with_capacity(0);
        out.reserve_exact(case_str.len().add(case_s.len()).add(case_str_colon.len()));
        out.push_str(case_str);
        out.push_str(&case_s);
        out.push_str(case_str_colon);
        out
    }
}

impl Write for IoHelper {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.output.write(buf)
    }

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

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.output.write_all(buf)
    }

    fn write_fmt(&mut self, fmt: Arguments) -> io::Result<()> {
        self.output.write_fmt(fmt)
    }
}
<commit_msg>Fixed continuous integration build failure<commit_after>// Copyright (c) 2017 FaultyRAM
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT
// or http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! A helper library for Google Code Jam solutions.
//!
//! In the Google Code Jam, solving a problem typically requires the following steps:
//!
//! 1. Open an input file containing a series of test cases.
//! 2. Open an output file where solutions will be written.
//! 2. Read the first line from the input file, which consists solely of an unsigned integer
//!    specifying the number of test cases in the input file.
//! 3. For each test case, perform the following steps:
//!    1. Obtain the corresponding test data by reading one or more lines from the input file (it
//!       may be a fixed number, or specified within the test data itself).
//!    2. Perform some logic using the test data, in order to obtain a set of results.
//!    3. Write the string `"Case #N:"` (where `N` is the number of completed test cases) followed
//!       by the results obtained in the previous step, formatted as the problem requires.
//!
//! Writing code to handle all of the above is tedious and time-consuming, in a situation where
//! every microsecond counts. `gcj-helper` is designed to handle the boilerplate, so you can focus
//! on writing solutions instead.

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", forbid(clippy))]
#![cfg_attr(feature = "clippy", forbid(clippy_internal))]
#![cfg_attr(feature = "clippy", forbid(clippy_pedantic))]
#![cfg_attr(feature = "clippy", forbid(clippy_restrictions))]
#![forbid(warnings)]
#![forbid(box_pointers)]
#![forbid(fat_ptr_transmutes)]
#![forbid(missing_copy_implementations)]
#![forbid(missing_debug_implementations)]
#![forbid(missing_docs)]
#![forbid(trivial_casts)]
#![forbid(trivial_numeric_casts)]
#![forbid(unsafe_code)]
#![forbid(unused_extern_crates)]
#![forbid(unused_import_braces)]
#![deny(unused_qualifications)]
#![forbid(unused_results)]
#![forbid(variant_size_differences)]

use std::{env, io};
use std::fmt::Arguments;
use std::fs::{File, OpenOptions};
use std::io::{BufRead, BufReader, LineWriter, Lines, Write};
use std::ops::{Add, AddAssign};
use std::path::Path;

/// Facilitates the execution of problem solving code.
///
/// In order to handle test cases, you need to create a new `TestEngine`, then call
/// `TestEngine::run()`, which accepts an `Fn(&mut IoHelper)` that is called once per test case.
/// Creating a `TestEngine` is cheap; no files are opened until you call `TestEngine::run()`.
#[derive(Debug)]
pub struct TestEngine<I: AsRef<Path>, O: AsRef<Path>> {
    /// A path to an input file.
    input_file_path: I,
    /// A path to an output file.
    output_file_path: O,
}

/// Provides I/O support for problem solving code.
///
/// The `IoHelper` type allows reading from an input file and writing to an output file.
/// `IoHelper::read_line()` reads the next line of text from the input file, and `io::Write` is
/// implemented for `IoHelper` such that data is written to the output file.
#[derive(Debug)]
pub struct IoHelper {
    /// An iterator over the lines of an input file.
    input: Lines<BufReader<File>>,
    /// An output file.
    output: LineWriter<File>,
    /// The current test case.
    current_case: usize,
    /// The total number of test cases to handle.
    case_count: usize,
}

impl<I: AsRef<Path>, O: AsRef<Path>> TestEngine<I, O> {
    /// Creates a new test engine using the specified input and output file paths.
    ///
    /// Calling this method is cheap; no files are opened until `TestEngine::run()` is called.
    pub fn new(input_file_path: I, output_file_path: O) -> TestEngine<I, O> {
        TestEngine {
            input_file_path: input_file_path,
            output_file_path: output_file_path,
        }
    }

    /// Consumes the test engine, calling a closure once for each test case.
    pub fn run<F: Fn(&mut IoHelper)>(self, f: F) {
        let io_helper = IoHelper::new(self);
        io_helper.run(f);
    }
}

impl TestEngine<String, String> {
    /// Creates a new test engine using input and output file paths obtained from command line
    /// arguments.
    ///
    /// Calling this method is cheap; no files are opened until `TestEngine::run()` is called.
    ///
    /// # Panics
    ///
    /// This method panics if either the input file path or output file path is missing.
    pub fn from_args() -> TestEngine<String, String> {
        let mut args = env::args();
        let input_file_path = args.nth(1).expect("input file path not specified");
        let output_file_path = args.next().expect("output file path not specified");
        Self::new(input_file_path, output_file_path)
    }
}

impl Default for TestEngine<String, String> {
    fn default() -> TestEngine<String, String> {
        Self::from_args()
    }
}

impl IoHelper {
    /// Reads a line of text from the input file.
    ///
    /// # Panics
    ///
    /// This method panics if reading fails for any reason, such as having reached the end of the
    /// input file.
    pub fn read_line(&mut self) -> String {
        self.input
            .next()
            .expect("reached end of file")
            .expect("could not read from input file")
    }

    /// Returns the current test case number.
    pub fn current_case(&self) -> usize {
        self.current_case
    }

    /// Returns the total number of test cases in the input file.
    pub fn case_count(&self) -> usize {
        self.case_count
    }

    /// Creates a new I/O helper.
    fn new<I: AsRef<Path>, O: AsRef<Path>>(test_engine: TestEngine<I, O>) -> IoHelper {
        let mut io_helper = IoHelper {
            input: Self::open_input_file(test_engine.input_file_path),
            output: Self::open_output_file(test_engine.output_file_path),
            current_case: 1,
            case_count: 0,
        };
        io_helper.init_test_case_count();
        io_helper
    }

    /// Consumes the I/O helper, calling a closure once for each test case.
    fn run<F: Fn(&mut IoHelper)>(mut self, f: F) {
        while self.current_case <= self.case_count {
            let current_case_s = self.current_case_string();
            let _ = self.write(current_case_s.as_bytes())
                .expect("could not write current test case string to output file");
            (f)(&mut self);
            self.current_case.add_assign(1);
        }
    }

    /// Creates an iterator over the lines of an input file.
    fn open_input_file<P: AsRef<Path>>(path: P) -> Lines<BufReader<File>> {
        BufReader::new(OpenOptions::new()
            .read(true)
            .open(path)
            .expect("could not open input file for reading")).lines()
    }

    /// Creates an output file.
    fn open_output_file<P: AsRef<Path>>(path: P) -> LineWriter<File> {
        LineWriter::new(OpenOptions::new()
                            .write(true)
                            .truncate(true)
                            .create(true)
                            .open(path)
                            .expect("could not open output file for writing"))
    }

    /// Obtains the number of test cases to examine from the input file.
    fn init_test_case_count(&mut self) {
        let line = self.read_line();
        self.case_count =
            usize::from_str_radix(&line, 10).expect("could not parse test case count");
    }

    /// Creates a string identifying the current test case.
    fn current_case_string(&mut self) -> String {
        let case_str = "Case #";
        let case_s = self.current_case.to_string();
        let case_str_colon = ":";
        let mut out = String::with_capacity(0);
        out.reserve_exact(case_str.len().add(case_s.len()).add(case_str_colon.len()));
        out.push_str(case_str);
        out.push_str(&case_s);
        out.push_str(case_str_colon);
        out
    }
}

impl Write for IoHelper {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.output.write(buf)
    }

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

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.output.write_all(buf)
    }

    fn write_fmt(&mut self, fmt: Arguments) -> io::Result<()> {
        self.output.write_fmt(fmt)
    }
}
<|endoftext|>


<commit_before>#[macro_use] extern crate quick_error;
#[macro_use] extern crate string_cache;
extern crate mime;
extern crate hyper;
extern crate url;
extern crate kuchiki;
extern crate image;

mod strategies;
mod util;

use image::GenericImage;
use strategies::Strategy;
use std::io::Read;
use util::AsImageFormat;

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        Hyper(error: hyper::Error) { from() }
        Io(error: std::io::Error) { from() }
        Image(error: image::ImageError) { from() }
        Other(msg: String) {
            description(msg)
        }
    }
}

pub struct IconScraper {
    pub document_url: url::Url,
    pub dom: Option<kuchiki::NodeRef>,
}

impl IconScraper {
    pub fn from_url(url: url::Url) -> Self {
        IconScraper {
            document_url: url,
            dom: None
        }
    }

    pub fn fetch_document(&mut self) -> Result<(), Error> {
        let client = hyper::client::Client::new();
        let mut response = try!(client.get(self.document_url.clone()).send());
        let parser = try!(kuchiki::Html::from_stream(&mut response));
        self.dom = Some(parser.parse());
        Ok(())
    }

    pub fn icons_by_size(mut self) -> Vec<Icon> {
        let mut guesses = strategies::LinkRelStrategy.get_guesses(&mut self)
            .into_iter()
            .chain(strategies::DefaultFaviconPathStrategy.get_guesses(&mut self).into_iter())
            .filter_map(|mut icon| if icon.fetch_dimensions().is_ok() { Some(icon) } else { None })
            .collect::<Vec<_>>();

        guesses.sort_by(|a, b| {
            (a.width.unwrap() * a.height.unwrap())
                .cmp(&(b.width.unwrap() * b.height.unwrap()))
        });
        guesses
    }

    pub fn at_least(self, width: u32, height: u32) -> Option<Icon> {
        self.icons_by_size()
            .into_iter()
            .skip_while(|icon| icon.width.unwrap() < width || icon.height.unwrap() < height)
            .next()
    }
}

pub struct Icon {
    pub url: url::Url,
    pub raw: Option<Vec<u8>>,
    pub mime_type: Option<mime::Mime>,
    pub width: Option<u32>,
    pub height: Option<u32>
}

impl Icon {
    pub fn from_url(url: url::Url) -> Self {
        Icon {
            url: url,
            raw: None,
            mime_type: None,
            width: None,
            height: None
        }
    }

    pub fn fetch(&mut self) -> Result<(), Error> {
        let client = hyper::client::Client::new();
        let mut response = try!(client.get(self.url.clone()).send());

        let mut bytes: Vec<u8> = vec![];
        try!(response.read_to_end(&mut bytes));
        if !response.status.is_success() {
            return Err(Error::Other(format!("Bad status code: {:?}", response.status)));
        }

        let mime_type: mime::Mime = match response.headers.get::<hyper::header::ContentType>() {
            Some(x) => x.clone().0,
            None => return Err(Error::Other("No Content-Type found.".to_owned()))
        };
        let image_format = match mime_type.as_image_format() {
            Some(x) => x,
            None => return Err(Error::Other(format!("Invalid image type: {:?}", mime_type)))
        };
        let image = try!(image::load_from_memory_with_format(&bytes, image_format));

        self.width = Some(image.width());
        self.height = Some(image.height());
        self.raw = Some(bytes);
        self.mime_type = Some(mime_type);
        Ok(())
    }

    pub fn fetch_dimensions(&mut self) -> Result<(), Error> {
        match (self.width, self.height) {
            (Some(_), Some(_)) => Ok(()),
            _ => self.fetch()
        }
    }
}
<commit_msg>Add largest helper method<commit_after>#[macro_use] extern crate quick_error;
#[macro_use] extern crate string_cache;
extern crate mime;
extern crate hyper;
extern crate url;
extern crate kuchiki;
extern crate image;

mod strategies;
mod util;

use image::GenericImage;
use strategies::Strategy;
use std::io::Read;
use util::AsImageFormat;

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        Hyper(error: hyper::Error) { from() }
        Io(error: std::io::Error) { from() }
        Image(error: image::ImageError) { from() }
        Other(msg: String) {
            description(msg)
        }
    }
}

pub struct IconScraper {
    pub document_url: url::Url,
    pub dom: Option<kuchiki::NodeRef>,
    pub icons: Vec<Icon>
}

impl IconScraper {
    pub fn from_url(url: url::Url) -> Self {
        IconScraper {
            document_url: url,
            dom: None,
            icons: vec![];
        }
    }

    pub fn fetch_document(&mut self) -> Result<(), Error> {
        let client = hyper::client::Client::new();
        let mut response = try!(client.get(self.document_url.clone()).send());
        let parser = try!(kuchiki::Html::from_stream(&mut response));
        self.dom = Some(parser.parse());
        Ok(())
    }

    pub fn fetch_icons(&mut self) {
        self.icons = strategies::LinkRelStrategy.get_guesses(&mut self)
            .into_iter()
            .chain(strategies::DefaultFaviconPathStrategy.get_guesses(&mut self).into_iter())
            .filter_map(|mut icon| if icon.fetch_dimensions().is_ok() { Some(icon) } else { None })
            .collect::<Vec<_>>();

        self.icons.sort_by(|a, b| {
            (a.width.unwrap() * a.height.unwrap())
                .cmp(&(b.width.unwrap() * b.height.unwrap()))
        });
    }

    pub fn at_least(self, width: u32, height: u32) -> Option<Icon> {
        self.icons
            .into_iter()
            .skip_while(|icon| icon.width.unwrap() < width || icon.height.unwrap() < height)
            .next()
    }

    pub fn largest(self) -> Option<Icon> {
        if self.icons.len() > 0 {
            Some(self.icons[self.icons.len() - 1])
        }
    }
}

pub struct Icon {
    pub url: url::Url,
    pub raw: Option<Vec<u8>>,
    pub mime_type: Option<mime::Mime>,
    pub width: Option<u32>,
    pub height: Option<u32>
}

impl Icon {
    pub fn from_url(url: url::Url) -> Self {
        Icon {
            url: url,
            raw: None,
            mime_type: None,
            width: None,
            height: None
        }
    }

    pub fn fetch(&mut self) -> Result<(), Error> {
        let client = hyper::client::Client::new();
        let mut response = try!(client.get(self.url.clone()).send());

        let mut bytes: Vec<u8> = vec![];
        try!(response.read_to_end(&mut bytes));
        if !response.status.is_success() {
            return Err(Error::Other(format!("Bad status code: {:?}", response.status)));
        }

        let mime_type: mime::Mime = match response.headers.get::<hyper::header::ContentType>() {
            Some(x) => x.clone().0,
            None => return Err(Error::Other("No Content-Type found.".to_owned()))
        };
        let image_format = match mime_type.as_image_format() {
            Some(x) => x,
            None => return Err(Error::Other(format!("Invalid image type: {:?}", mime_type)))
        };
        let image = try!(image::load_from_memory_with_format(&bytes, image_format));

        self.width = Some(image.width());
        self.height = Some(image.height());
        self.raw = Some(bytes);
        self.mime_type = Some(mime_type);
        Ok(())
    }

    pub fn fetch_dimensions(&mut self) -> Result<(), Error> {
        match (self.width, self.height) {
            (Some(_), Some(_)) => Ok(()),
            _ => self.fetch()
        }
    }
}
<|endoftext|>


<commit_before>#![feature(libc)]
#![feature(plugin)]
#![feature(alloc)]

#![allow(dead_code)]
#![allow(unused_imports)]

extern crate libc;
#[macro_use] extern crate bitflags;

mod ffi;

use std::ffi::CString;
use std::ptr;
use std::mem;
use std::boxed;

use ffi::nginx::{
   ngx_str_t, ngx_http_request_t, ngx_pcalloc, ngx_palloc, ngx_conf_t, ngx_command_t, ngx_http_core_module,
   ngx_http_conf_ctx_t, ngx_int_t, ngx_http_output_filter, ngx_chain_t, ngx_http_send_header, ngx_buf_t,
   ngx_uint_t, ngx_http_core_loc_conf_t, ngx_log_error_core,
};

use libc::{size_t, c_void, c_uchar, c_char};

const NGX_CONF_OK: *const c_void = 0 as *const c_void;
const NGX_CONF_ERROR: *const c_void = -1 as *const c_void;

const NGX_OK:        ngx_int_t =  0;
const NGX_ERROR:     ngx_int_t = -1;
const NGX_AGAIN:     ngx_int_t = -2;
const NGX_BUSY:      ngx_int_t = -3;
const NGX_DONE:      ngx_int_t = -4;
const NGX_DECLINED:  ngx_int_t = -5;
const NGX_ABORT:     ngx_int_t = -6;

const NGX_HTTP_OK:                      ngx_uint_t = 200;
const NGX_HTTP_INTERNAL_SERVER_ERROR:   ngx_uint_t = 500;

// #define ngx_http_conf_get_module_loc_conf(cf, module)                         \
//    ((ngx_http_conf_ctx_t *) cf->ctx)->loc_conf[module.ctx_index]
macro_rules! ngx_http_conf_get_module_loc_conf {
   ($cf:expr, $module:expr) => (
      unsafe {
         (*
            (
               (*
                  (
                     (*cf).ctx as *mut ngx_http_conf_ctx_t
                  )
               ).loc_conf
            ).offset(ngx_http_core_module.ctx_index as isize)
         )
      }
   )
}

macro_rules! ngx_alloc_buf {
   ($pool:expr) => (
      ngx_palloc($pool, mem::size_of::<ngx_buf_t>() as u64)
   )
}

macro_rules! ngx_calloc_buf {
   ($pool:expr) => (
      ngx_pcalloc($pool, mem::size_of::<ngx_buf_t>() as u64)
   )
}

bitflags! {
    flags BufFlags: u32 {
        const FLAG_TEMPORARY        = 0b0000000000000001,
        const FLAG_MEMORY           = 0b0000000000000010,
        const FLAG_MMAP             = 0b0000000000000100,
        const FLAG_RECYCLED         = 0b0000000000001000,
        const FLAG_IN_FILE          = 0b0000000000010000,
        const FLAG_FLUSH            = 0b0000000000100000,
        const FLAG_SYNC             = 0b0000000001000000,
        const FLAG_LAST_BUF         = 0b0000000010000000,
        const FLAG_LAST_IN_CHAIN    = 0b0000000100000000,
        const FLAG_LAST_SHADOW      = 0b0000001000000000,
        const FLAG_TEMP_FILE        = 0b0000010000000000,
    }
}

#[no_mangle]
pub extern fn ngx_http_sample_module_command(
   cf: *mut ngx_conf_t,
   cmd: *mut ngx_command_t,
   conf: *mut c_void
) -> *mut c_char {
   //ngx_http_core_loc_conf_t  *clcf;

   unsafe {
      let clcf: *mut ngx_http_core_loc_conf_t = (*((*((*cf).ctx as *mut ngx_http_conf_ctx_t)).loc_conf).offset(ngx_http_core_module.ctx_index as isize)) as *mut ngx_http_core_loc_conf_t;
      (*clcf).handler = Some(ngx_http_sample_handler);
   }

   NGX_CONF_OK as *mut c_char
}

#[no_mangle]
pub extern fn ngx_http_sample_handler(r: *mut ngx_http_request_t) -> ngx_int_t
{
   unsafe {
      let log = (*(*r).connection).log;

      let ngx_http_sample_text: ngx_str_t = sample_text_from_rust(r);

      (*r).headers_out.status = NGX_HTTP_OK;
      (*r).headers_out.content_length_n = ngx_http_sample_text.len as i64;

      let rc: ngx_int_t = ngx_http_send_header(r);
      if rc == NGX_ERROR || rc > NGX_OK { //|| (*r).header_only) {
         return rc;
      }

      let b: *mut ngx_buf_t = ngx_calloc_buf!((*r).pool) as *mut ngx_buf_t;

      if b.is_null() {
         return NGX_HTTP_INTERNAL_SERVER_ERROR as i64;
      };

      let out: Box<ngx_chain_t> = Box::new(
         ngx_chain_t {
            buf: b,
            next: ptr::null_mut(),
         }
      );

      let headers_in = (*r).headers_in;

      let cstr_template = CString::new("BITS: \"%s\"").unwrap();
      let b1 = CString::new(format!("{:032b}", headers_in._bindgen_bitfield_1_)).unwrap();

      ngx_log_error_core(
         2, log, 0,
         cstr_template.as_ptr(),
         b1.as_ptr()
      );

      let out: *mut ngx_chain_t = boxed::into_raw(out);

      (*b).start = ngx_http_sample_text.data;
      (*b).pos = (*b).start;

      (*b).end = ngx_http_sample_text.data.offset(ngx_http_sample_text.len as isize);
      (*b).last = (*b).end;

      let buf_flags = FLAG_MEMORY | FLAG_LAST_BUF | FLAG_LAST_IN_CHAIN;
      (*b)._bindgen_bitfield_1_ = buf_flags.bits();

      ngx_http_output_filter(r, out)
   }
}

fn sample_text_from_rust(r: *mut ngx_http_request_t) -> ngx_str_t
{
   let s = CString::new("<meta charset=\"utf-8\">Здравейте!".to_string()).unwrap();
   let len = s.to_bytes().len() as size_t;

   let result = ngx_str_t {
      len: len,
      data: unsafe {
         ngx_pcalloc((*r).pool, len) as *mut u8
      },
   };

   unsafe {
      ptr::copy_nonoverlapping(result.data, s.as_ptr() as *const u8, len as usize);
   }

   result
}

#[no_mangle]
pub extern fn dump_request(r: *mut ngx_http_request_t) {
   unsafe {
      let log = (*(*r).connection).log;

      let template = "REQ: \
         method=\"%ud\" \
         http_version=\"%ud\" \
         request_line=\"%V\" \
         uri=\"%V\" \
         args=\"%V\" \
         exten=\"%V\" \
         unparsed_uri=\"%V\" \
         method_name=\"%V\" \
         http_protocol=\"%V\" \
         bit1=\"%s\" \
         bit2=\"%s\" \
         bit3=\"%s\" \
         bit4=\"%s\" \
         bits=\"%s\" \
      ";
      let cstr_template = CString::new(template).unwrap();

      let b1 = CString::new(format!("{:032b}", (*r)._bindgen_bitfield_1_)).unwrap();
      let b2 = CString::new(format!("{:032b}", (*r)._bindgen_bitfield_2_)).unwrap();
      let b3 = CString::new(format!("{:032b}", (*r)._bindgen_bitfield_3_)).unwrap();
      let b4 = CString::new(format!("{:032b}", (*r)._bindgen_bitfield_4_)).unwrap();

      let buf_flags = FLAG_MEMORY | FLAG_LAST_BUF | FLAG_LAST_IN_CHAIN;
      let bits = CString::new(format!("{:032b}", buf_flags.bits())).unwrap();

      ngx_log_error_core(
         2, log, 0,
         cstr_template.as_ptr(),
         (*r).method,
         (*r).http_version,
         &((*r).request_line),
         &((*r).uri),
         &((*r).args),
         &((*r).exten),
         &((*r).unparsed_uri),
         &((*r).method_name),
         &((*r).http_protocol),
         b1.as_ptr(),
         b2.as_ptr(),
         b3.as_ptr(),
         b4.as_ptr(),
         bits.as_ptr(),
      );
   }
}

#[no_mangle]
pub extern fn dump_buffer(r: *mut ngx_http_request_t, b: *mut ngx_buf_t) {
   unsafe {
      let log = (*(*r).connection).log;

      let template = "BUF: \
         pos=\"%p\" \
         last=\"%p\" \
         start=\"%p\" \
         end=\"%p\" \
         num=\"%d\" \
         bit1=\"%s\" \
      ";
      let cstr_template = CString::new(template).unwrap();

      let b1 = CString::new(format!("{:064b}", (*b)._bindgen_bitfield_1_)).unwrap();

      ngx_log_error_core(
         2, log, 0,
         cstr_template.as_ptr(),
         (*b).pos,
         (*b).last,
         (*b).start,
         (*b).end,
         (*b).num,
         b1.as_ptr(),
      );
   }
}
<commit_msg>Using the ngx_http_conf_get_module_loc_conf macros.<commit_after>#![feature(libc)]
#![feature(plugin)]
#![feature(alloc)]

#![allow(dead_code)]
#![allow(unused_imports)]

extern crate libc;
#[macro_use] extern crate bitflags;

mod ffi;

use std::ffi::CString;
use std::ptr;
use std::mem;
use std::boxed;

use ffi::nginx::{
   ngx_str_t, ngx_http_request_t, ngx_pcalloc, ngx_palloc, ngx_conf_t, ngx_command_t, ngx_http_core_module,
   ngx_http_conf_ctx_t, ngx_int_t, ngx_http_output_filter, ngx_chain_t, ngx_http_send_header, ngx_buf_t,
   ngx_uint_t, ngx_http_core_loc_conf_t, ngx_log_error_core,
};

use libc::{size_t, c_void, c_uchar, c_char};

const NGX_CONF_OK: *const c_void = 0 as *const c_void;
const NGX_CONF_ERROR: *const c_void = -1 as *const c_void;

const NGX_OK:        ngx_int_t =  0;
const NGX_ERROR:     ngx_int_t = -1;
const NGX_AGAIN:     ngx_int_t = -2;
const NGX_BUSY:      ngx_int_t = -3;
const NGX_DONE:      ngx_int_t = -4;
const NGX_DECLINED:  ngx_int_t = -5;
const NGX_ABORT:     ngx_int_t = -6;

const NGX_HTTP_OK:                      ngx_uint_t = 200;
const NGX_HTTP_INTERNAL_SERVER_ERROR:   ngx_uint_t = 500;

macro_rules! ngx_http_conf_get_module_loc_conf {
   ($cf:expr, $module:expr) => ({
      (*
         (
            (*
               (
                  (*$cf).ctx as *mut ngx_http_conf_ctx_t
               )
            ).loc_conf
         ).offset($module.ctx_index as isize)
      ) as *mut ngx_http_core_loc_conf_t
   })
}

macro_rules! ngx_alloc_buf {
   ($pool:expr) => (
      ngx_palloc($pool, mem::size_of::<ngx_buf_t>() as u64)
   )
}

macro_rules! ngx_calloc_buf {
   ($pool:expr) => (
      ngx_pcalloc($pool, mem::size_of::<ngx_buf_t>() as u64)
   )
}

bitflags! {
    flags BufFlags: u32 {
        const FLAG_TEMPORARY        = 0b0000000000000001,
        const FLAG_MEMORY           = 0b0000000000000010,
        const FLAG_MMAP             = 0b0000000000000100,
        const FLAG_RECYCLED         = 0b0000000000001000,
        const FLAG_IN_FILE          = 0b0000000000010000,
        const FLAG_FLUSH            = 0b0000000000100000,
        const FLAG_SYNC             = 0b0000000001000000,
        const FLAG_LAST_BUF         = 0b0000000010000000,
        const FLAG_LAST_IN_CHAIN    = 0b0000000100000000,
        const FLAG_LAST_SHADOW      = 0b0000001000000000,
        const FLAG_TEMP_FILE        = 0b0000010000000000,
    }
}

#[no_mangle]
pub extern fn ngx_http_sample_module_command(
   cf: *mut ngx_conf_t,
   cmd: *mut ngx_command_t,
   conf: *mut c_void
) -> *mut c_char {
   //ngx_http_core_loc_conf_t  *clcf;

   unsafe {
      let clcf = ngx_http_conf_get_module_loc_conf!(cf, ngx_http_core_module);
      (*clcf).handler = Some(ngx_http_sample_handler);
   }

   NGX_CONF_OK as *mut c_char
}

#[no_mangle]
pub extern fn ngx_http_sample_handler(r: *mut ngx_http_request_t) -> ngx_int_t
{
   unsafe {
      let log = (*(*r).connection).log;

      let ngx_http_sample_text: ngx_str_t = sample_text_from_rust(r);

      (*r).headers_out.status = NGX_HTTP_OK;
      (*r).headers_out.content_length_n = ngx_http_sample_text.len as i64;

      let rc: ngx_int_t = ngx_http_send_header(r);
      if rc == NGX_ERROR || rc > NGX_OK { //|| (*r).header_only) {
         return rc;
      }

      let b: *mut ngx_buf_t = ngx_calloc_buf!((*r).pool) as *mut ngx_buf_t;

      if b.is_null() {
         return NGX_HTTP_INTERNAL_SERVER_ERROR as i64;
      };

      let out: Box<ngx_chain_t> = Box::new(
         ngx_chain_t {
            buf: b,
            next: ptr::null_mut(),
         }
      );

      let headers_in = (*r).headers_in;

      let cstr_template = CString::new("BITS: \"%s\"").unwrap();
      let b1 = CString::new(format!("{:032b}", headers_in._bindgen_bitfield_1_)).unwrap();

      ngx_log_error_core(
         2, log, 0,
         cstr_template.as_ptr(),
         b1.as_ptr()
      );

      let out: *mut ngx_chain_t = boxed::into_raw(out);

      (*b).start = ngx_http_sample_text.data;
      (*b).pos = (*b).start;

      (*b).end = ngx_http_sample_text.data.offset(ngx_http_sample_text.len as isize);
      (*b).last = (*b).end;

      let buf_flags = FLAG_MEMORY | FLAG_LAST_BUF | FLAG_LAST_IN_CHAIN;
      (*b)._bindgen_bitfield_1_ = buf_flags.bits();

      ngx_http_output_filter(r, out)
   }
}

fn sample_text_from_rust(r: *mut ngx_http_request_t) -> ngx_str_t
{
   let s = CString::new("<meta charset=\"utf-8\">Здравейте!".to_string()).unwrap();
   let len = s.to_bytes().len() as size_t;

   let result = ngx_str_t {
      len: len,
      data: unsafe {
         ngx_pcalloc((*r).pool, len) as *mut u8
      },
   };

   unsafe {
      ptr::copy_nonoverlapping(result.data, s.as_ptr() as *const u8, len as usize);
   }

   result
}

#[no_mangle]
pub extern fn dump_request(r: *mut ngx_http_request_t) {
   unsafe {
      let log = (*(*r).connection).log;

      let template = "REQ: \
         method=\"%ud\" \
         http_version=\"%ud\" \
         request_line=\"%V\" \
         uri=\"%V\" \
         args=\"%V\" \
         exten=\"%V\" \
         unparsed_uri=\"%V\" \
         method_name=\"%V\" \
         http_protocol=\"%V\" \
         bit1=\"%s\" \
         bit2=\"%s\" \
         bit3=\"%s\" \
         bit4=\"%s\" \
         bits=\"%s\" \
      ";
      let cstr_template = CString::new(template).unwrap();

      let b1 = CString::new(format!("{:032b}", (*r)._bindgen_bitfield_1_)).unwrap();
      let b2 = CString::new(format!("{:032b}", (*r)._bindgen_bitfield_2_)).unwrap();
      let b3 = CString::new(format!("{:032b}", (*r)._bindgen_bitfield_3_)).unwrap();
      let b4 = CString::new(format!("{:032b}", (*r)._bindgen_bitfield_4_)).unwrap();

      let buf_flags = FLAG_MEMORY | FLAG_LAST_BUF | FLAG_LAST_IN_CHAIN;
      let bits = CString::new(format!("{:032b}", buf_flags.bits())).unwrap();

      ngx_log_error_core(
         2, log, 0,
         cstr_template.as_ptr(),
         (*r).method,
         (*r).http_version,
         &((*r).request_line),
         &((*r).uri),
         &((*r).args),
         &((*r).exten),
         &((*r).unparsed_uri),
         &((*r).method_name),
         &((*r).http_protocol),
         b1.as_ptr(),
         b2.as_ptr(),
         b3.as_ptr(),
         b4.as_ptr(),
         bits.as_ptr(),
      );
   }
}

#[no_mangle]
pub extern fn dump_buffer(r: *mut ngx_http_request_t, b: *mut ngx_buf_t) {
   unsafe {
      let log = (*(*r).connection).log;

      let template = "BUF: \
         pos=\"%p\" \
         last=\"%p\" \
         start=\"%p\" \
         end=\"%p\" \
         num=\"%d\" \
         bit1=\"%s\" \
      ";
      let cstr_template = CString::new(template).unwrap();

      let b1 = CString::new(format!("{:064b}", (*b)._bindgen_bitfield_1_)).unwrap();

      ngx_log_error_core(
         2, log, 0,
         cstr_template.as_ptr(),
         (*b).pos,
         (*b).last,
         (*b).start,
         (*b).end,
         (*b).num,
         b1.as_ptr(),
      );
   }
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;

use std::collections::BTreeMap;

use rustc_serialize::json::{Json, ToJson};

/// An Optional value can contain Optional::Some<T> or Optional::Absent.
/// It is similar to an Option, but Optional::Absent means it will be
/// omitted when serialized.
#[derive(Debug, Copy, Clone)]
pub enum Optional<T> {
    Value(T),
    Absent,
}

impl<T> Optional<T> {
    pub fn map_or<U, F: FnOnce(T) -> U>(self, def: U, f: F) -> U {
        match self {
            Optional::Value(v) => f(v),
            Optional::Absent => def,
        }
    }

    pub fn as_mut<'r>(&'r mut self) -> Optional<&'r mut T> {
        match *self {
            Optional::Value(ref mut x) => Optional::Value(x),
            Optional::Absent => Optional::Absent
        }
    }

    pub fn as_ref<'r>(&'r self) -> Optional<&'r T> {
        match *self {
            Optional::Value(ref x) => Optional::Value(x),
            Optional::Absent => Optional::Absent
        }
    }
}

pub struct Location {
    pub address: Optional<String>,
    pub lat: f64,
    pub lon: f64,
}

pub struct Spacefed {
    pub spacenet: bool,
    pub spacesaml: bool,
    pub spacephone: bool,
}

pub struct Icon {
    pub open: String,
    pub close: String,
}

pub struct State {
    pub open: Option<bool>,
    pub lastchange: Optional<u64>,
    pub trigger_person: Optional<String>,
    pub message: Optional<String>,
    pub icon: Optional<Icon>,
}

pub struct Event {
    pub name: String,
    pub _type: String,
    pub timestamp: u64,
    pub extra: Optional<String>,
}

pub struct Contact {
    pub irc: Optional<String>,
    pub twitter: Optional<String>,
    pub foursquare: Optional<String>,
    pub email: Optional<String>,
}

pub struct Feed {
    pub _type: Optional<String>,
    pub url: String,
}

pub struct Feeds {
    pub blog: Optional<Feed>,
    pub wiki: Optional<Feed>,
    pub calendar: Optional<Feed>,
    pub flickr: Optional<Feed>,
}

pub struct Sensors {
    pub people_now_present: Optional<Vec<PeopleNowPresentSensor>>,
    pub temperature: Optional<Vec<TemperatureSensor>>,
}

pub struct PeopleNowPresentSensor {
    pub value: u32,
    pub location: Optional<String>,
    pub name: Optional<String>,
    pub names: Optional<Vec<String>>,
    pub description: Optional<String>,
}

pub struct TemperatureSensor {
    pub value: f32,
    pub unit: String,
    pub location: String,
    pub name: Optional<String>,
    pub description: Optional<String>,
}

pub struct Cache {
    pub schedule: String,
}

pub struct RadioShow {
    pub name: String,
    pub url: String,
    pub _type: String,
    pub start: String,
    pub end: String,
}

pub struct Status {

    // Hackerspace properties
    pub api: String,
    pub space: String,
    pub logo: String,
    pub url: String,
    pub location: Location,
    pub contact: Contact,

    // Hackerspace features / projects
    pub spacefed: Optional<Spacefed>,
    pub projects: Optional<Vec<String>>,
    pub cam: Optional<Vec<String>>,
    pub feeds: Optional<Feeds>,
    pub events: Optional<Vec<Event>>,
    pub radio_show: Optional<Vec<RadioShow>>,

    // SpaceAPI internal usage
    pub cache: Optional<Cache>,
    pub issue_report_channels: Vec<String>,

    // Mutable data
    pub state: State,
    pub sensors: Optional<Sensors>,

}

impl Status {

    /// Create a new Status object with only the minimum amount of fields
    pub fn new(space: String, logo: String, url: String, location: Location, contact: Contact, issue_report_channels: Vec<String>) -> Status {
        Status {
            api: "0.13".to_string(),
            space: space,
            logo: logo,
            url: url,
            location: location,
            contact: contact,

            spacefed: Optional::Absent,
            projects: Optional::Absent,
            cam: Optional::Absent,
            feeds: Optional::Absent,
            events: Optional::Absent,
            radio_show: Optional::Absent,

            cache: Optional::Absent,
            issue_report_channels: issue_report_channels,

            state: State {
                open: None,
                lastchange: Optional::Absent,
                trigger_person: Optional::Absent,
                message: Optional::Absent,
                icon: Optional::Absent,
            },
            sensors: Optional::Absent,
        }
    }

}

impl ToJson for Status {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();

        d.insert("api".to_string(), self.api.to_json());
        d.insert("space".to_string(), self.space.to_json());
        d.insert("logo".to_string(), self.logo.to_json());
        d.insert("url".to_string(), self.url.to_json());
        d.insert("location".to_string(), self.location.to_json());
        d.insert("contact".to_string(), self.contact.to_json());

        match self.spacefed {
            Optional::Value(ref spacefed) => { d.insert("spacefed".to_string(), spacefed.to_json()); },
            Optional::Absent => (),
        };
        match self.projects {
            Optional::Value(ref projects) => { d.insert("projects".to_string(), projects.to_json()); },
            Optional::Absent => (),
        };
        match self.cam {
            Optional::Value(ref cam) => { d.insert("cam".to_string(), cam.to_json()); },
            Optional::Absent => (),
        };
        match self.feeds {
            Optional::Value(ref feeds) => { d.insert("feeds".to_string(), feeds.to_json()); },
            Optional::Absent => (),
        };
        match self.events {
            Optional::Value(ref events) => { d.insert("events".to_string(), events.to_json()); },
            Optional::Absent => (),
        };
        match self.radio_show {
            Optional::Value(ref radio_show) => { d.insert("radio_show".to_string(), radio_show.to_json()); },
            Optional::Absent => (),
        };

        match self.cache {
            Optional::Value(ref cache) => { d.insert("cache".to_string(), cache.to_json()); },
            Optional::Absent => (),
        };
        d.insert("issue_report_channels".to_string(), self.issue_report_channels.to_json());

        d.insert("state".to_string(), self.state.to_json());
        match self.sensors {
            Optional::Value(ref sensors) => { d.insert("sensors".to_string(), sensors.to_json()); },
            Optional::Absent => (),
        };

        Json::Object(d)
    }
}

impl ToJson for Location {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("lat".to_string(), self.lat.to_json());
        d.insert("lon".to_string(), self.lon.to_json());
        match self.address {
            Optional::Value(ref address) => {
                d.insert("address".to_string(), address.to_json());
            },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Spacefed {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("spacenet".to_string(), self.spacenet.to_json());
        d.insert("spacesaml".to_string(), self.spacesaml.to_json());
        d.insert("spacephone".to_string(), self.spacephone.to_json());
        Json::Object(d)
    }
}

impl ToJson for Icon {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("open".to_string(), self.open.to_json());
        d.insert("close".to_string(), self.close.to_json());
        Json::Object(d)
    }
}

impl ToJson for State {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("open".to_string(), self.open.to_json());
        match self.lastchange {
            Optional::Value(ref lastchange) => { d.insert("lastchange".to_string(), lastchange.to_json()); },
            Optional::Absent => (),
        };
        match self.trigger_person {
            Optional::Value(ref trigger_person) => { d.insert("trigger_person".to_string(), trigger_person.to_json()); },
            Optional::Absent => (),
        };
        match self.message {
            Optional::Value(ref message) => { d.insert("message".to_string(), message.to_json()); },
            Optional::Absent => (),
        };
        match self.icon {
            Optional::Value(ref icon) => { d.insert("icon".to_string(), icon.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Event {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("name".to_string(), self.name.to_json());
        d.insert("type".to_string(), self._type.to_json());
        d.insert("timestamp".to_string(), self.timestamp.to_json());
        match self.extra {
            Optional::Value(ref extra) => { d.insert("extra".to_string(), extra.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Contact {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.irc {
            Optional::Value(ref irc) => { d.insert("irc".to_string(), irc.to_json()); },
            Optional::Absent => (),
        };
        match self.twitter {
            Optional::Value(ref twitter) => { d.insert("twitter".to_string(), twitter.to_json()); },
            Optional::Absent => (),
        };
        match self.foursquare {
            Optional::Value(ref foursquare) => { d.insert("foursquare".to_string(), foursquare.to_json()); },
            Optional::Absent => (),
        };
        match self.email {
            Optional::Value(ref email) => { d.insert("email".to_string(), email.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Feed {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("url".to_string(), self.url.to_json());
        match self._type {
            Optional::Value(ref _type) => { d.insert("type".to_string(), _type.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Feeds {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.blog {
            Optional::Value(ref blog) => { d.insert("blog".to_string(), blog.to_json()); },
            Optional::Absent => (),
        };
        match self.wiki {
            Optional::Value(ref wiki) => { d.insert("wiki".to_string(), wiki.to_json()); },
            Optional::Absent => (),
        };
        match self.calendar {
            Optional::Value(ref calendar) => { d.insert("calendar".to_string(), calendar.to_json()); },
            Optional::Absent => (),
        };
        match self.flickr {
            Optional::Value(ref flickr) => { d.insert("flickr".to_string(), flickr.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Sensors {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.people_now_present {
            Optional::Value(ref people_now_present) => { d.insert("people_now_present".to_string(), people_now_present.to_json()); },
            Optional::Absent => (),
        };
        match self.temperature {
            Optional::Value(ref temperature) => { d.insert("temperature".to_string(), temperature.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for PeopleNowPresentSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        match self.location {
            Optional::Value(ref location) => { d.insert("location".to_string(), location.to_json()); },
            Optional::Absent => (),
        };
        match self.name {
            Optional::Value(ref name) => { d.insert("name".to_string(), name.to_json()); },
            Optional::Absent => (),
        };
        match self.names {
            Optional::Value(ref names) => { d.insert("names".to_string(), names.to_json()); },
            Optional::Absent => (),
        };
        match self.description {
            Optional::Value(ref description) => { d.insert("description".to_string(), description.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for TemperatureSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        d.insert("unit".to_string(), self.unit.to_json());
        d.insert("location".to_string(), self.location.to_json());
        match self.name {
            Optional::Value(ref name) => { d.insert("name".to_string(), name.to_json()); },
            Optional::Absent => (),
        };
        match self.description {
            Optional::Value(ref description) => { d.insert("description".to_string(), description.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Cache {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("schedule".to_string(), self.schedule.to_json());
        Json::Object(d)
    }
}

impl ToJson for RadioShow {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("name".to_string(), self.name.to_json());
        d.insert("url".to_string(), self.url.to_json());
        d.insert("type".to_string(), self._type.to_json());
        d.insert("start".to_string(), self.start.to_json());
        d.insert("end".to_string(), self.end.to_json());
        Json::Object(d)
    }
}
<commit_msg>spaceapi: Use map_or() to simplify ToJson implementations<commit_after>extern crate rustc_serialize;

use std::collections::BTreeMap;

use rustc_serialize::json::{Json, ToJson};

/// An Optional value can contain Optional::Some<T> or Optional::Absent.
/// It is similar to an Option, but Optional::Absent means it will be
/// omitted when serialized.
#[derive(Debug, Copy, Clone)]
pub enum Optional<T> {
    Value(T),
    Absent,
}

impl<T> Optional<T> {
    pub fn map_or<U, F: FnOnce(T) -> U>(self, def: U, f: F) -> U {
        match self {
            Optional::Value(v) => f(v),
            Optional::Absent => def,
        }
    }

    pub fn as_mut<'r>(&'r mut self) -> Optional<&'r mut T> {
        match *self {
            Optional::Value(ref mut x) => Optional::Value(x),
            Optional::Absent => Optional::Absent
        }
    }

    pub fn as_ref<'r>(&'r self) -> Optional<&'r T> {
        match *self {
            Optional::Value(ref x) => Optional::Value(x),
            Optional::Absent => Optional::Absent
        }
    }
}

pub struct Location {
    pub address: Optional<String>,
    pub lat: f64,
    pub lon: f64,
}

pub struct Spacefed {
    pub spacenet: bool,
    pub spacesaml: bool,
    pub spacephone: bool,
}

pub struct Icon {
    pub open: String,
    pub close: String,
}

pub struct State {
    pub open: Option<bool>,
    pub lastchange: Optional<u64>,
    pub trigger_person: Optional<String>,
    pub message: Optional<String>,
    pub icon: Optional<Icon>,
}

pub struct Event {
    pub name: String,
    pub _type: String,
    pub timestamp: u64,
    pub extra: Optional<String>,
}

pub struct Contact {
    pub irc: Optional<String>,
    pub twitter: Optional<String>,
    pub foursquare: Optional<String>,
    pub email: Optional<String>,
}

pub struct Feed {
    pub _type: Optional<String>,
    pub url: String,
}

pub struct Feeds {
    pub blog: Optional<Feed>,
    pub wiki: Optional<Feed>,
    pub calendar: Optional<Feed>,
    pub flickr: Optional<Feed>,
}

pub struct Sensors {
    pub people_now_present: Optional<Vec<PeopleNowPresentSensor>>,
    pub temperature: Optional<Vec<TemperatureSensor>>,
}

pub struct PeopleNowPresentSensor {
    pub value: u32,
    pub location: Optional<String>,
    pub name: Optional<String>,
    pub names: Optional<Vec<String>>,
    pub description: Optional<String>,
}

pub struct TemperatureSensor {
    pub value: f32,
    pub unit: String,
    pub location: String,
    pub name: Optional<String>,
    pub description: Optional<String>,
}

pub struct Cache {
    pub schedule: String,
}

pub struct RadioShow {
    pub name: String,
    pub url: String,
    pub _type: String,
    pub start: String,
    pub end: String,
}

pub struct Status {

    // Hackerspace properties
    pub api: String,
    pub space: String,
    pub logo: String,
    pub url: String,
    pub location: Location,
    pub contact: Contact,

    // Hackerspace features / projects
    pub spacefed: Optional<Spacefed>,
    pub projects: Optional<Vec<String>>,
    pub cam: Optional<Vec<String>>,
    pub feeds: Optional<Feeds>,
    pub events: Optional<Vec<Event>>,
    pub radio_show: Optional<Vec<RadioShow>>,

    // SpaceAPI internal usage
    pub cache: Optional<Cache>,
    pub issue_report_channels: Vec<String>,

    // Mutable data
    pub state: State,
    pub sensors: Optional<Sensors>,

}

impl Status {

    /// Create a new Status object with only the minimum amount of fields
    pub fn new(space: String, logo: String, url: String, location: Location, contact: Contact, issue_report_channels: Vec<String>) -> Status {
        Status {
            api: "0.13".to_string(),
            space: space,
            logo: logo,
            url: url,
            location: location,
            contact: contact,

            spacefed: Optional::Absent,
            projects: Optional::Absent,
            cam: Optional::Absent,
            feeds: Optional::Absent,
            events: Optional::Absent,
            radio_show: Optional::Absent,

            cache: Optional::Absent,
            issue_report_channels: issue_report_channels,

            state: State {
                open: None,
                lastchange: Optional::Absent,
                trigger_person: Optional::Absent,
                message: Optional::Absent,
                icon: Optional::Absent,
            },
            sensors: Optional::Absent,
        }
    }

}

impl ToJson for Status {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();

        d.insert("api".to_string(), self.api.to_json());
        d.insert("space".to_string(), self.space.to_json());
        d.insert("logo".to_string(), self.logo.to_json());
        d.insert("url".to_string(), self.url.to_json());
        d.insert("location".to_string(), self.location.to_json());
        d.insert("contact".to_string(), self.contact.to_json());

        self.spacefed.as_ref().map_or((), |v| { d.insert("spacefed".to_string(), v.to_json()); } );
        self.projects.as_ref().map_or((), |v| { d.insert("projects".to_string(), v.to_json()); });
        self.cam.as_ref().map_or((), |v| { d.insert("cam".to_string(), v.to_json()); });
        self.feeds.as_ref().map_or((), |v| { d.insert("feeds".to_string(), v.to_json()); });
        self.events.as_ref().map_or((), |v| { d.insert("events".to_string(), v.to_json()); });
        self.radio_show.as_ref().map_or((), |v| { d.insert("radio_show".to_string(), v.to_json()); });

        self.cache.as_ref().map_or((), |v| { d.insert("cache".to_string(), v.to_json()); });
        d.insert("issue_report_channels".to_string(), self.issue_report_channels.to_json());

        d.insert("state".to_string(), self.state.to_json());
        self.sensors.as_ref().map_or((), |v| { d.insert("sensors".to_string(), v.to_json()); });

        Json::Object(d)
    }
}

impl ToJson for Location {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("lat".to_string(), self.lat.to_json());
        d.insert("lon".to_string(), self.lon.to_json());
        match self.address {
            Optional::Value(ref address) => {
                d.insert("address".to_string(), address.to_json());
            },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Spacefed {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("spacenet".to_string(), self.spacenet.to_json());
        d.insert("spacesaml".to_string(), self.spacesaml.to_json());
        d.insert("spacephone".to_string(), self.spacephone.to_json());
        Json::Object(d)
    }
}

impl ToJson for Icon {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("open".to_string(), self.open.to_json());
        d.insert("close".to_string(), self.close.to_json());
        Json::Object(d)
    }
}

impl ToJson for State {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("open".to_string(), self.open.to_json());
        self.lastchange.as_ref().map_or((), |v| { d.insert("lastchange".to_string(), v.to_json()); });
        self.trigger_person.as_ref().map_or((), |v| { d.insert("trigger_person".to_string(), v.to_json()); });
        self.message.as_ref().map_or((), |v| { d.insert("message".to_string(), v.to_json()); });
        self.icon.as_ref().map_or((), |v| { d.insert("icon".to_string(), v.to_json()); });
        Json::Object(d)
    }
}

impl ToJson for Event {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("name".to_string(), self.name.to_json());
        d.insert("type".to_string(), self._type.to_json());
        d.insert("timestamp".to_string(), self.timestamp.to_json());
        self.extra.as_ref().map_or((), |v| { d.insert("extra".to_string(), v.to_json()); });
        Json::Object(d)
    }
}

impl ToJson for Contact {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        self.irc.as_ref().map_or((), |v| { d.insert("irc".to_string(), v.to_json()); });
        self.twitter.as_ref().map_or((), |v| { d.insert("twitter".to_string(), v.to_json()); });
        self.foursquare.as_ref().map_or((), |v| { d.insert("foursquare".to_string(), v.to_json()); });
        self.email.as_ref().map_or((), |v| { d.insert("email".to_string(), v.to_json()); });
        Json::Object(d)
    }
}

impl ToJson for Feed {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("url".to_string(), self.url.to_json());
        self._type.as_ref().map_or((), |v| { d.insert("type".to_string(), v.to_json()); });
        Json::Object(d)
    }
}

impl ToJson for Feeds {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        self.blog.as_ref().map_or((), |v| { d.insert("blog".to_string(), v.to_json()); });
        self.wiki.as_ref().map_or((), |v| { d.insert("wiki".to_string(), v.to_json()); });
        self.calendar.as_ref().map_or((), |v| { d.insert("calendar".to_string(), v.to_json()); });
        self.flickr.as_ref().map_or((), |v| { d.insert("flickr".to_string(), v.to_json()); });
        Json::Object(d)
    }
}

impl ToJson for Sensors {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        self.people_now_present.as_ref().map_or((), |v| { d.insert("people_now_present".to_string(), v.to_json()); });
        self.temperature.as_ref().map_or((), |v| { d.insert("temperature".to_string(), v.to_json()); });
        Json::Object(d)
    }
}

impl ToJson for PeopleNowPresentSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        self.location.as_ref().map_or((), |v| { d.insert("location".to_string(), v.to_json()); });
        self.name.as_ref().map_or((), |v| { d.insert("name".to_string(), v.to_json()); });
        self.names.as_ref().map_or((), |v| { d.insert("names".to_string(), v.to_json()); });
        self.description.as_ref().map_or((), |v| { d.insert("description".to_string(), v.to_json()); });
        Json::Object(d)
    }
}

impl ToJson for TemperatureSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        d.insert("unit".to_string(), self.unit.to_json());
        d.insert("location".to_string(), self.location.to_json());
        self.name.as_ref().map_or((), |v| { d.insert("name".to_string(), v.to_json()); });
        self.description.as_ref().map_or((), |v| { d.insert("description".to_string(), v.to_json()); });
        Json::Object(d)
    }
}

impl ToJson for Cache {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("schedule".to_string(), self.schedule.to_json());
        Json::Object(d)
    }
}

impl ToJson for RadioShow {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("name".to_string(), self.name.to_json());
        d.insert("url".to_string(), self.url.to_json());
        d.insert("type".to_string(), self._type.to_json());
        d.insert("start".to_string(), self.start.to_json()); d.insert("end".to_string(), self.end.to_json());
        Json::Object(d)
    }
}
<|endoftext|>


<commit_before>

/// Used to ensure an abort on panic.
/// Call .done() to consume without aborting
#[derive(Debug)]
struct AbortOnSuddenDrop {
    finished: bool
}

impl AbortOnSuddenDrop {

    pub fn new() -> Self {
        AbortOnSuddenDrop { finished: false }
    }
    /// Consume `self` without aborting
    pub fn done(mut self) {
        self.finished = true;
    }
}

impl Drop for AbortOnSuddenDrop {
    fn drop(&mut self) {
        if !self.finished {
            std::process::exit(-1);
        }
    }
}

/// Allows use of a value inside a `&mut T` as though it was owned by the closure
///
/// The closure must return a valid T
/// # Aborts
/// Will abort the program (exiting with status code -1) if the closure panics.
pub fn take<T, F>(mut_ref: &mut T, closure: F)
  where F: FnOnce(T) -> T {
    use std::ptr;
    let aborter = AbortOnSuddenDrop::new();
    unsafe {
        let old_t = ptr::read(mut_ref);
        let new_t = closure(old_t);
        ptr::write(mut_ref, new_t);
    }
    aborter.done();
}

use std::cell::Cell;

pub struct Scope {
    active_holes: Cell<usize>
}

impl Scope {
    pub fn scope<F>(f: F)
    where F: FnOnce(&Scope) {
        let aborter = AbortOnSuddenDrop::new();
        let this = Scope { active_holes: Cell::new(0) };
        f(&this);
        if this.active_holes.get() != 0 {
            panic!("There are still unfilled Holes!");
        }
        aborter.done();
    }
    // TODO: NEED TO GUARANTEE THAT MUTABLE OBJECT IN QUESTION IS NOT A SMALLER LIFETIME
    pub fn take<'s, 'm: 's, T: 'm>(&'s self, mut_ref: &'m mut T) -> (T, Hole<'s, 'm, T>) {
        use std::ptr;

        let num_holes = self.active_holes.get();
        if num_holes == std::usize::MAX {
            panic!("Failed to create new Hole, already usize::MAX unfilled holes.");
        }
        self.active_holes.set(num_holes + 1);
        let t: T;
        let hole: Hole<'s, 'm, T>;
        unsafe {
            t = ptr::read(mut_ref);
            hole = Hole { scope: self, hole: mut_ref };
        };
        (t, hole)
    }
}

pub struct Hole<'scope, 'm, T: 'm> {
    scope: &'scope Scope,
    hole: &'m mut T
}

impl<'scope, 'm, T: 'm> Hole<'scope, 'm, T> {
    pub fn fill(self, t: T) {
        use std::ptr;

        unsafe {
            ptr::write(self.hole, t);
        }

        self.scope.active_holes.set(self.scope.active_holes.get() - 1);
    }
}

#[test]
fn it_works() {
    enum Foo {A, B};
    impl Drop for Foo {
        fn drop(&mut self) {
            match *self {
                Foo::A => println!("Foo::A dropped"),
                Foo::B => println!("Foo::B dropped")
            }
        }
    }
    let mut foo = Foo::A;
    take(&mut foo, |mut f| {
       drop(f);
       Foo::B
    });
}

#[test]
fn scope_based_take() {
    #[derive(Debug)]
    struct Foo;

    #[derive(Debug)]
    struct Bar {
        a: Foo,
        b: Foo
    }
    let mut bar = Bar { a: Foo, b: Foo };
    Scope::scope(|scope| {
        let (a, a_hole) = scope.take(&mut bar.a);
        let (b, b_hole) = scope.take(&mut bar.b);
        // Imagine consuming a and b
        a_hole.fill(Foo);
        b_hole.fill(Foo);
    });
    println!("{:?}", &bar);
}<commit_msg>Removing scope-based take for a while, which I'm currently uncertain how to make safe.<commit_after>

/// Used to ensure an abort on panic.
/// Call .done() to consume without aborting
#[derive(Debug)]
struct AbortOnSuddenDrop {
    finished: bool
}

impl AbortOnSuddenDrop {

    pub fn new() -> Self {
        AbortOnSuddenDrop { finished: false }
    }
    /// Consume `self` without aborting
    pub fn done(mut self) {
        self.finished = true;
    }
}

impl Drop for AbortOnSuddenDrop {
    fn drop(&mut self) {
        if !self.finished {
            std::process::exit(-1);
        }
    }
}

/// Allows use of a value inside a `&mut T` as though it was owned by the closure
///
/// The closure must return a valid T
/// # Aborts
/// Will abort the program (exiting with status code -1) if the closure panics.
pub fn take<T, F>(mut_ref: &mut T, closure: F)
  where F: FnOnce(T) -> T {
    use std::ptr;
    let aborter = AbortOnSuddenDrop::new();
    unsafe {
        let old_t = ptr::read(mut_ref);
        let new_t = closure(old_t);
        ptr::write(mut_ref, new_t);
    }
    aborter.done();
}

#[test]
fn it_works() {
    enum Foo {A, B};
    impl Drop for Foo {
        fn drop(&mut self) {
            match *self {
                Foo::A => println!("Foo::A dropped"),
                Foo::B => println!("Foo::B dropped")
            }
        }
    }
    let mut foo = Foo::A;
    take(&mut foo, |mut f| {
       drop(f);
       Foo::B
    });
}<|endoftext|>


<commit_before>//! Implementation of the Micro Transport Protocol.[^spec]
//!
//! [^spec]: http://www.bittorrent.org/beps/bep_0029.html

//! # Examples
//!
//! ```no_run
//! extern crate utp;
//!
//! use utp::UtpStream;
//! use std::io::{Read, Write};
//!
//! fn main() {
//!     // Connect to an hypothetical local server running on port 8080
//!     let addr = "127.0.0.1:8080";
//!     let mut stream = match UtpStream::connect(addr) {
//!         Ok(stream) => stream,
//!         Err(e) => panic!("{}", e),
//!     };
//!
//!     // Send a string
//!     match stream.write("Hi there!".as_bytes()) {
//!         Ok(_) => (),
//!         Err(e) => println!("Write failed with {}", e)
//!     }
//!
//!     // Close the stream
//!     match stream.close() {
//!         Ok(()) => println!("Connection closed"),
//!         Err(e) => println!("{}", e)
//!     }
//! }
//! ```

//   __________  ____  ____
//  /_  __/ __ \/ __ \/ __ \
//   / / / / / / / / / / / /
//  / / / /_/ / /_/ / /_/ /
// /_/  \____/_____/\____/
//
// - Lossy UDP socket for testing purposes: send and receive ops are wrappers
// that stochastically drop or reorder packets.
// - Sending FIN on drop
// - Handle packet loss
// - Path MTU discovery (RFC4821)

#![deny(missing_docs)]
#![feature(core, collections, io, old_io)]

extern crate rand;
extern crate time;
#[macro_use] extern crate log;

// Public API
pub use socket::UtpSocket;
pub use stream::UtpStream;

mod util;
mod bit_iterator;
mod packet;
mod socket;
mod stream;
<commit_msg>Remove unused feature.<commit_after>//! Implementation of the Micro Transport Protocol.[^spec]
//!
//! [^spec]: http://www.bittorrent.org/beps/bep_0029.html

//! # Examples
//!
//! ```no_run
//! extern crate utp;
//!
//! use utp::UtpStream;
//! use std::io::{Read, Write};
//!
//! fn main() {
//!     // Connect to an hypothetical local server running on port 8080
//!     let addr = "127.0.0.1:8080";
//!     let mut stream = match UtpStream::connect(addr) {
//!         Ok(stream) => stream,
//!         Err(e) => panic!("{}", e),
//!     };
//!
//!     // Send a string
//!     match stream.write("Hi there!".as_bytes()) {
//!         Ok(_) => (),
//!         Err(e) => println!("Write failed with {}", e)
//!     }
//!
//!     // Close the stream
//!     match stream.close() {
//!         Ok(()) => println!("Connection closed"),
//!         Err(e) => println!("{}", e)
//!     }
//! }
//! ```

//   __________  ____  ____
//  /_  __/ __ \/ __ \/ __ \
//   / / / / / / / / / / / /
//  / / / /_/ / /_/ / /_/ /
// /_/  \____/_____/\____/
//
// - Lossy UDP socket for testing purposes: send and receive ops are wrappers
// that stochastically drop or reorder packets.
// - Sending FIN on drop
// - Handle packet loss
// - Path MTU discovery (RFC4821)

#![deny(missing_docs)]
#![feature(core, collections, old_io)]

extern crate rand;
extern crate time;
#[macro_use] extern crate log;

// Public API
pub use socket::UtpSocket;
pub use stream::UtpStream;

mod util;
mod bit_iterator;
mod packet;
mod socket;
mod stream;
<|endoftext|>


<commit_before>//! Time handling for games and other real-time simulations.
//!
//! Provides types and helpers for dealing with time in games. `game_time` allows for
//! easy decoupling of internal "game" time and external "wall" time, as well as tracking
//! frame rate.
//!
//! Additionally, different kinds of time steps may be used, while also setting a multiplier
//! for speeding up/slowing down game time progression.
//!
//! # Usage
//! Put this in your `Cargo.toml`:
//!
//! ```toml,ignore
//! [dependencies]
//! game_time = "0.1.0"
//! ```
//!
//! # Overview
//!
//! `game_time` consists of 4 main types.
//!
//! - [`GameClock`](clock/struct.GameClock.html) provides the basic time keeping for a simulation,
//!   tracking frames and returning a `GameTime` at the beginning of each.
//! - [`GameTime`](clock/struct.GameTime.html) provides the time information for each frame.
//! - [`FrameCount`](framerate/counter/struct.FrameCount.html) objects can be optionally used to track
//!   frame rate and other runtime statistics, utilizing swappable methods for computing the
//!   average fps.
//! - [`FrameRunner`](runner/struct.FrameRunner.html) combines a `GameClock` and `FrameCount` and
//!   makes it easy to run the simulation at a given frame rate.
//!
//! For each frame, a [`TimeStep`](step/trait.TimeStep.html) is passed to `GameClock` in order
//! to advance the frame. This allows the frame rate to be changed at any time, and allows different
//! kinds of time steps (fixed, variable and a constant step are supported by default) to be used
//! based on what is most useful. Together, these objects combine to form a convenient but
//! flexible framework for time progression.
//!
//! # Examples
//!
//! Run a simulation with 50ms frames, without fps counting:
//!
//! ```rust
//! use game_time::GameClock;
//! use game_time::step;
//! use game_time::FloatDuration;
//!
//! let mut clock = GameClock::new();
//! let end_time = FloatDuration::seconds(10.0);
//! let mut sim_time = clock.last_frame_time().clone();
//! let step = step::ConstantStep::new(FloatDuration::milliseconds(50.0));
//!
//! while FloatDuration::from(sim_time.total_game_time()) < end_time {
//!     sim_time = clock.tick(&step);
//!     println!("Frame #{} at time={:?}", sim_time.frame_number(), sim_time.total_game_time());
//! }
//! ```
//!
//! Run a simulation at 30fps, sleeping if necessary to maintain the framerate:
//!
//! ```rust
//! use game_time::{GameClock, FrameCounter, FrameCount, FloatDuration};
//! use game_time::framerate::RunningAverageSampler;
//! use game_time::step;
//!
//! let mut clock = GameClock::new();
//! let mut counter = FrameCounter::new(30.0, RunningAverageSampler::with_max_samples(60));
//! let end_time = FloatDuration::seconds(10.0);
//! let mut sim_time = clock.last_frame_time().clone();
//!
//! while FloatDuration::from(sim_time.total_game_time()) < end_time {
//!     sim_time = clock.tick(&step::FixedStep::new(&counter));
//!     counter.tick(&sim_time);
//!     println!("Frame #{} at time={:?}", sim_time.frame_number(), sim_time.total_game_time());
//! }
//! ```
//!
extern crate chrono;
extern crate time;
extern crate float_duration;
#[cfg(test)]
#[macro_use]
extern crate approx;

pub mod clock;
pub mod framerate;
pub mod runner;
pub mod step;

pub use self::clock::{GameTime, GameClock};
pub use self::framerate::{FrameCounter, FrameCount, FrameRateSampler};
pub use self::runner::FrameRunner;
pub use self::step::TimeStep;

pub use float_duration::FloatDuration;
<commit_msg>Update crate level doc for changes.<commit_after>//! Time handling for games and other real-time simulations.
//!
//! Provides types and helpers for dealing with time in games. `game_time` allows for
//! easy decoupling of internal "game" time and external "wall" time, as well as tracking
//! frame rate.
//!
//! Additionally, different kinds of time steps may be used, while also setting a multiplier
//! for speeding up/slowing down game time progression.
//!
//! # Usage
//! Put this in your `Cargo.toml`:
//!
//! ```toml,ignore
//! [dependencies]
//! game_time = "0.1.0"
//! ```
//!
//! # Overview
//!
//! `game_time` consists of 4 main types.
//!
//! - [`GameClock`](clock/struct.GameClock.html) provides the basic time keeping for a simulation,
//!   tracking frames and returning a `GameTime` at the beginning of each.
//! - [`GameTime`](clock/struct.GameTime.html) provides the time information for each frame.
//! - [`FrameCount`](framerate/counter/struct.FrameCount.html) objects can be optionally used to track
//!   frame rate and other runtime statistics, utilizing swappable methods for computing the
//!   average fps.
//! - [`FrameRunner`](runner/struct.FrameRunner.html) combines a `GameClock` and `FrameCount` and
//!   makes it easy to run the simulation at a given frame rate.
//!
//! For each frame, a [`TimeStep`](step/trait.TimeStep.html) is passed to `GameClock` in order
//! to advance the frame. This allows the frame rate to be changed at any time, and allows different
//! kinds of time steps (fixed, variable and a constant step are supported by default) to be used
//! based on what is most useful. Together, these objects combine to form a convenient but
//! flexible framework for time progression.
//!
//! # Examples
//!
//! Run a simulation with 50ms frames, without fps counting:
//!
//! ```rust
//! use game_time::GameClock;
//! use game_time::step;
//! use game_time::FloatDuration;
//!
//! let mut clock = GameClock::new();
//! let end_time = FloatDuration::seconds(10.0);
//! let mut sim_time = clock.last_frame_time().clone();
//! let step = step::ConstantStep::new(FloatDuration::milliseconds(50.0));
//!
//! while sim_time.total_game_time() < end_time {
//!     sim_time = clock.tick(&step);
//!     println!("Frame #{} at time={:?}", sim_time.frame_number(), sim_time.total_game_time());
//! }
//! ```
//!
//! Run a simulation at 30fps, sleeping if necessary to maintain the framerate:
//!
//! ```rust
//! use game_time::{GameClock, FrameCounter, FrameCount, FloatDuration};
//! use game_time::framerate::RunningAverageSampler;
//! use game_time::step;
//!
//! let mut clock = GameClock::new();
//! let mut counter = FrameCounter::new(30.0, RunningAverageSampler::with_max_samples(60));
//! let end_time = FloatDuration::seconds(10.0);
//! let mut sim_time = clock.last_frame_time().clone();
//!
//! while sim_time.total_game_time() < end_time {
//!     sim_time = clock.tick(&step::FixedStep::new(&counter));
//!     counter.tick(&sim_time);
//!     println!("Frame #{} at time={:?}", sim_time.frame_number(), sim_time.total_game_time());
//! }
//! ```
//!
extern crate chrono;
extern crate time;
extern crate float_duration;
#[cfg(test)]
#[macro_use]
extern crate approx;

pub mod clock;
pub mod framerate;
pub mod runner;
pub mod step;

pub use self::clock::{GameTime, GameClock};
pub use self::framerate::{FrameCounter, FrameCount, FrameRateSampler};
pub use self::runner::FrameRunner;
pub use self::step::TimeStep;

pub use float_duration::FloatDuration;
<|endoftext|>