<commit_before>use cocoa::base::{id, nil};
use cocoa::foundation::{NSString, NSUInteger};
use error::NSError;
use objc::runtime::YES;
use objc_bringup::NSArray;
use sys::{MTLCopyAllDevices, MTLCreateSystemDefaultDevice, MTLDevice};
use std::borrow::Cow;
use std::convert::{AsRef, From};
use std::error::Error;
use std::ffi::CStr;
use std::fmt::{self, Display, Formatter};
use std::path::Path;
use {CommandQueue, CommandQueueError, CompileOptions, FromRaw, FromRawError, Library,
     LibraryError, LibraryErrorType, Size};

pub struct Device(id);

impl Device {
    pub fn system_default_device() -> Result<Self, DeviceError> {
        let device = unsafe { MTLCreateSystemDefaultDevice() };
        if device != nil { Ok(Device(device)) } else { Err(DeviceError::ConstructionFailed) }
    }

    pub fn enumerate_all_system_devices() -> Vec<Result<Self, DeviceError>> {
        let all_devices = unsafe { MTLCopyAllDevices() };
        let mut devices_vec = vec![];

        unsafe {
            for i in 0..all_devices.count() {
                let device = all_devices.objectAtIndex(i);
                if device != nil {
                    devices_vec.push(Ok(Device(device)));
                } else {
                    devices_vec.push(Err(DeviceError::ConstructionFailed));
                }
            }
        }

        devices_vec
    }

    pub fn new_command_queue(&mut self) -> Result<CommandQueue, CommandQueueError> {
        let command_queue = unsafe { self.0.newCommandQueue() };
        Ok(try!(FromRaw::from_raw(command_queue)))
    }

    pub fn new_command_queue_with_max_buffer_count(&mut self, max_command_buffer_count: usize)
                                                   -> Result<CommandQueue, CommandQueueError> {
        let command_queue = unsafe {
            self.0.newCommandQueueWithMaxCommandBufferCount(max_command_buffer_count as NSUInteger)
        };
        Ok(try!(FromRaw::from_raw(command_queue)))
    }

    // TODO(George): This will panic in the metal lib if not called from a binary in a bundle. Need
    // to add proper error checking
    pub fn new_default_library(&mut self) -> Result<Library, LibraryError> {
        unsafe {
            let library = self.0.newDefaultLibrary();
            Ok(try!(FromRaw::from_raw(library)))
        }
    }

    #[allow(unused_variables)]
    pub fn new_library_with_file<P: AsRef<Path>>(&mut self, file_path: P)
                                                 -> Result<Library, LibraryError> {
        unimplemented!();
    }

    pub fn new_library_with_source<S: AsRef<str>>(&mut self, source: S,
                                                  compile_options: &CompileOptions)
                                                  -> Result<Library, LibraryError> {
        unsafe {
            let source = NSString::alloc(nil).init_str(source.as_ref());
            let options = compile_options.mtl_compile_options();
            let mut error = nil;
            let library = self.0.newLibraryWithSource_options_error(source, options, &mut error);
            if library == nil {
                Err(LibraryError {
                    ns_error: NSError::new(error),
                    error_type: LibraryErrorType::SourceError
                })
            } else {
                Ok(try!(FromRaw::from_raw(library)))
            }
        }
    }

    #[allow(unused_variables)]
    // TODO(George): `data` parameter should be of the correct type
    pub fn new_library_with_data(&mut self, data: ()) -> Result<Library, LibraryError> {
        unimplemented!();
    }

    pub fn is_depth24_stencil8_pixel_format_supported(&self) -> bool {
        unsafe { self.0.depth24Stencil8PixelFormatSupported() == YES }
    }

    pub fn is_headless(&self) -> bool {
        unsafe { self.0.headless() == YES }
    }

    pub fn is_low_power(&self) -> bool {
        unsafe { self.0.lowPower() == YES }
    }

    pub fn max_threads_per_group(&self) -> Size {
        unsafe { self.0.maxThreadsPerGroup().into() }
    }

    pub fn name(&self) -> Cow<str> {
        unsafe { CStr::from_ptr(self.0.name().UTF8String()).to_string_lossy() }
    }

    pub fn supports_texture_sample_count(&self, sample_count: usize) -> bool {
        unsafe { self.0.supportsTextureSampleCount(sample_count as NSUInteger) == YES }
    }
}

impl_from_into_raw!(Device, of protocol "MTLDevice");

#[derive(Clone, Debug)]
pub enum DeviceError {
    ConstructionFailed,
    RawError(FromRawError)
}

impl From<FromRawError> for DeviceError {
    fn from(error: FromRawError) -> Self {
        DeviceError::RawError(error)
    }
}

impl Display for DeviceError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let descr = match *self {
            DeviceError::ConstructionFailed => "DeviceError::ConstructionFailed",
            DeviceError::RawError(_) => "DeviceError::ConstructionFailed",
        };
        write!(f, "{}", descr)
    }
}

impl Error for DeviceError {
    fn description(&self) -> &str {
        match *self {
            DeviceError::ConstructionFailed => {
                "Could not create a default device. Please ensure that you are using at least OSX \
                 10.11 or iOS 8.0"
            }
            DeviceError::RawError(_) => "There was an error with the device pointer",
        }
    }

    fn cause(&self) -> Option<&Error> {
        match self {
            &DeviceError::ConstructionFailed => None,
            &DeviceError::RawError(ref raw_err) => Some(raw_err),
        }
    }
}
<commit_msg>Pass AsRef<_> objects by trait reference rather than generics<commit_after>use cocoa::base::{id, nil};
use cocoa::foundation::{NSString, NSUInteger};
use error::NSError;
use objc::runtime::YES;
use objc_bringup::NSArray;
use sys::{MTLCopyAllDevices, MTLCreateSystemDefaultDevice, MTLDevice};
use std::borrow::Cow;
use std::convert::{AsRef, From};
use std::error::Error;
use std::ffi::CStr;
use std::fmt::{self, Display, Formatter};
use std::path::Path;
use {CommandQueue, CommandQueueError, CompileOptions, FromRaw, FromRawError, Library,
     LibraryError, LibraryErrorType, Size};

pub struct Device(id);

impl Device {
    pub fn system_default_device() -> Result<Self, DeviceError> {
        let device = unsafe { MTLCreateSystemDefaultDevice() };
        if device != nil { Ok(Device(device)) } else { Err(DeviceError::ConstructionFailed) }
    }

    pub fn enumerate_all_system_devices() -> Vec<Result<Self, DeviceError>> {
        let all_devices = unsafe { MTLCopyAllDevices() };
        let mut devices_vec = vec![];

        unsafe {
            for i in 0..all_devices.count() {
                let device = all_devices.objectAtIndex(i);
                if device != nil {
                    devices_vec.push(Ok(Device(device)));
                } else {
                    devices_vec.push(Err(DeviceError::ConstructionFailed));
                }
            }
        }

        devices_vec
    }

    pub fn new_command_queue(&mut self) -> Result<CommandQueue, CommandQueueError> {
        let command_queue = unsafe { self.0.newCommandQueue() };
        Ok(try!(FromRaw::from_raw(command_queue)))
    }

    pub fn new_command_queue_with_max_buffer_count(&mut self, max_command_buffer_count: usize)
                                                   -> Result<CommandQueue, CommandQueueError> {
        let command_queue = unsafe {
            self.0.newCommandQueueWithMaxCommandBufferCount(max_command_buffer_count as NSUInteger)
        };
        Ok(try!(FromRaw::from_raw(command_queue)))
    }

    // TODO(George): This will panic in the metal lib if not called from a binary in a bundle. Need
    // to add proper error checking
    pub fn new_default_library(&mut self) -> Result<Library, LibraryError> {
        unsafe {
            let library = self.0.newDefaultLibrary();
            Ok(try!(FromRaw::from_raw(library)))
        }
    }

    #[allow(unused_variables)]
    pub fn new_library_with_file(&mut self, file_path: &AsRef<Path>) -> Result<Library, LibraryError> {
        unimplemented!();
    }

    pub fn new_library_with_source(&mut self, source: &AsRef<str>,
                                                  compile_options: &CompileOptions)
                                                  -> Result<Library, LibraryError> {
        unsafe {
            let source = NSString::alloc(nil).init_str(source.as_ref());
            let options = compile_options.mtl_compile_options();
            let mut error = nil;
            let library = self.0.newLibraryWithSource_options_error(source, options, &mut error);
            if library == nil {
                Err(LibraryError {
                    ns_error: NSError::new(error),
                    error_type: LibraryErrorType::SourceError
                })
            } else {
                Ok(try!(FromRaw::from_raw(library)))
            }
        }
    }

    #[allow(unused_variables)]
    // TODO(George): `data` parameter should be of the correct type
    pub fn new_library_with_data(&mut self, data: ()) -> Result<Library, LibraryError> {
        unimplemented!();
    }

    pub fn is_depth24_stencil8_pixel_format_supported(&self) -> bool {
        unsafe { self.0.depth24Stencil8PixelFormatSupported() == YES }
    }

    pub fn is_headless(&self) -> bool {
        unsafe { self.0.headless() == YES }
    }

    pub fn is_low_power(&self) -> bool {
        unsafe { self.0.lowPower() == YES }
    }

    pub fn max_threads_per_group(&self) -> Size {
        unsafe { self.0.maxThreadsPerGroup().into() }
    }

    pub fn name(&self) -> Cow<str> {
        unsafe { CStr::from_ptr(self.0.name().UTF8String()).to_string_lossy() }
    }

    pub fn supports_texture_sample_count(&self, sample_count: usize) -> bool {
        unsafe { self.0.supportsTextureSampleCount(sample_count as NSUInteger) == YES }
    }
}

impl_from_into_raw!(Device, of protocol "MTLDevice");

#[derive(Clone, Debug)]
pub enum DeviceError {
    ConstructionFailed,
    RawError(FromRawError)
}

impl From<FromRawError> for DeviceError {
    fn from(error: FromRawError) -> Self {
        DeviceError::RawError(error)
    }
}

impl Display for DeviceError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let descr = match *self {
            DeviceError::ConstructionFailed => "DeviceError::ConstructionFailed",
            DeviceError::RawError(_) => "DeviceError::ConstructionFailed",
        };
        write!(f, "{}", descr)
    }
}

impl Error for DeviceError {
    fn description(&self) -> &str {
        match *self {
            DeviceError::ConstructionFailed => {
                "Could not create a default device. Please ensure that you are using at least OSX \
                 10.11 or iOS 8.0"
            }
            DeviceError::RawError(_) => "There was an error with the device pointer",
        }
    }

    fn cause(&self) -> Option<&Error> {
        match self {
            &DeviceError::ConstructionFailed => None,
            &DeviceError::RawError(ref raw_err) => Some(raw_err),
        }
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use azure::azure_hl::Color;
use geom::point::Point2D;
use geom::rect::Rect;
use layers::platform::surface::NativeGraphicsMetadata;
use layers::layers::LayerBufferSet;
use std::fmt::{Formatter, Show};
use std::fmt;

use constellation_msg::PipelineId;

/// The status of the painter.
#[deriving(PartialEq, Clone)]
pub enum PaintState {
    IdlePaintState,
    PaintingPaintState,
}

#[deriving(Eq, Ord, PartialEq, PartialOrd, Clone)]
pub enum ReadyState {
    /// Informs the compositor that nothing has been done yet. Used for setting status
    Blank,
    /// Informs the compositor that a page is loading. Used for setting status
    Loading,
    /// Informs the compositor that a page is performing layout. Used for setting status
    PerformingLayout,
    /// Informs the compositor that a page is finished loading. Used for setting status
    FinishedLoading,
}

/// A newtype struct for denoting the age of messages; prevents race conditions.
#[deriving(PartialEq, Show)]
pub struct Epoch(pub uint);

impl Epoch {
    pub fn next(&mut self) {
        let Epoch(ref mut u) = *self;
        *u += 1;
    }
}

#[deriving(Clone, PartialEq)]
pub struct LayerId(pub uint, pub uint);

impl Show for LayerId {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let LayerId(a, b) = *self;
        write!(f, "Layer({}, {})", a, b)
    }
}

impl LayerId {
    /// FIXME(#2011, pcwalton): This is unfortunate. Maybe remove this in the future.
    pub fn null() -> LayerId {
        LayerId(0, 0)
    }
}

/// The scrolling policy of a layer.
#[deriving(Clone, PartialEq)]
pub enum ScrollPolicy {
    /// These layers scroll when the parent receives a scrolling message.
    Scrollable,
    /// These layers do not scroll when the parent receives a scrolling message.
    FixedPosition,
}

/// All layer-specific information that the painting task sends to the compositor other than the
/// buffer contents of the layer itself.
pub struct LayerMetadata {
    /// An opaque ID. This is usually the address of the flow and index of the box within it.
    pub id: LayerId,
    /// The position and size of the layer in pixels.
    pub position: Rect<uint>,
    /// The background color of the layer.
    pub background_color: Color,
    /// The scrolling policy of this layer.
    pub scroll_policy: ScrollPolicy,
}

/// The interface used by the renderer to acquire draw targets for each render frame and
/// submit them to be drawn to the display.
pub trait PaintListener for Sized? {
    fn get_graphics_metadata(&mut self) -> Option<NativeGraphicsMetadata>;

    /// Informs the compositor of the layers for the given pipeline. The compositor responds by
    /// creating and/or destroying render layers as necessary.
    fn initialize_layers_for_pipeline(&mut self,
                                      pipeline_id: PipelineId,
                                      metadata: Vec<LayerMetadata>,
                                      epoch: Epoch);

    /// Sends new tiles for the given layer to the compositor.
    fn paint(&mut self,
             pipeline_id: PipelineId,
             epoch: Epoch,
             replies: Vec<(LayerId, Box<LayerBufferSet>)>);

    fn paint_msg_discarded(&mut self);
    fn set_paint_state(&mut self, PipelineId, PaintState);
}

/// The interface used by the script task to tell the compositor to update its ready state,
/// which is used in displaying the appropriate message in the window's title.
pub trait ScriptListener {
    fn set_ready_state(&mut self, PipelineId, ReadyState);
    fn scroll_fragment_point(&mut self,
                             pipeline_id: PipelineId,
                             layer_id: LayerId,
                             point: Point2D<f32>);
    fn close(&mut self);
    fn dup(&mut self) -> Box<ScriptListener+'static>;
}
<commit_msg>Replace 'render' to 'paint' in compositor_msg.rs<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use azure::azure_hl::Color;
use geom::point::Point2D;
use geom::rect::Rect;
use layers::platform::surface::NativeGraphicsMetadata;
use layers::layers::LayerBufferSet;
use std::fmt::{Formatter, Show};
use std::fmt;

use constellation_msg::PipelineId;

/// The status of the painter.
#[deriving(PartialEq, Clone)]
pub enum PaintState {
    IdlePaintState,
    PaintingPaintState,
}

#[deriving(Eq, Ord, PartialEq, PartialOrd, Clone)]
pub enum ReadyState {
    /// Informs the compositor that nothing has been done yet. Used for setting status
    Blank,
    /// Informs the compositor that a page is loading. Used for setting status
    Loading,
    /// Informs the compositor that a page is performing layout. Used for setting status
    PerformingLayout,
    /// Informs the compositor that a page is finished loading. Used for setting status
    FinishedLoading,
}

/// A newtype struct for denoting the age of messages; prevents race conditions.
#[deriving(PartialEq, Show)]
pub struct Epoch(pub uint);

impl Epoch {
    pub fn next(&mut self) {
        let Epoch(ref mut u) = *self;
        *u += 1;
    }
}

#[deriving(Clone, PartialEq)]
pub struct LayerId(pub uint, pub uint);

impl Show for LayerId {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let LayerId(a, b) = *self;
        write!(f, "Layer({}, {})", a, b)
    }
}

impl LayerId {
    /// FIXME(#2011, pcwalton): This is unfortunate. Maybe remove this in the future.
    pub fn null() -> LayerId {
        LayerId(0, 0)
    }
}

/// The scrolling policy of a layer.
#[deriving(Clone, PartialEq)]
pub enum ScrollPolicy {
    /// These layers scroll when the parent receives a scrolling message.
    Scrollable,
    /// These layers do not scroll when the parent receives a scrolling message.
    FixedPosition,
}

/// All layer-specific information that the painting task sends to the compositor other than the
/// buffer contents of the layer itself.
pub struct LayerMetadata {
    /// An opaque ID. This is usually the address of the flow and index of the box within it.
    pub id: LayerId,
    /// The position and size of the layer in pixels.
    pub position: Rect<uint>,
    /// The background color of the layer.
    pub background_color: Color,
    /// The scrolling policy of this layer.
    pub scroll_policy: ScrollPolicy,
}

/// The interface used by the painter to acquire draw targets for each paint frame and
/// submit them to be drawn to the display.
pub trait PaintListener for Sized? {
    fn get_graphics_metadata(&mut self) -> Option<NativeGraphicsMetadata>;

    /// Informs the compositor of the layers for the given pipeline. The compositor responds by
    /// creating and/or destroying paint layers as necessary.
    fn initialize_layers_for_pipeline(&mut self,
                                      pipeline_id: PipelineId,
                                      metadata: Vec<LayerMetadata>,
                                      epoch: Epoch);

    /// Sends new tiles for the given layer to the compositor.
    fn paint(&mut self,
             pipeline_id: PipelineId,
             epoch: Epoch,
             replies: Vec<(LayerId, Box<LayerBufferSet>)>);

    fn paint_msg_discarded(&mut self);
    fn set_paint_state(&mut self, PipelineId, PaintState);
}

/// The interface used by the script task to tell the compositor to update its ready state,
/// which is used in displaying the appropriate message in the window's title.
pub trait ScriptListener {
    fn set_ready_state(&mut self, PipelineId, ReadyState);
    fn scroll_fragment_point(&mut self,
                             pipeline_id: PipelineId,
                             layer_id: LayerId,
                             point: Point2D<f32>);
    fn close(&mut self);
    fn dup(&mut self) -> Box<ScriptListener+'static>;
}
<|endoftext|>


<commit_before>// run-pass

#![feature(option_expect_none, option_unwrap_none)]

//! Test that panic locations for `#[track_caller]` functions in std have the correct
//! location reported.

fn main() {
    // inspect the `PanicInfo` we receive to ensure the right file is the source
    std::panic::set_hook(Box::new(|info| {
        let actual = info.location().unwrap();
        if actual.file() != file!() {
            eprintln!("expected a location in the test file, found {:?}", actual);
            panic!();
        }
    }));

    fn assert_panicked(f: impl FnOnce() + std::panic::UnwindSafe) {
        std::panic::catch_unwind(f).unwrap_err();
    }

    let nope: Option<()> = None;
    assert_panicked(|| nope.unwrap());
    assert_panicked(|| nope.expect(""));

    let yep: Option<()> = Some(());
    assert_panicked(|| yep.unwrap_none());
    assert_panicked(|| yep.expect_none(""));

    let oops: Result<(), ()> = Err(());
    assert_panicked(|| oops.unwrap());
    assert_panicked(|| oops.expect(""));

    let fine: Result<(), ()> = Ok(());
    assert_panicked(|| fine.unwrap_err());
    assert_panicked(|| fine.expect_err(""));
}
<commit_msg>Skip caller location test in wasm32.<commit_after>// run-pass
// ignore-wasm32-bare compiled with panic=abort by default

#![feature(option_expect_none, option_unwrap_none)]

//! Test that panic locations for `#[track_caller]` functions in std have the correct
//! location reported.

fn main() {
    // inspect the `PanicInfo` we receive to ensure the right file is the source
    std::panic::set_hook(Box::new(|info| {
        let actual = info.location().unwrap();
        if actual.file() != file!() {
            eprintln!("expected a location in the test file, found {:?}", actual);
            panic!();
        }
    }));

    fn assert_panicked(f: impl FnOnce() + std::panic::UnwindSafe) {
        std::panic::catch_unwind(f).unwrap_err();
    }

    let nope: Option<()> = None;
    assert_panicked(|| nope.unwrap());
    assert_panicked(|| nope.expect(""));

    let yep: Option<()> = Some(());
    assert_panicked(|| yep.unwrap_none());
    assert_panicked(|| yep.expect_none(""));

    let oops: Result<(), ()> = Err(());
    assert_panicked(|| oops.unwrap());
    assert_panicked(|| oops.expect(""));

    let fine: Result<(), ()> = Ok(());
    assert_panicked(|| fine.unwrap_err());
    assert_panicked(|| fine.expect_err(""));
}
<|endoftext|>


<commit_before>use error_chain::ChainedError;
use ffmpeg_sys;
use std::sync::RwLock;

use avcodec;
use errors::*;

lazy_static! {
    static ref VIDEO_ENCODER: RwLock<Option<avcodec::Codec>> = RwLock::new(None);
}

/// Initialize the encoding stuff. Should be called once.
pub fn initialize() -> Result<()> {
    avcodec::initialize();

    Ok(())
}

command!(cap_set_video_encoder, |engine| {
    let mut args = engine.args();

    if args.len() != 2 {
        let mut buf = String::new();

        buf.push_str("Usage:\n");
        buf.push_str("    cap_set_video_encoder <encoder>\n");
        buf.push_str("     - Set the video encoder by name.\n");
        buf.push_str("Example:\n");
        buf.push_str("    cap_set_video_encoder libx264\n");

        engine.con_print(&buf);
        return;
    }

    let encoder_name = args.nth(1).unwrap();
    match avcodec::find_encoder_by_name(&encoder_name) {
        Ok(Some(encoder)) => {
            if encoder.is_video() {
                let mut buf = String::new();

                buf.push_str(&format!("Encoder: {}\n", encoder_name));
                buf.push_str(&format!("Description: {}\n", encoder.description()));
                buf.push_str("Pixel formats: ");

                if let Some(formats) = encoder.pixel_formats() {
                    buf.push_str(&format!("{:?}\n", formats.collect::<Vec<_>>()));
                } else {
                    buf.push_str("any\n");
                }

                engine.con_print(&buf);

                *VIDEO_ENCODER.write().unwrap() = Some(encoder);
            } else {
                engine.con_print(&format!("Invalid encoder type '{}'\n", encoder_name));
            }
        }

        Ok(None) => {
            engine.con_print(&format!("Unknown encoder '{}'\n", encoder_name));
        },

        Err(ref e) => {
            engine.con_print(&format!("{}", e.display()));
        }
    }
});

command!(cap_test_video_output, |engine| {
    if let Err(ref e) = test_video_output() {
        engine.con_print(&format!("{}", e.display()));
        return;
    }

    engine.con_print("Done!\n");
});

fn test_video_output() -> Result<()> {
    let codec = *VIDEO_ENCODER.read().unwrap();
    ensure!(codec.is_some(), "codec is None");
    let codec = codec.unwrap();

    let mut context = codec.context()
        .chain_err(|| "unable to get the codec context")?;

    context.set_width(640);
    context.set_height(360);
    context.set_time_base(&(1, 60).into());
    context.set_pixel_format(ffmpeg_sys::AVPixelFormat::AV_PIX_FMT_YUV420P);

    // Get ready for encoding.
    let context = context.open();

    Ok(())
}
<commit_msg>Add missing error handling to context opening<commit_after>use error_chain::ChainedError;
use ffmpeg_sys;
use std::sync::RwLock;

use avcodec;
use errors::*;

lazy_static! {
    static ref VIDEO_ENCODER: RwLock<Option<avcodec::Codec>> = RwLock::new(None);
}

/// Initialize the encoding stuff. Should be called once.
pub fn initialize() -> Result<()> {
    avcodec::initialize();

    Ok(())
}

command!(cap_set_video_encoder, |engine| {
    let mut args = engine.args();

    if args.len() != 2 {
        let mut buf = String::new();

        buf.push_str("Usage:\n");
        buf.push_str("    cap_set_video_encoder <encoder>\n");
        buf.push_str("     - Set the video encoder by name.\n");
        buf.push_str("Example:\n");
        buf.push_str("    cap_set_video_encoder libx264\n");

        engine.con_print(&buf);
        return;
    }

    let encoder_name = args.nth(1).unwrap();
    match avcodec::find_encoder_by_name(&encoder_name) {
        Ok(Some(encoder)) => {
            if encoder.is_video() {
                let mut buf = String::new();

                buf.push_str(&format!("Encoder: {}\n", encoder_name));
                buf.push_str(&format!("Description: {}\n", encoder.description()));
                buf.push_str("Pixel formats: ");

                if let Some(formats) = encoder.pixel_formats() {
                    buf.push_str(&format!("{:?}\n", formats.collect::<Vec<_>>()));
                } else {
                    buf.push_str("any\n");
                }

                engine.con_print(&buf);

                *VIDEO_ENCODER.write().unwrap() = Some(encoder);
            } else {
                engine.con_print(&format!("Invalid encoder type '{}'\n", encoder_name));
            }
        }

        Ok(None) => {
            engine.con_print(&format!("Unknown encoder '{}'\n", encoder_name));
        },

        Err(ref e) => {
            engine.con_print(&format!("{}", e.display()));
        }
    }
});

command!(cap_test_video_output, |engine| {
    if let Err(ref e) = test_video_output() {
        engine.con_print(&format!("{}", e.display()));
        return;
    }

    engine.con_print("Done!\n");
});

fn test_video_output() -> Result<()> {
    let codec = *VIDEO_ENCODER.read().unwrap();
    ensure!(codec.is_some(), "codec is None");
    let codec = codec.unwrap();

    let mut context = codec.context()
        .chain_err(|| "unable to get the codec context")?;

    context.set_width(640);
    context.set_height(360);
    context.set_time_base(&(1, 60).into());
    context.set_pixel_format(ffmpeg_sys::AVPixelFormat::AV_PIX_FMT_YUV420P);

    // Get ready for encoding.
    let context = context.open()
        .chain_err(|| "could not open context for encoding")?;

    Ok(())
}
<|endoftext|>


<commit_before>use std::thread;
use std::time::{Duration, Instant};

use sdl2;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;

use sdl2::pixels::Color;
use sdl2::rect::Rect; // TODO: abstract my own drawtypes?
use sdl2::render::Texture;

use graphics::Display;
use input::Input;
use units::V2;

pub static COLOR_BG: Color  = Color::RGB(0,0,0);
pub static COLOR_FPS: Color = Color::RGB(255,255,0);
pub static COLOR_PEN: Color = Color::RGB(125, 0, 175);

#[derive(Copy, Clone, Debug)]
enum BrushMode {
    Normal,
    Squareish,
    WowSoEdgy,
}

pub struct Engine {
	context:     sdl2::Sdl,
	controller:  Input,
	display:     Display,

    brush:   BrushMode,
    color:   (u8,u8,u8),
    cursor:  (i32,i32),
    scanbox: V2,
}

impl Engine {
    pub fn new(context: sdl2::Sdl) -> Engine {
        let video_renderer = Display::new(&context);

        Engine {
            context:    context,
            controller: Input::new(),
            display:    video_renderer,

            brush:   BrushMode::Normal,
            color:   (125,0,175),
            cursor:  (0,0),
            scanbox: V2(0,0),
        }
    }

    pub fn run(&mut self) {
        let target_fps_ms  = Duration::from_millis(1000 / 120); // TODO: const fn?

		let mut event_pump = self.context.event_pump().unwrap();
        let mut is_running = true;

        let mut frame_start_at;
        let mut elapsed_time = Duration::from_millis(0);

        // drawing state
        let mut regions = vec![];
        for _ in 0..9 {
            let mut texture = Some(self.display.get_texture(1280,720));
            Engine::with_texture(&mut self.display, &mut texture, |io| {
                io.clear_buffer();
                io.fill_rect(Rect::new(0,0,1280,5),   Color::RGB(255,0,0));  // top
                io.fill_rect(Rect::new(0,715,1280,5), Color::RGB(255,0,0));  // bottom
                io.fill_rect(Rect::new(0,0,5,720),    Color::RGB(255,0,0) ); // left
                io.fill_rect(Rect::new(1275,0,5,720), Color::RGB(255,0,0));  // right
            });

            regions.push(texture);
        }

        let mut mouse_clicked = false;
        let mut last_point = None;

        // init bitmap to good state
        //

        while is_running {
            frame_start_at  = Instant::now();

			// drain input event queue once per frame
			self.controller.begin_new_frame();
			for event in event_pump.poll_iter() {
				match event {
					Event::KeyDown { keycode, .. } => {
						self.controller.key_down_event(keycode.unwrap());
					},

					Event::KeyUp { keycode, .. } => {
						self.controller.key_up_event(keycode.unwrap());
					},

                    Event::MouseMotion { x, y, .. } => self.cursor = (x,y),

                    Event::MouseButtonDown { .. } => mouse_clicked = true,
                    Event::MouseButtonUp   { .. } => mouse_clicked = false,

					_ => {},
				}
			}

            // handle exit game
			if self.controller.was_key_released(Keycode::Escape) { is_running = false; }

            // erase canvas
            if self.controller.was_key_released(Keycode::E) {
                Engine::with_texture(&mut self.display, &mut regions[0], |io| { io.clear_buffer() });
            }

            // switch brush
            if self.controller.was_key_released(Keycode::B) {
                self.brush = match self.brush { // TODO: better cycle?
                    BrushMode::Normal    => BrushMode::Squareish,
                    BrushMode::Squareish => BrushMode::WowSoEdgy,
                    BrushMode::WowSoEdgy => BrushMode::Squareish,
                }
            }

            if self.controller.is_key_held(Keycode::I) {
                self.color.0 = self.color.0.wrapping_add(0x01);
            } else if self.controller.is_key_held(Keycode::O) {
                self.color.1 = self.color.1.wrapping_add(0x01);
            } else if self.controller.is_key_held(Keycode::P) {
                self.color.2 = self.color.2.wrapping_add(0x01);
            }

            if self.controller.is_key_held(Keycode::Up) {
                self.scanbox = self.scanbox - V2(0, 1);
            } else if self.controller.is_key_held(Keycode::Down) {
                self.scanbox = self.scanbox + V2(0, 1);
            } else if self.controller.is_key_held(Keycode::Left) {
                self.scanbox = self.scanbox - V2(1, 0);
            } else if self.controller.is_key_held(Keycode::Right) {
                self.scanbox = self.scanbox + V2(1, 0);
            }

            let brush_color = Color::RGB(self.color.0, self.color.1, self.color.2);
            if mouse_clicked {
                let (x2,y2) = self.cursor;

                if let Some((x1,y1)) = last_point {

                    let brush = self.brush;
                    Engine::with_texture(&mut self.display, &mut regions[0], |display| {
                        match brush {
                            BrushMode::WowSoEdgy => for i in 0..10 {
                                display.draw_line(x1+i, y1, x2, y2+i, brush_color);
                            },

                            BrushMode::Squareish => for i in 0..5 {
                                display.draw_line(x1+i, y1, x2+i, y2, brush_color);
                            },

                            BrushMode::Normal => {},
                        }
                    });

                    // let diffx = x2 - x1;
                    // let diffy = y2 - y1;
                    // println!("delta ({},{}), mag: {}", diffx, diffy, diffy-diffx);
                } // NOTE: doesn't draw point if mouse held for single frame

                last_point = Some((x2,y2));
           } else { last_point = None; }

            // handle draw calls
			self.display.clear_buffer(); // clear back-buffer
            self.draw_regions(&mut regions);
            self.draw_cursor(brush_color);
            self.draw_debug(elapsed_time);
			self.display.switch_buffers();

            // sleep for <target> - <draw time> and floor to zero
            elapsed_time = frame_start_at.elapsed();
            let sleep_time = if elapsed_time > target_fps_ms {
                Duration::from_millis(0)
            } else { target_fps_ms - elapsed_time };

            thread::sleep(sleep_time);
        }
    }

    // HACK: pulls texture out of an option and gives you a closure in which
    // you can use renderer calls to blit to it ...
    //
    fn with_texture<F>(io: &mut Display, target: &mut Option<Texture>, mut mutator: F)
        where F: FnMut(&mut Display) -> () {

        let _last = io.retarget().set(target.take().unwrap());
        mutator(io);
        *target = io.retarget().reset()
                        .ok().expect("did not get target back");
    }

    fn draw_cursor(&mut self, brush_color: Color) {
        self.display.fill_rect(Rect::new(self.cursor.0, self.cursor.1, 10, 10), brush_color);
    }

    fn draw_debug(&mut self, time: Duration) {
        let mut time_ms = time.as_secs() * 1000;        // -> millis
        time_ms += time.subsec_nanos() as u64 / (1000 * 1000); // /> micros /> millis

        let (hue_r, hue_g, hue_b) = self.color;
        let buf = format!("{}ms, sb @ {:?}, e = erase all, b = brush ({:?}), hue(i,o,p) => ({:x},{:x},{:x})",
                          time_ms,
                          self.scanbox,
                          self.brush,
                          hue_r, hue_g, hue_b);
        self.display.blit_text(&buf[..], COLOR_FPS);
    }

    fn draw_regions(&mut self, regions: &mut Vec<Option<Texture>>) {
        let V2(ofs_x, ofs_y) = self.scanbox;

        for row in 0..3 {
            for col in 0..3 {
                // (0,0), (0, 720)
                let x = (col * 1280) as i32;
                let y = (row *  720) as i32;
                let ridx = col + (row * 3);

                println!("drawing [{}] at ({},{})", ridx, x, y);
                self.display.copy_t(regions[ridx].as_ref().unwrap(),
                    Rect::new(0, 0, 1280, 720),
                    Rect::new(x - ofs_x as i32, y - ofs_y as i32, 1280, 720));
            }
        }
    }
}
<commit_msg>actually draw in proper region while panned<commit_after>use std::thread;
use std::time::{Duration, Instant};

use sdl2;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;

use sdl2::pixels::Color;
use sdl2::rect::Rect; // TODO: abstract my own drawtypes?
use sdl2::render::Texture;

use graphics::Display;
use input::Input;
use units::V2;

pub static COLOR_BG: Color  = Color::RGB(0,0,0);
pub static COLOR_FPS: Color = Color::RGB(255,255,0);
pub static COLOR_PEN: Color = Color::RGB(125, 0, 175);

#[derive(Copy, Clone, Debug)]
enum BrushMode {
    Normal,
    Squareish,
    WowSoEdgy,
}

pub struct Engine {
	context:     sdl2::Sdl,
	controller:  Input,
	display:     Display,

    brush:   BrushMode,
    color:   (u8,u8,u8),
    cursor:  (i32,i32),
    scanbox: V2,
}

impl Engine {
    pub fn new(context: sdl2::Sdl) -> Engine {
        let video_renderer = Display::new(&context);

        Engine {
            context:    context,
            controller: Input::new(),
            display:    video_renderer,

            brush:   BrushMode::Squareish,
            color:   (125,0,175),
            cursor:  (0,0),
            scanbox: V2(0,0),
        }
    }

    pub fn run(&mut self) {
        let target_fps_ms  = Duration::from_millis(1000 / 120); // TODO: const fn?

		let mut event_pump = self.context.event_pump().unwrap();
        let mut is_running = true;

        let mut frame_start_at;
        let mut elapsed_time = Duration::from_millis(0);

        // drawing state
        let mut regions = vec![];
        for _ in 0..9 {
            let mut texture = Some(self.display.get_texture(1280,720));
            Engine::with_texture(&mut self.display, &mut texture, |io| {
                io.clear_buffer();
                io.fill_rect(Rect::new(0,0,1280,5),   Color::RGB(255,0,0));  // top
                io.fill_rect(Rect::new(0,715,1280,5), Color::RGB(255,0,0));  // bottom
                io.fill_rect(Rect::new(0,0,5,720),    Color::RGB(255,0,0) ); // left
                io.fill_rect(Rect::new(1275,0,5,720), Color::RGB(255,0,0));  // right
            });

            regions.push(texture);
        }

        let mut mouse_clicked = false;
        let mut last_point = None;

        // init bitmap to good state
        //

        while is_running {
            frame_start_at  = Instant::now();

			// drain input event queue once per frame
			self.controller.begin_new_frame();
			for event in event_pump.poll_iter() {
				match event {
					Event::KeyDown { keycode, .. } => {
						self.controller.key_down_event(keycode.unwrap());
					},

					Event::KeyUp { keycode, .. } => {
						self.controller.key_up_event(keycode.unwrap());
					},

                    Event::MouseMotion { x, y, .. } => self.cursor = (x,y),

                    Event::MouseButtonDown { .. } => mouse_clicked = true,
                    Event::MouseButtonUp   { .. } => mouse_clicked = false,

					_ => {},
				}
			}

            // handle exit game
			if self.controller.was_key_released(Keycode::Escape) { is_running = false; }

            // erase canvas
            if self.controller.was_key_released(Keycode::E) {
                for region in regions.iter_mut() {
                    Engine::with_texture(&mut self.display, region, |io| {
                        io.clear_buffer();
                        io.fill_rect(Rect::new(0,0,1280,5),   Color::RGB(255,0,0));  // top
                        io.fill_rect(Rect::new(0,715,1280,5), Color::RGB(255,0,0));  // bottom
                        io.fill_rect(Rect::new(0,0,5,720),    Color::RGB(255,0,0) ); // left
                        io.fill_rect(Rect::new(1275,0,5,720), Color::RGB(255,0,0));  // right
                    });
                }
            }

            // switch brush
            if self.controller.was_key_released(Keycode::B) {
                self.brush = match self.brush { // TODO: better cycle?
                    BrushMode::Normal    => BrushMode::Squareish,
                    BrushMode::Squareish => BrushMode::WowSoEdgy,
                    BrushMode::WowSoEdgy => BrushMode::Squareish,
                }
            }

            if self.controller.is_key_held(Keycode::I) {
                self.color.0 = self.color.0.wrapping_add(0x01);
            } else if self.controller.is_key_held(Keycode::O) {
                self.color.1 = self.color.1.wrapping_add(0x01);
            } else if self.controller.is_key_held(Keycode::P) {
                self.color.2 = self.color.2.wrapping_add(0x01);
            }

            if self.controller.is_key_held(Keycode::Up) {
                self.scanbox = self.scanbox - V2(0, 5);
            } else if self.controller.is_key_held(Keycode::Down) {
                self.scanbox = self.scanbox + V2(0, 5);
            } else if self.controller.is_key_held(Keycode::Left) {
                self.scanbox = self.scanbox - V2(5, 0);
            } else if self.controller.is_key_held(Keycode::Right) {
                self.scanbox = self.scanbox + V2(5, 0);
            }

            let brush_color = Color::RGB(self.color.0, self.color.1, self.color.2);
            if mouse_clicked {
                let (x2,y2) = self.cursor;

                if let Some((x1,y1)) = last_point {
                    let brush = self.brush;
                    let V2(ofs_x, ofs_y) = self.scanbox;

                    let x1 = x1 + ofs_x as i32;
                    let x2 = x2 + ofs_x as i32;
                    let y1 = y1 + ofs_y as i32;
                    let y2 = y2 + ofs_y as i32;

                    Engine::with_texture(&mut self.display, &mut regions[0], |display| {
                        match brush {
                            BrushMode::WowSoEdgy => for i in 0..10 {
                                display.draw_line(x1+i, y1, x2, y2+i, brush_color);
                            },

                            BrushMode::Squareish => for i in 0..5 {
                                display.draw_line(x1+i, y1, x2+i, y2, brush_color);
                            },

                            BrushMode::Normal => {},
                        }
                    });

                    if (x1 > 1280 || y1 > 720) {
                        // compute ridx
                        let col  = x1 / 1280;
                        let row  = y1 / 720;
                        let ridx = (row * 3) + col; // row * 3rows/col + col

                        println!("[{}], row: {}, col: {}", ridx, row, col);

                        println!("real ({},{})=>({},{})", x1, y1, x2, y2);

                        let (x1,x2) = if (x1 > 1280) {
                            let x1 = x1 % (1280 * col+1);
                            let x2 = x2 % (1280 * col+1);
                            (x1,x2)
                        } else { (x1,x2) };

                        let (y1,y2) = if (y1 > 720) {
                            let y1 = y1 % ( 720 * row+1);
                            let y2 = y2 % ( 720 * row+1);
                            (y1,y2)
                        } else { (y1,y2) };

                        println!("adj ({},{})=>({},{})", x1, y1, x2, y2);

                        Engine::with_texture(&mut self.display, &mut regions[ridx as usize], |display| {
                            match brush {
                                BrushMode::WowSoEdgy => for i in 0..10 {
                                    display.draw_line(x1+i, y1, x2, y2+i, brush_color);
                                },

                                BrushMode::Squareish => for i in 0..5 {
                                    display.draw_line(x1+i, y1, x2+i, y2, brush_color);
                                },

                                BrushMode::Normal => {},
                            }
                        });
                    }

                    // let diffx = x2 - x1;
                    // let diffy = y2 - y1;
                    // println!("delta ({},{}), mag: {}", diffx, diffy, diffy-diffx);
                } // NOTE: doesn't draw point if mouse held for single frame

                last_point = Some((x2,y2));
           } else { last_point = None; }

            // handle draw calls
			self.display.clear_buffer(); // clear back-buffer
            self.draw_regions(&mut regions);
            self.draw_cursor(brush_color);
            self.draw_debug(elapsed_time, regions.len());
			self.display.switch_buffers();

            // sleep for <target> - <draw time> and floor to zero
            elapsed_time = frame_start_at.elapsed();
            let sleep_time = if elapsed_time > target_fps_ms {
                Duration::from_millis(0)
            } else { target_fps_ms - elapsed_time };

            thread::sleep(sleep_time);
        }
    }

    // HACK: pulls texture out of an option and gives you a closure in which
    // you can use renderer calls to blit to it ...
    //
    fn with_texture<F>(io: &mut Display, target: &mut Option<Texture>, mut mutator: F)
        where F: FnMut(&mut Display) -> () {

        let _last = io.retarget().set(target.take().unwrap());
        mutator(io);
        *target = io.retarget().reset()
                        .ok().expect("did not get target back");
    }

    fn draw_cursor(&mut self, brush_color: Color) {
        self.display.fill_rect(Rect::new(self.cursor.0, self.cursor.1, 10, 10), brush_color);
    }

    fn draw_debug(&mut self, time: Duration, num_regions: usize) {
        let mut time_ms = time.as_secs() * 1000;        // -> millis
        time_ms += time.subsec_nanos() as u64 / (1000 * 1000); // /> micros /> millis

        let (hue_r, hue_g, hue_b) = self.color;
        let buf = format!("{}ms, # regions: {}, sb @ {:?}, \
                          e = erase all, b = brush ({:?}), hue(i,o,p) => ({:x},{:x},{:x})",
                          time_ms,
                          num_regions,
                          self.scanbox,
                          self.brush,
                          hue_r, hue_g, hue_b);
        self.display.blit_text(&buf[..], COLOR_FPS);
    }

    fn draw_regions(&mut self, regions: &mut Vec<Option<Texture>>) {
        let V2(ofs_x, ofs_y) = self.scanbox;

        for row in 0..3 {
            for col in 0..3 {
                // (0,0), (0, 720)
                let x = (col * 1280) as i32;
                let y = (row *  720) as i32;
                let ridx = col + (row * 3);

                self.display.copy_t(regions[ridx].as_ref().unwrap(),
                    Rect::new(0, 0, 1280, 720),
                    Rect::new(x - ofs_x as i32, y - ofs_y as i32, 1280, 720));
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::error::Error as StdError;
use std::fmt;
use std::result;

/// A crate private constructor for `Error`.
pub(crate) fn new_error(kind: ErrorKind) -> Error {
    Error(Box::new(kind))
}

/// A type alias for `Result<T, jsonwebtoken::Error>`.
pub type Result<T> = result::Result<T, Error>;

/// An error that can occur when encoding/decoding JWTs
#[derive(Debug)]
pub struct Error(Box<ErrorKind>);

impl Error {
    /// Return the specific type of this error.
    pub fn kind(&self) -> &ErrorKind {
        &self.0
    }

    /// Unwrap this error into its underlying type.
    pub fn into_kind(self) -> ErrorKind {
        *self.0
    }
}

/// The specific type of an error.
///
/// This enum may grow additional variants, the `#[non_exhaustive]`
/// attribute makes sure clients don't count on exhaustive matching.
/// (Otherwise, adding a new variant could break existing code.)
#[non_exhaustive]
#[derive(Debug)]
pub enum ErrorKind {
    /// When a token doesn't have a valid JWT shape
    InvalidToken,
    /// When the signature doesn't match
    InvalidSignature,
    /// When the secret given is not a valid ECDSA key
    InvalidEcdsaKey,
    /// When the secret given is not a valid RSA key
    InvalidRsaKey(&'static str),
    /// We could not sign with the given key
    RsaFailedSigning,
    /// When the algorithm from string doesn't match the one passed to `from_str`
    InvalidAlgorithmName,
    /// When a key is provided with an invalid format
    InvalidKeyFormat,

    // Validation errors
    /// When a token’s `exp` claim indicates that it has expired
    ExpiredSignature,
    /// When a token’s `iss` claim does not match the expected issuer
    InvalidIssuer,
    /// When a token’s `aud` claim does not match one of the expected audience values
    InvalidAudience,
    /// When a token’s `sub` claim does not match one of the expected audience values
    InvalidSubject,
    /// When a token’s nbf claim represents a time in the future
    ImmatureSignature,
    /// When the algorithm in the header doesn't match the one passed to `decode` or the encoding/decoding key
    /// used doesn't match the alg requested
    InvalidAlgorithm,
    /// When the Validation struct does not contain at least 1 algorithm
    MissingAlgorithm,

    // 3rd party errors
    /// An error happened when decoding some base64 text
    Base64(base64::DecodeError),
    /// An error happened while serializing/deserializing JSON
    Json(serde_json::Error),
    /// Some of the text was invalid UTF-8
    Utf8(::std::string::FromUtf8Error),
    /// Something unspecified went wrong with crypto
    Crypto(::ring::error::Unspecified),
}

impl StdError for Error {
    fn cause(&self) -> Option<&dyn StdError> {
        match *self.0 {
            ErrorKind::InvalidToken => None,
            ErrorKind::InvalidSignature => None,
            ErrorKind::InvalidEcdsaKey => None,
            ErrorKind::RsaFailedSigning => None,
            ErrorKind::InvalidRsaKey(_) => None,
            ErrorKind::ExpiredSignature => None,
            ErrorKind::MissingAlgorithm => None,
            ErrorKind::InvalidIssuer => None,
            ErrorKind::InvalidAudience => None,
            ErrorKind::InvalidSubject => None,
            ErrorKind::ImmatureSignature => None,
            ErrorKind::InvalidAlgorithm => None,
            ErrorKind::InvalidAlgorithmName => None,
            ErrorKind::InvalidKeyFormat => None,
            ErrorKind::Base64(ref err) => Some(err),
            ErrorKind::Json(ref err) => Some(err),
            ErrorKind::Utf8(ref err) => Some(err),
            ErrorKind::Crypto(ref err) => Some(err),
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self.0 {
            ErrorKind::InvalidToken
            | ErrorKind::InvalidSignature
            | ErrorKind::InvalidEcdsaKey
            | ErrorKind::ExpiredSignature
            | ErrorKind::RsaFailedSigning
            | ErrorKind::MissingAlgorithm
            | ErrorKind::InvalidIssuer
            | ErrorKind::InvalidAudience
            | ErrorKind::InvalidSubject
            | ErrorKind::ImmatureSignature
            | ErrorKind::InvalidAlgorithm
            | ErrorKind::InvalidKeyFormat
            | ErrorKind::InvalidAlgorithmName => write!(f, "{:?}", self.0),
            ErrorKind::InvalidRsaKey(ref msg) => write!(f, "RSA key invalid: {}", msg),
            ErrorKind::Json(ref err) => write!(f, "JSON error: {}", err),
            ErrorKind::Utf8(ref err) => write!(f, "UTF-8 error: {}", err),
            ErrorKind::Crypto(ref err) => write!(f, "Crypto error: {}", err),
            ErrorKind::Base64(ref err) => write!(f, "Base64 error: {}", err),
        }
    }
}

impl PartialEq for ErrorKind {
    fn eq(&self, other: &Self) -> bool {
        format!("{:?}", self) == format!("{:?}", other)
    }
}

impl From<base64::DecodeError> for Error {
    fn from(err: base64::DecodeError) -> Error {
        new_error(ErrorKind::Base64(err))
    }
}

impl From<serde_json::Error> for Error {
    fn from(err: serde_json::Error) -> Error {
        new_error(ErrorKind::Json(err))
    }
}

impl From<::std::string::FromUtf8Error> for Error {
    fn from(err: ::std::string::FromUtf8Error) -> Error {
        new_error(ErrorKind::Utf8(err))
    }
}

impl From<::ring::error::Unspecified> for Error {
    fn from(err: ::ring::error::Unspecified) -> Error {
        new_error(ErrorKind::Crypto(err))
    }
}

impl From<::ring::error::KeyRejected> for Error {
    fn from(_err: ::ring::error::KeyRejected) -> Error {
        new_error(ErrorKind::InvalidEcdsaKey)
    }
}

impl From<ErrorKind> for Error {
    fn from(kind: ErrorKind) -> Error {
        new_error(kind)
    }
}

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

    #[test]
    fn test_error_rendering() {
        assert_eq!(
            "InvalidAlgorithmName",
            Error::from(ErrorKind::InvalidAlgorithmName).to_string()
        );
    }
}
<commit_msg>Implement Clone, Eq and PartialEq for Error. (#218)<commit_after>use std::error::Error as StdError;
use std::fmt;
use std::result;
use std::sync::Arc;

/// A crate private constructor for `Error`.
pub(crate) fn new_error(kind: ErrorKind) -> Error {
    Error(Box::new(kind))
}

/// A type alias for `Result<T, jsonwebtoken::Error>`.
pub type Result<T> = result::Result<T, Error>;

/// An error that can occur when encoding/decoding JWTs
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Error(Box<ErrorKind>);

impl Error {
    /// Return the specific type of this error.
    pub fn kind(&self) -> &ErrorKind {
        &self.0
    }

    /// Unwrap this error into its underlying type.
    pub fn into_kind(self) -> ErrorKind {
        *self.0
    }
}

/// The specific type of an error.
///
/// This enum may grow additional variants, the `#[non_exhaustive]`
/// attribute makes sure clients don't count on exhaustive matching.
/// (Otherwise, adding a new variant could break existing code.)
#[non_exhaustive]
#[derive(Clone, Debug)]
pub enum ErrorKind {
    /// When a token doesn't have a valid JWT shape
    InvalidToken,
    /// When the signature doesn't match
    InvalidSignature,
    /// When the secret given is not a valid ECDSA key
    InvalidEcdsaKey,
    /// When the secret given is not a valid RSA key
    InvalidRsaKey(&'static str),
    /// We could not sign with the given key
    RsaFailedSigning,
    /// When the algorithm from string doesn't match the one passed to `from_str`
    InvalidAlgorithmName,
    /// When a key is provided with an invalid format
    InvalidKeyFormat,

    // Validation errors
    /// When a token’s `exp` claim indicates that it has expired
    ExpiredSignature,
    /// When a token’s `iss` claim does not match the expected issuer
    InvalidIssuer,
    /// When a token’s `aud` claim does not match one of the expected audience values
    InvalidAudience,
    /// When a token’s `sub` claim does not match one of the expected audience values
    InvalidSubject,
    /// When a token’s nbf claim represents a time in the future
    ImmatureSignature,
    /// When the algorithm in the header doesn't match the one passed to `decode` or the encoding/decoding key
    /// used doesn't match the alg requested
    InvalidAlgorithm,
    /// When the Validation struct does not contain at least 1 algorithm
    MissingAlgorithm,

    // 3rd party errors
    /// An error happened when decoding some base64 text
    Base64(base64::DecodeError),
    /// An error happened while serializing/deserializing JSON
    Json(Arc<serde_json::Error>),
    /// Some of the text was invalid UTF-8
    Utf8(::std::string::FromUtf8Error),
    /// Something unspecified went wrong with crypto
    Crypto(::ring::error::Unspecified),
}

impl StdError for Error {
    fn cause(&self) -> Option<&dyn StdError> {
        match *self.0 {
            ErrorKind::InvalidToken => None,
            ErrorKind::InvalidSignature => None,
            ErrorKind::InvalidEcdsaKey => None,
            ErrorKind::RsaFailedSigning => None,
            ErrorKind::InvalidRsaKey(_) => None,
            ErrorKind::ExpiredSignature => None,
            ErrorKind::MissingAlgorithm => None,
            ErrorKind::InvalidIssuer => None,
            ErrorKind::InvalidAudience => None,
            ErrorKind::InvalidSubject => None,
            ErrorKind::ImmatureSignature => None,
            ErrorKind::InvalidAlgorithm => None,
            ErrorKind::InvalidAlgorithmName => None,
            ErrorKind::InvalidKeyFormat => None,
            ErrorKind::Base64(ref err) => Some(err),
            ErrorKind::Json(ref err) => Some(err.as_ref()),
            ErrorKind::Utf8(ref err) => Some(err),
            ErrorKind::Crypto(ref err) => Some(err),
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self.0 {
            ErrorKind::InvalidToken
            | ErrorKind::InvalidSignature
            | ErrorKind::InvalidEcdsaKey
            | ErrorKind::ExpiredSignature
            | ErrorKind::RsaFailedSigning
            | ErrorKind::MissingAlgorithm
            | ErrorKind::InvalidIssuer
            | ErrorKind::InvalidAudience
            | ErrorKind::InvalidSubject
            | ErrorKind::ImmatureSignature
            | ErrorKind::InvalidAlgorithm
            | ErrorKind::InvalidKeyFormat
            | ErrorKind::InvalidAlgorithmName => write!(f, "{:?}", self.0),
            ErrorKind::InvalidRsaKey(ref msg) => write!(f, "RSA key invalid: {}", msg),
            ErrorKind::Json(ref err) => write!(f, "JSON error: {}", err),
            ErrorKind::Utf8(ref err) => write!(f, "UTF-8 error: {}", err),
            ErrorKind::Crypto(ref err) => write!(f, "Crypto error: {}", err),
            ErrorKind::Base64(ref err) => write!(f, "Base64 error: {}", err),
        }
    }
}

impl PartialEq for ErrorKind {
    fn eq(&self, other: &Self) -> bool {
        format!("{:?}", self) == format!("{:?}", other)
    }
}

// Equality of ErrorKind is an equivalence relation: it is reflexive, symmetric and transitive.
impl Eq for ErrorKind {}

impl From<base64::DecodeError> for Error {
    fn from(err: base64::DecodeError) -> Error {
        new_error(ErrorKind::Base64(err))
    }
}

impl From<serde_json::Error> for Error {
    fn from(err: serde_json::Error) -> Error {
        new_error(ErrorKind::Json(Arc::new(err)))
    }
}

impl From<::std::string::FromUtf8Error> for Error {
    fn from(err: ::std::string::FromUtf8Error) -> Error {
        new_error(ErrorKind::Utf8(err))
    }
}

impl From<::ring::error::Unspecified> for Error {
    fn from(err: ::ring::error::Unspecified) -> Error {
        new_error(ErrorKind::Crypto(err))
    }
}

impl From<::ring::error::KeyRejected> for Error {
    fn from(_err: ::ring::error::KeyRejected) -> Error {
        new_error(ErrorKind::InvalidEcdsaKey)
    }
}

impl From<ErrorKind> for Error {
    fn from(kind: ErrorKind) -> Error {
        new_error(kind)
    }
}

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

    #[test]
    fn test_error_rendering() {
        assert_eq!(
            "InvalidAlgorithmName",
            Error::from(ErrorKind::InvalidAlgorithmName).to_string()
        );
    }
}
<|endoftext|>


<commit_before>use time;
use std::io::timer::sleep;
use std::time::duration::Duration;
use current::{ Modifier };
use window::{
    PollEvent,
    ShouldClose, GetShouldClose,
    Size, GetSize,
    SwapBuffers,
};

use {
    Event,
    GenericEvent,
    Input,
    Render,
    RenderArgs,
    Update,
    UpdateArgs,
};

use std::cmp;

#[deriving(Show)]
enum EventsState {
    RenderState,
    SwapBuffersState,
    UpdateLoopState,
    HandleEventsState,
    UpdateState,
}

/// The number of updates per second.
/// If the event loop lags, it will try to catch up.
pub struct Ups(pub u64);

impl<W> Modifier<Events<W>> for Ups {
    fn modify(self, events: &mut Events<W>) {
        let Ups(frames) = self;
        events.dt_update_in_ns = BILLION / frames;
    }
}

/// The maximum number of frames per second.
/// Next frame is always scheduled from the previous frame.
pub struct MaxFps(pub u64);

impl<W> Modifier<Events<W>> for MaxFps {
    fn modify(self, events: &mut Events<W>) {
        let MaxFps(frames) = self;
        events.dt_frame_in_ns = BILLION / frames;
    }
}

/// Defines generic constraints for event loop.
/// This is auto implemented by all types that satisfy the constraints.
pub trait EventWindow<I: GenericEvent>: PollEvent<I> + GetShouldClose + GetSize + SwapBuffers {}

impl<T: PollEvent<I> + GetShouldClose + GetSize + SwapBuffers, I: GenericEvent>
EventWindow<I> for T {}

/// A game loop iterator.
///
/// *Warning: Because the iterator polls events from the window back-end,
/// it must be used on the same thread as the window back-end (usually main thread),
/// unless the window back-end supports multi-thread event polling.*
///
/// Example:
///
/// ```Rust
/// let ref mut gl = Gl::new();
/// let window = RefCell::new(window);
/// for e in Events::new(&window)
///     .set(Ups(120))
///     .set(MaxFps(60)) {
///     use event::RenderEvent;
///     e.render(|args| {
///         // Set the viewport in window to render graphics.
///         gl.viewport(0, 0, args.width as i32, args.height as i32);
///         // Create graphics context with absolute coordinates.
///         let c = Context::abs(args.width as f64, args.height as f64);
///         // Do rendering here.
///     });
/// }
/// ```
pub struct Events<W> {
    /// The game window used by iterator.
    pub window: W,
    state: EventsState,
    last_update: u64,
    last_frame: u64,
    dt_update_in_ns: u64,
    dt_frame_in_ns: u64,
    dt: f64,
}

static BILLION: u64 = 1_000_000_000;

/// The default updates per second.
pub const DEFAULT_UPS: Ups = Ups(120);
/// The default maximum frames per second.
pub const DEFAULT_MAX_FPS: MaxFps = MaxFps(60);

impl<W: EventWindow<I>, I: GenericEvent> Events<W> {
    /// Creates a new event iterator with default UPS and FPS settings.
    pub fn new(window: W) -> Events<W> {
        let start = time::precise_time_ns();
        let Ups(updates_per_second) = DEFAULT_UPS;
        let MaxFps(max_frames_per_second) = DEFAULT_MAX_FPS;
        Events {
            window: window,
            state: RenderState,
            last_update: start,
            last_frame: start,
            dt_update_in_ns: BILLION / updates_per_second,
            dt_frame_in_ns: BILLION / max_frames_per_second,
            dt: 1.0 / updates_per_second as f64,
        }
    }
}

impl<W: EventWindow<I>, I: GenericEvent>
Iterator<Event<I>>
for Events<W> {
    /// Returns the next game event.
    fn next(&mut self) -> Option<Event<I>> {
        loop {
            self.state = match self.state {
                RenderState => {
                    let ShouldClose(should_close) = self.window.get_should_close();
                    if should_close { return None; }

                    let start_render = time::precise_time_ns();
                    self.last_frame = start_render;

                    let Size([w, h]) = self.window.get_size();
                    if w != 0 && h != 0 {
                        // Swap buffers next time.
                        self.state = SwapBuffersState;
                        return Some(Render(RenderArgs {
                            // Extrapolate time forward to allow smooth motion.
                            ext_dt: (start_render - self.last_update) as f64
                                    / BILLION as f64,
                            width: w,
                            height: h,
                        }));
                    }

                    UpdateLoopState
                }
                SwapBuffersState => {
                    self.window.swap_buffers();
                    UpdateLoopState
                }
                UpdateLoopState => {
                    let current_time = time::precise_time_ns();
                    let next_frame = self.last_frame + self.dt_frame_in_ns;
                    let next_update = self.last_update + self.dt_update_in_ns;
                    let next_event = cmp::min(next_frame, next_update);
                    if next_event > current_time {
                        sleep( Duration::nanoseconds((next_event - current_time) as i64) );
                        UpdateLoopState
                    } else if next_event == next_frame {
                        RenderState
                    } else {
                        HandleEventsState
                    }
                }
                HandleEventsState => {
                    // Handle all events before updating.
                    match self.window.poll_event() {
                        None => UpdateState,
                        Some(x) => { return Some(Input(x)); },
                    }
                }
                UpdateState => {
                    self.state = UpdateLoopState;
                    self.last_update += self.dt_update_in_ns;
                    return Some(Update(UpdateArgs{ dt: self.dt }));
                }
            };
        }
    }
}
<commit_msg>Fleshed out example usage comment<commit_after>use time;
use std::io::timer::sleep;
use std::time::duration::Duration;
use current::{ Modifier };
use window::{
    PollEvent,
    ShouldClose, GetShouldClose,
    Size, GetSize,
    SwapBuffers,
};

use {
    Event,
    GenericEvent,
    Input,
    Render,
    RenderArgs,
    Update,
    UpdateArgs,
};

use std::cmp;

#[deriving(Show)]
enum EventsState {
    RenderState,
    SwapBuffersState,
    UpdateLoopState,
    HandleEventsState,
    UpdateState,
}

/// The number of updates per second.
/// If the event loop lags, it will try to catch up.
pub struct Ups(pub u64);

impl<W> Modifier<Events<W>> for Ups {
    fn modify(self, events: &mut Events<W>) {
        let Ups(frames) = self;
        events.dt_update_in_ns = BILLION / frames;
    }
}

/// The maximum number of frames per second.
/// Next frame is always scheduled from the previous frame.
pub struct MaxFps(pub u64);

impl<W> Modifier<Events<W>> for MaxFps {
    fn modify(self, events: &mut Events<W>) {
        let MaxFps(frames) = self;
        events.dt_frame_in_ns = BILLION / frames;
    }
}

/// Defines generic constraints for event loop.
/// This is auto implemented by all types that satisfy the constraints.
pub trait EventWindow<I: GenericEvent>: PollEvent<I> + GetShouldClose + GetSize + SwapBuffers {}

impl<T: PollEvent<I> + GetShouldClose + GetSize + SwapBuffers, I: GenericEvent>
EventWindow<I> for T {}

/// A game loop iterator.
///
/// *Warning: Because the iterator polls events from the window back-end,
/// it must be used on the same thread as the window back-end (usually main thread),
/// unless the window back-end supports multi-thread event polling.*
///
/// Example:
///
/// ```Rust
/// fn main() {
///     let opengl = shader_version::opengl::OpenGL_3_2;
///     let window = Sdl2Window::new(
///         opengl,
///         WindowSettings {
///             title: "Example".to_string(),
///             size: [500, 500],
///             fullscreen: false,
///             exit_on_esc: true,
///             samples: 0,
///         }
///     )
///     let ref mut gl = Gl::new();
///     let window = RefCell::new(window);
///     for e in Events::new(&window)
///         .set(Ups(120))
///         .set(MaxFps(60)) {
///         use event::RenderEvent;
///         e.render(|args| {
///             // Set the viewport in window to render graphics.
///             gl.viewport(0, 0, args.width as i32, args.height as i32);
///             // Create graphics context with absolute coordinates.
///             let c = Context::abs(args.width as f64, args.height as f64);
///             // Do rendering here.
///         });
///     }
/// }
/// ```
pub struct Events<W> {
    /// The game window used by iterator.
    pub window: W,
    state: EventsState,
    last_update: u64,
    last_frame: u64,
    dt_update_in_ns: u64,
    dt_frame_in_ns: u64,
    dt: f64,
}

static BILLION: u64 = 1_000_000_000;

/// The default updates per second.
pub const DEFAULT_UPS: Ups = Ups(120);
/// The default maximum frames per second.
pub const DEFAULT_MAX_FPS: MaxFps = MaxFps(60);

impl<W: EventWindow<I>, I: GenericEvent> Events<W> {
    /// Creates a new event iterator with default UPS and FPS settings.
    pub fn new(window: W) -> Events<W> {
        let start = time::precise_time_ns();
        let Ups(updates_per_second) = DEFAULT_UPS;
        let MaxFps(max_frames_per_second) = DEFAULT_MAX_FPS;
        Events {
            window: window,
            state: RenderState,
            last_update: start,
            last_frame: start,
            dt_update_in_ns: BILLION / updates_per_second,
            dt_frame_in_ns: BILLION / max_frames_per_second,
            dt: 1.0 / updates_per_second as f64,
        }
    }
}

impl<W: EventWindow<I>, I: GenericEvent>
Iterator<Event<I>>
for Events<W> {
    /// Returns the next game event.
    fn next(&mut self) -> Option<Event<I>> {
        loop {
            self.state = match self.state {
                RenderState => {
                    let ShouldClose(should_close) = self.window.get_should_close();
                    if should_close { return None; }

                    let start_render = time::precise_time_ns();
                    self.last_frame = start_render;

                    let Size([w, h]) = self.window.get_size();
                    if w != 0 && h != 0 {
                        // Swap buffers next time.
                        self.state = SwapBuffersState;
                        return Some(Render(RenderArgs {
                            // Extrapolate time forward to allow smooth motion.
                            ext_dt: (start_render - self.last_update) as f64
                                    / BILLION as f64,
                            width: w,
                            height: h,
                        }));
                    }

                    UpdateLoopState
                }
                SwapBuffersState => {
                    self.window.swap_buffers();
                    UpdateLoopState
                }
                UpdateLoopState => {
                    let current_time = time::precise_time_ns();
                    let next_frame = self.last_frame + self.dt_frame_in_ns;
                    let next_update = self.last_update + self.dt_update_in_ns;
                    let next_event = cmp::min(next_frame, next_update);
                    if next_event > current_time {
                        sleep( Duration::nanoseconds((next_event - current_time) as i64) );
                        UpdateLoopState
                    } else if next_event == next_frame {
                        RenderState
                    } else {
                        HandleEventsState
                    }
                }
                HandleEventsState => {
                    // Handle all events before updating.
                    match self.window.poll_event() {
                        None => UpdateState,
                        Some(x) => { return Some(Input(x)); },
                    }
                }
                UpdateState => {
                    self.state = UpdateLoopState;
                    self.last_update += self.dt_update_in_ns;
                    return Some(Update(UpdateArgs{ dt: self.dt }));
                }
            };
        }
    }
}
<|endoftext|>


<commit_before>extern crate num_cpus;

use std;
use std::thread;
use std::sync::mpsc;

pub fn prime_filter(iter_size: usize) -> Vec<bool>{
    if iter_size<100{
        slow_prime_filter(iter_size)
    }else{
        prime_filter_section(0, iter_size)
    }
}

fn case_1(y_sq: usize, iter_size: usize)
    -> Vec<usize> {
    //n_1 = 4x^2 + y^2 === 1 (mod 4)
    let (mut n_1, mut to_next_n_1) = (y_sq, 4);    let mut ret_stack: Vec<usize> = Vec::new();
    loop{
        n_1 += to_next_n_1;
        to_next_n_1 += 8;
        match n_1%60{
            _ if n_1 >= iter_size => break,
            1 | 13 | 17 | 29 | 37 | 41 | 49 | 53 => (),
            _ => continue,
        };

        // println!("1: {}", n_1);
        ret_stack.push(n_1);
    };
    ret_stack
}
fn case_2(y_sq: usize, iter_size: usize)
    -> Vec<usize> {
    //n_2 = 3x^2 + y^2 === 1 (mod 6)
    let (mut n_2, mut to_next_n_2) = (y_sq, 3);
    let mut ret_stack: Vec<usize> = Vec::new();
    loop {
        n_2 += to_next_n_2;
        to_next_n_2 += 6;
        match n_2%60{
            _ if n_2 >= iter_size => break,
            7 | 19 | 31 | 43 => (),
            _ => continue,
        };
        // println!("2: {}", n_2);
        ret_stack.push(n_2);
    };
    ret_stack
}
fn case_3(y_sq: usize, to_next_y_sq: usize, iter_size: usize)
    -> Vec<usize> {
    //n_3 = 3x^2 - y^2 === 11 (mod 12)
    let (mut n_3, mut to_next_n_3) = (2*y_sq, 3*to_next_y_sq);
    let mut ret_stack: Vec<usize> = Vec::new();
    loop {
        n_3 += to_next_n_3;
        to_next_n_3 += 6;
        match n_3%60{
            _ if n_3 >= iter_size => break,
            11 | 23 | 47 | 59 => (),
            _ => continue,
        };
        // println!("3: {}", n_3);
        ret_stack.push(n_3);
    };
    ret_stack
}

fn prime_filter_section(min:usize, max: usize) -> Vec<bool>{
    //Sieve of Atkin
    let num_cpus = num_cpus::get();
    assert!(min<max);
    let mut prime_filter = vec![false; max-min];
    if (min <= 2) & (max > 2) {prime_filter[2-min] = true;}
    if (min <= 3) & (max > 3) {prime_filter[3-min] = true;}
    if (min <= 5) & (max > 5) {prime_filter[5-min] = true;}

    let (mut y_sq, mut to_next_y_sq) = match min {
        0|1 => (1, 3),
        _ => (min*min, 2*min + 1),
    };
    let mut spawned_threads = 0;
    let (tx, rx) = mpsc::channel();
    while y_sq<max {
        if y_sq%2 == 1 {
            spawned_threads += 1;
            let (y_sq, tx) = (y_sq, tx.clone());
            thread::spawn(move || {
                tx.send(case_1(y_sq, max)).unwrap();
            });
        };
        if y_sq%3 == 1 {

            spawned_threads += 1;
            let (y_sq, to_next_y_sq, tx1) = (y_sq, to_next_y_sq, tx.clone());
            thread::spawn(move || {
                tx1.send(case_2(y_sq, max)).unwrap();
            });
            if y_sq*2<max{
                spawned_threads += 1;
                let tx2 = tx.clone();
                thread::spawn(move || {
                    tx2.send(case_3(y_sq, to_next_y_sq, max)).unwrap();
                });
            }
        };
        while{ //Do-while
            y_sq += to_next_y_sq;
            to_next_y_sq += 2;
            y_sq%6 == 0
        } {};
        if spawned_threads>=num_cpus{
            for mes in rx.try_iter(){
                spawned_threads -= 1;
                for flip_i in mes{
                    prime_filter[flip_i - min] ^= true;
                }
            }
        };
    };

    while spawned_threads!=0{
        for mes in rx.try_iter(){
            spawned_threads -= 1;
            for flip_i in mes{
                prime_filter[flip_i - min] ^= true;
            }
        }
    };
    //Eliminate non-squarefree numbers
    let mut n_sq = 49; // 7^2
    let mut next_n_sq = 32; //9^2 - 7^2, skip even numbers.
    while n_sq < max {
        let mut non_sq_free = n_sq;
        while non_sq_free < max {
            if non_sq_free >= min {
                prime_filter[non_sq_free - min] = false;
            }
            while{ //Do-while
                non_sq_free += n_sq + n_sq;
                (non_sq_free%3==0) | (non_sq_free%5==0)
            } {};
        };
        while{ //Do-while
            n_sq += next_n_sq;
            next_n_sq += 8;
            (n_sq%3==0) | (n_sq%5 == 0)
        } {};
    }
    prime_filter
}
#[cfg(test)]
pub fn old_prime_filter(iter_size: usize) -> std::vec::Vec<bool>{
    slow_prime_filter(iter_size)
}

fn slow_prime_filter(iter_size: usize) -> std::vec::Vec<bool>{
    if iter_size < 5 {
         let mut ret = vec![false, false, true, true];
         ret.truncate(iter_size);
         return ret
     }
    let mut prime_filter = vec![true; iter_size];
    prime_filter[0] = false;
    prime_filter[1] = false;
    let mut cur_num = 2;
    'outer: loop{
        for i in (cur_num+1)..iter_size{
            if 0 == i%cur_num { prime_filter[i] = false; }
        }
        cur_num += 1;
        while !prime_filter[cur_num]{
            if cur_num*cur_num > iter_size {
                break 'outer
            }
            cur_num += 1;
        }
    };
    prime_filter
}
<commit_msg>Arbitrary cap on thread number...<commit_after>extern crate num_cpus;

use std;
use std::thread;
use std::sync::mpsc;

static THREAD_THRESHOLD: usize = 255;

pub fn prime_filter(iter_size: usize) -> Vec<bool>{
    if iter_size<100{
        slow_prime_filter(iter_size)
    }else{
        prime_filter_section(0, iter_size)
    }
}

fn case_1(y_sq: usize, iter_size: usize)
    -> Vec<usize> {
    //n_1 = 4x^2 + y^2 === 1 (mod 4)
    let (mut n_1, mut to_next_n_1) = (y_sq, 4);    let mut ret_stack: Vec<usize> = Vec::new();
    loop{
        n_1 += to_next_n_1;
        to_next_n_1 += 8;
        match n_1%60{
            _ if n_1 >= iter_size => break,
            1 | 13 | 17 | 29 | 37 | 41 | 49 | 53 => (),
            _ => continue,
        };

        // println!("1: {}", n_1);
        ret_stack.push(n_1);
    };
    ret_stack
}
fn case_2(y_sq: usize, iter_size: usize)
    -> Vec<usize> {
    //n_2 = 3x^2 + y^2 === 1 (mod 6)
    let (mut n_2, mut to_next_n_2) = (y_sq, 3);
    let mut ret_stack: Vec<usize> = Vec::new();
    loop {
        n_2 += to_next_n_2;
        to_next_n_2 += 6;
        match n_2%60{
            _ if n_2 >= iter_size => break,
            7 | 19 | 31 | 43 => (),
            _ => continue,
        };
        // println!("2: {}", n_2);
        ret_stack.push(n_2);
    };
    ret_stack
}
fn case_3(y_sq: usize, to_next_y_sq: usize, iter_size: usize)
    -> Vec<usize> {
    //n_3 = 3x^2 - y^2 === 11 (mod 12)
    let (mut n_3, mut to_next_n_3) = (2*y_sq, 3*to_next_y_sq);
    let mut ret_stack: Vec<usize> = Vec::new();
    loop {
        n_3 += to_next_n_3;
        to_next_n_3 += 6;
        match n_3%60{
            _ if n_3 >= iter_size => break,
            11 | 23 | 47 | 59 => (),
            _ => continue,
        };
        // println!("3: {}", n_3);
        ret_stack.push(n_3);
    };
    ret_stack
}

fn prime_filter_section(min:usize, max: usize) -> Vec<bool>{
    //Sieve of Atkin
    let num_cpus = num_cpus::get();
    assert!(min<max);
    let mut prime_filter = vec![false; max-min];
    if (min <= 2) & (max > 2) {prime_filter[2-min] = true;}
    if (min <= 3) & (max > 3) {prime_filter[3-min] = true;}
    if (min <= 5) & (max > 5) {prime_filter[5-min] = true;}

    let (mut y_sq, mut to_next_y_sq) = match min {
        0|1 => (1, 3),
        _ => (min*min, 2*min + 1),
    };
    let mut spawned_threads = 0;
    let (tx, rx) = mpsc::channel();
    while y_sq<max {
        if y_sq%2 == 1 {
            spawned_threads += 1;
            let (y_sq, tx) = (y_sq, tx.clone());
            thread::spawn(move || {
                tx.send(case_1(y_sq, max)).unwrap();
            });
        };
        if y_sq%3 == 1 {

            spawned_threads += 1;
            let (y_sq, to_next_y_sq, tx1) = (y_sq, to_next_y_sq, tx.clone());
            thread::spawn(move || {
                tx1.send(case_2(y_sq, max)).unwrap();
            });
            if y_sq*2<max{
                spawned_threads += 1;
                let tx2 = tx.clone();
                thread::spawn(move || {
                    tx2.send(case_3(y_sq, to_next_y_sq, max)).unwrap();
                });
            }
        };
        while{ //Do-while
            y_sq += to_next_y_sq;
            to_next_y_sq += 2;
            y_sq%6 == 0
        } {};
        if spawned_threads >= num_cpus{
            while spawned_threads > THREAD_THRESHOLD{
                for mes in rx.try_iter(){
                    spawned_threads -= 1;
                    for flip_i in mes{
                        prime_filter[flip_i - min] ^= true;
                    }
                }
            }
        };
    };

    while spawned_threads!=0{
        for mes in rx.try_iter(){
            spawned_threads -= 1;
            for flip_i in mes{
                prime_filter[flip_i - min] ^= true;
            }
        }
    };
    //Eliminate non-squarefree numbers
    let mut n_sq = 49; // 7^2
    let mut next_n_sq = 32; //9^2 - 7^2, skip even numbers.
    while n_sq < max {
        let mut non_sq_free = n_sq;
        while non_sq_free < max {
            if non_sq_free >= min {
                prime_filter[non_sq_free - min] = false;
            }
            while{ //Do-while
                non_sq_free += n_sq + n_sq;
                (non_sq_free%3==0) | (non_sq_free%5==0)
            } {};
        };
        while{ //Do-while
            n_sq += next_n_sq;
            next_n_sq += 8;
            (n_sq%3==0) | (n_sq%5 == 0)
        } {};
    }
    prime_filter
}
#[cfg(test)]
pub fn old_prime_filter(iter_size: usize) -> std::vec::Vec<bool>{
    slow_prime_filter(iter_size)
}

fn slow_prime_filter(iter_size: usize) -> std::vec::Vec<bool>{
    if iter_size < 5 {
         let mut ret = vec![false, false, true, true];
         ret.truncate(iter_size);
         return ret
     }
    let mut prime_filter = vec![true; iter_size];
    prime_filter[0] = false;
    prime_filter[1] = false;
    let mut cur_num = 2;
    'outer: loop{
        for i in (cur_num+1)..iter_size{
            if 0 == i%cur_num { prime_filter[i] = false; }
        }
        cur_num += 1;
        while !prime_filter[cur_num]{
            if cur_num*cur_num > iter_size {
                break 'outer
            }
            cur_num += 1;
        }
    };
    prime_filter
}
<|endoftext|>


<commit_before>use ruma_api::Outgoing;
use ruma_identifiers::UserId;

#[allow(unused)]
pub struct Thing<'t, T> {
    some: &'t str,
    t: &'t T,
}

#[derive(Debug)]
pub struct IncomingThing<T> {
    some: String,
    t: T,
}

#[derive(Outgoing)]
#[incoming_no_deserialize]
pub struct Request<'a, T> {
    pub abc: &'a str,
    pub thing: Thing<'a, T>,
    pub device_id: &'a ::ruma_identifiers::DeviceId,
    pub user_id: &'a UserId,
    pub bytes: &'a [u8],
    pub recursive: &'a [Thing<'a, T>],
    pub option: Option<&'a [u8]>,
}

#[derive(Outgoing)]
#[incoming_no_deserialize]
pub enum EnumThing<'a, T> {
    Abc(&'a str),
    Stuff(Thing<'a, T>),
    Boxy(&'a ::ruma_identifiers::DeviceId),
    Other(Option<&'a str>),
    StructVar { stuff: &'a str, more: &'a ::ruma_identifiers::ServerName },
}
<commit_msg>Add failing test to ruma-api for lifetimes in ruma_api! macro<commit_after>use ruma_api::Outgoing;
use ruma_identifiers::UserId;

#[allow(unused)]
pub struct Thing<'t, T> {
    some: &'t str,
    t: &'t T,
}

#[derive(Debug)]
pub struct IncomingThing<T> {
    some: String,
    t: T,
}

#[allow(unused)]
#[derive(Copy, Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct OtherThing<'t> {
    some: &'t str,
    t: &'t [u8],
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct IncomingOtherThing {
    some: String,
    t: Vec<u8>,
}

use ruma_api::ruma_api;

ruma_api! {
    metadata: {
        description: "Does something.",
        method: GET,
        name: "no_fields",
        path: "/_matrix/my/endpoint/:thing",
        rate_limited: false,
        requires_authentication: false,
    }

    request: {
        #[ruma_api(query)]
        pub abc: &'a str,
        #[ruma_api(path)]
        pub thing: &'a str,
        #[ruma_api(header = CONTENT_TYPE)]
        pub stuff: &'a str,
    }

    response: {
        pub body: &'a str,
        pub thing: OtherThing<'a>,
        pub stuff: &'a [u8],
    }
}

// #[derive(Outgoing)]
// #[incoming_no_deserialize]
// pub struct Request<'a, T> {
//     pub abc: &'a str,
//     pub thing: Thing<'a, T>,
//     pub device_id: &'a ::ruma_identifiers::DeviceId,
//     pub user_id: &'a UserId,
//     pub bytes: &'a [u8],
//     pub recursive: &'a [Thing<'a, T>],
//     pub option: Option<&'a [u8]>,
// }

// #[derive(Outgoing)]
// #[incoming_no_deserialize]
// pub enum EnumThing<'a, T> {
//     Abc(&'a str),
//     Stuff(Thing<'a, T>),
//     Boxy(&'a ::ruma_identifiers::DeviceId),
//     Other(Option<&'a str>),
//     StructVar { stuff: &'a str, more: &'a ::ruma_identifiers::ServerName },
// }
<|endoftext|>