<commit_before>extern mod core_foundation;
extern mod io_surface;
extern mod opengles;

use mod opengles::cgl;
use mod opengles::gl2;

use core_foundation::base::CFTypeOps;
use core::cast::transmute;
use core::ptr::{null, to_unsafe_ptr};
use geom::size::Size2D;
use io_surface::{IOSurface, kIOSurfaceBytesPerElement, kIOSurfaceBytesPerRow, kIOSurfaceHeight};
use io_surface::{kIOSurfaceIsGlobal, kIOSurfaceWidth};
use opengles::cgl::{CGLChoosePixelFormat, CGLContextObj, CGLCreateContext, CGLLockContext};
use opengles::cgl::{CGLSetCurrentContext, CGLTexImageIOSurface2D, kCGLNoError, kCGLPFACompliant};
use opengles::cgl::{kCGLPFADoubleBuffer};
use opengles::gl2::{BGRA, CLAMP_TO_EDGE, COLOR_ATTACHMENT0, FRAMEBUFFER, FRAMEBUFFER_COMPLETE};
use opengles::gl2::{GLenum, GLint, GLsizei, GLuint, LINEAR, NEAREST, RGBA, TEXTURE_MAG_FILTER};
use opengles::gl2::{TEXTURE_MIN_FILTER, TEXTURE_RECTANGLE_ARB, TEXTURE_WRAP_S, TEXTURE_WRAP_T};
use opengles::gl2::{UNSIGNED_INT_8_8_8_8_REV};

use base::ShareContext;

// FIXME: This is not good.
#[link_args="-framework IOSurface -framework CoreFoundation"]
#[nolink]
extern {}

pub type Context = MacContext;

pub struct MacContext {
    surface: IOSurface,
    framebuffer: GLuint,
    texture: GLuint

    // FIXME: Needs drop.
}

pub fn init_cgl() -> CGLContextObj {
    // FIXME: We should expose some higher-level, safe abstractions inside the CGL module.
    unsafe {
        // Choose a pixel format.
        let attributes = [ kCGLPFADoubleBuffer, kCGLPFACompliant, 0 ];
        let pixel_format = null();
        let pixel_format_count = 1;
        let gl_error = CGLChoosePixelFormat(transmute(&attributes[0]),
                                            to_unsafe_ptr(&pixel_format),
                                            to_unsafe_ptr(&pixel_format_count));
        assert gl_error == kCGLNoError;

        // Create the context.
        let cgl_context = null();
        let gl_error = CGLCreateContext(pixel_format, null(), to_unsafe_ptr(&cgl_context));
        assert gl_error == kCGLNoError;

        // Set the context.
        let gl_error = CGLSetCurrentContext(cgl_context);
        assert gl_error == kCGLNoError;

        // Lock the context.
        let gl_error = CGLLockContext(cgl_context);
        assert gl_error == kCGLNoError;

        return cgl_context;
    }
}

pub fn init_surface(+size: Size2D<int>) -> IOSurface {
    use cf = core_foundation;
    use cf::boolean::{CFBooleanRef, CFBoolean};
    use cf::number::{CFNumberRef, CFNumber};
    use number = cf::number::CFNumber::new;
    use string = cf::string::CFString::wrap_extern;
    use true_value = cf::boolean::CFBoolean::true_value;

    IOSurface::new_io_surface(&cf::dictionary::CFDictionary::new([
        (string(kIOSurfaceWidth),           cf::base::as_CFType::<CFNumberRef, CFNumber>(number(size.width as i32))),
        (string(kIOSurfaceHeight),          cf::base::as_CFType::<CFNumberRef, CFNumber>(number(size.height as i32))),
        (string(kIOSurfaceBytesPerRow),     cf::base::as_CFType::<CFNumberRef, CFNumber>(number(size.width as i32 * 4))),
        (string(kIOSurfaceBytesPerElement), cf::base::as_CFType::<CFNumberRef, CFNumber>(number(4i32))),
        (string(kIOSurfaceIsGlobal),        cf::base::as_CFType::<CFBooleanRef, CFBoolean>(true_value()))
    ]))
}

pub fn init_texture() -> GLuint {
    gl2::enable(TEXTURE_RECTANGLE_ARB);

    let texture = gl2::gen_textures(1)[0];
    gl2::bind_texture(TEXTURE_RECTANGLE_ARB, texture);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_WRAP_S, CLAMP_TO_EDGE as GLint);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_WRAP_T, CLAMP_TO_EDGE as GLint);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_MAG_FILTER, LINEAR as GLint);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_MIN_FILTER, NEAREST as GLint);
    return texture;
}

// Assumes the texture is already bound via gl2::bind_texture().
pub fn bind_surface_to_texture(context: &CGLContextObj, surface: &IOSurface, +size: Size2D<int>) {
    // FIXME: There should be safe wrappers for this.
    unsafe {
        let gl_error = CGLTexImageIOSurface2D(*context,
                                              TEXTURE_RECTANGLE_ARB,
                                              RGBA as GLenum,
                                              size.width as GLsizei,
                                              size.height as GLsizei,
                                              BGRA as GLenum,
                                              UNSIGNED_INT_8_8_8_8_REV,
                                              transmute(copy surface.obj),
                                              0);
        assert gl_error == kCGLNoError;
    }
}

pub fn bind_texture_to_framebuffer(texture: GLuint) {
    gl2::bind_texture(TEXTURE_RECTANGLE_ARB, 0);
    gl2::framebuffer_texture_2d(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_RECTANGLE_ARB, texture, 0);
    assert gl2::check_framebuffer_status(FRAMEBUFFER) == FRAMEBUFFER_COMPLETE;
}

impl MacContext : ShareContext {
    static fn new(size: Size2D<int>) -> MacContext {
        // Initialize CGL.
        let context = init_cgl();

        // Create the surface.
        let surface = init_surface(copy size);

        // Create a framebuffer.
        let framebuffer = gl2::gen_framebuffers(1)[0];
        gl2::bind_framebuffer(FRAMEBUFFER, framebuffer);

        // Create and bind to the texture.
        let texture = init_texture();
        bind_surface_to_texture(&context, &surface, size);

        // Bind the texture to the framebuffer.
        bind_texture_to_framebuffer(texture);

        MacContext {
            surface: move surface,
            framebuffer: framebuffer,
            texture: texture
        }
    }

    fn flush(&self) {
        gl2::finish();
    }

    fn id() -> int {
        self.surface.get_id() as int
    }
}

<commit_msg>Uglify use of CFDictionary::new because the lifetimes aren't set up properly.<commit_after>extern mod core_foundation;
extern mod io_surface;
extern mod opengles;

use mod opengles::cgl;
use mod opengles::gl2;

use core::cast::transmute;
use core::ptr::{null, to_unsafe_ptr};
use geom::size::Size2D;
use io_surface::{IOSurface, kIOSurfaceBytesPerElement, kIOSurfaceBytesPerRow, kIOSurfaceHeight};
use io_surface::{kIOSurfaceIsGlobal, kIOSurfaceWidth};
use opengles::cgl::{CGLChoosePixelFormat, CGLContextObj, CGLCreateContext, CGLLockContext};
use opengles::cgl::{CGLSetCurrentContext, CGLTexImageIOSurface2D, kCGLNoError, kCGLPFACompliant};
use opengles::cgl::{kCGLPFADoubleBuffer};
use opengles::gl2::{BGRA, CLAMP_TO_EDGE, COLOR_ATTACHMENT0, FRAMEBUFFER, FRAMEBUFFER_COMPLETE};
use opengles::gl2::{GLenum, GLint, GLsizei, GLuint, LINEAR, NEAREST, RGBA, TEXTURE_MAG_FILTER};
use opengles::gl2::{TEXTURE_MIN_FILTER, TEXTURE_RECTANGLE_ARB, TEXTURE_WRAP_S, TEXTURE_WRAP_T};
use opengles::gl2::{UNSIGNED_INT_8_8_8_8_REV};

use base::ShareContext;

// FIXME: This is not good.
#[link_args="-framework IOSurface -framework CoreFoundation"]
#[nolink]
extern {}

pub type Context = MacContext;

pub struct MacContext {
    surface: IOSurface,
    framebuffer: GLuint,
    texture: GLuint

    // FIXME: Needs drop.
}

pub fn init_cgl() -> CGLContextObj {
    // FIXME: We should expose some higher-level, safe abstractions inside the CGL module.
    unsafe {
        // Choose a pixel format.
        let attributes = [ kCGLPFADoubleBuffer, kCGLPFACompliant, 0 ];
        let pixel_format = null();
        let pixel_format_count = 1;
        let gl_error = CGLChoosePixelFormat(transmute(&attributes[0]),
                                            to_unsafe_ptr(&pixel_format),
                                            to_unsafe_ptr(&pixel_format_count));
        assert gl_error == kCGLNoError;

        // Create the context.
        let cgl_context = null();
        let gl_error = CGLCreateContext(pixel_format, null(), to_unsafe_ptr(&cgl_context));
        assert gl_error == kCGLNoError;

        // Set the context.
        let gl_error = CGLSetCurrentContext(cgl_context);
        assert gl_error == kCGLNoError;

        // Lock the context.
        let gl_error = CGLLockContext(cgl_context);
        assert gl_error == kCGLNoError;

        return cgl_context;
    }
}

pub fn init_surface(+size: Size2D<int>) -> IOSurface {
    use cf = core_foundation;
    use cf::boolean::{CFBooleanRef, CFBoolean};
    use cf::number::{CFNumberRef, CFNumber};
    use number = cf::number::CFNumber::new;
    use string = cf::string::CFString::wrap_extern;

    // TODO: dictionary constructor should be less ridiculous.
    // Or, we could add bindings for mutable dictionaries.
    let k_width = string(kIOSurfaceWidth);
    let v_width = number(size.width as i32);

    let k_height = string(kIOSurfaceHeight);
    let v_height = number(size.height as i32);

    let k_bytes_per_row = string(kIOSurfaceBytesPerRow);
    let v_bytes_per_row = number(size.width as i32 * 4);

    let k_bytes_per_elem = string(kIOSurfaceBytesPerElement);
    let v_bytes_per_elem = number(4i32);

    let k_is_global = string(kIOSurfaceIsGlobal);
    let v_is_global = CFBoolean::true_value();

    io_surface::new(&cf::dictionary::CFDictionary::new([
        (*k_width.borrow_ref(),          *v_width.borrow_type_ref()),
        (*k_height.borrow_ref(),         *v_height.borrow_type_ref()),
        (*k_bytes_per_row.borrow_ref(),  *v_bytes_per_row.borrow_type_ref()),
        (*k_bytes_per_elem.borrow_ref(), *v_bytes_per_elem.borrow_type_ref()),
        (*k_is_global.borrow_ref(),      *v_is_global.borrow_type_ref()),
    ]))
}

pub fn init_texture() -> GLuint {
    gl2::enable(TEXTURE_RECTANGLE_ARB);

    let texture = gl2::gen_textures(1)[0];
    gl2::bind_texture(TEXTURE_RECTANGLE_ARB, texture);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_WRAP_S, CLAMP_TO_EDGE as GLint);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_WRAP_T, CLAMP_TO_EDGE as GLint);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_MAG_FILTER, LINEAR as GLint);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_MIN_FILTER, NEAREST as GLint);
    return texture;
}

// Assumes the texture is already bound via gl2::bind_texture().
pub fn bind_surface_to_texture(context: &CGLContextObj, surface: &IOSurface, +size: Size2D<int>) {
    // FIXME: There should be safe wrappers for this.
    unsafe {
        let gl_error = CGLTexImageIOSurface2D(*context,
                                              TEXTURE_RECTANGLE_ARB,
                                              RGBA as GLenum,
                                              size.width as GLsizei,
                                              size.height as GLsizei,
                                              BGRA as GLenum,
                                              UNSIGNED_INT_8_8_8_8_REV,
                                              transmute(copy surface.obj),
                                              0);
        assert gl_error == kCGLNoError;
    }
}

pub fn bind_texture_to_framebuffer(texture: GLuint) {
    gl2::bind_texture(TEXTURE_RECTANGLE_ARB, 0);
    gl2::framebuffer_texture_2d(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_RECTANGLE_ARB, texture, 0);
    assert gl2::check_framebuffer_status(FRAMEBUFFER) == FRAMEBUFFER_COMPLETE;
}

impl MacContext : ShareContext {
    static fn new(size: Size2D<int>) -> MacContext {
        // Initialize CGL.
        let context = init_cgl();

        // Create the surface.
        let surface = init_surface(copy size);

        // Create a framebuffer.
        let framebuffer = gl2::gen_framebuffers(1)[0];
        gl2::bind_framebuffer(FRAMEBUFFER, framebuffer);

        // Create and bind to the texture.
        let texture = init_texture();
        bind_surface_to_texture(&context, &surface, size);

        // Bind the texture to the framebuffer.
        bind_texture_to_framebuffer(texture);

        MacContext {
            surface: move surface,
            framebuffer: framebuffer,
            texture: texture
        }
    }

    fn flush(&self) {
        gl2::finish();
    }

    fn id() -> int {
        self.surface.get_id() as int
    }
}

<|endoftext|>


<commit_before>use anyhow::{Context, Error};
use js_sys::JsString;
use next_swc::{custom_before_pass, TransformOptions};
use once_cell::sync::Lazy;
use std::sync::Arc;
use wasm_bindgen::{prelude::*, JsCast};
use wasm_bindgen_futures::future_to_promise;

use swc_core::{
    base::{config::JsMinifyOptions, config::ParseOptions, try_with_handler, Compiler},
    common::{comments::Comments, errors::ColorConfig, FileName, FilePathMapping, SourceMap},
    ecma::transforms::base::pass::noop,
};

fn convert_err(err: Error) -> JsValue {
    format!("{:?}", err).into()
}

#[wasm_bindgen(js_name = "minifySync")]
pub fn minify_sync(s: JsString, opts: JsValue) -> Result<JsValue, JsValue> {
    console_error_panic_hook::set_once();

    let c = compiler();

    try_with_handler(
        c.cm.clone(),
        swc_core::base::HandlerOpts {
            color: ColorConfig::Never,
            skip_filename: false,
        },
        |handler| {
            let opts: JsMinifyOptions = opts.into_serde().context("failed to parse options")?;

            let fm = c.cm.new_source_file(FileName::Anon, s.into());
            let program = c
                .minify(fm, handler, &opts)
                .context("failed to minify file")?;

            JsValue::from_serde(&program).context("failed to serialize json")
        },
    )
    .map_err(convert_err)
}

#[wasm_bindgen(js_name = "minify")]
pub fn minify(s: JsString, opts: JsValue) -> js_sys::Promise {
    // TODO: This'll be properly scheduled once wasm have standard backed thread
    // support.
    future_to_promise(async { minify_sync(s, opts) })
}

#[wasm_bindgen(js_name = "transformSync")]
pub fn transform_sync(s: JsValue, opts: JsValue) -> Result<JsValue, JsValue> {
    console_error_panic_hook::set_once();

    let c = compiler();

    try_with_handler(
        c.cm.clone(),
        swc_core::base::HandlerOpts {
            color: ColorConfig::Never,
            skip_filename: false,
        },
        |handler| {
            let opts: TransformOptions = opts.into_serde().context("failed to parse options")?;

            let s = s.dyn_into::<js_sys::JsString>();
            let out = match s {
                Ok(s) => {
                    let fm = c.cm.new_source_file(
                        if opts.swc.filename.is_empty() {
                            FileName::Anon
                        } else {
                            FileName::Real(opts.swc.filename.clone().into())
                        },
                        s.into(),
                    );
                    let cm = c.cm.clone();
                    let file = fm.clone();
                    c.process_js_with_custom_pass(
                        fm,
                        None,
                        handler,
                        &opts.swc,
                        |_, comments| {
                            custom_before_pass(
                                cm,
                                file,
                                &opts,
                                comments.clone(),
                                Default::default(),
                            )
                        },
                        |_, _| noop(),
                    )
                    .context("failed to process js file")?
                }
                Err(v) => c.process_js(handler, v.into_serde().expect(""), &opts.swc)?,
            };

            JsValue::from_serde(&out).context("failed to serialize json")
        },
    )
    .map_err(convert_err)
}

#[wasm_bindgen(js_name = "transform")]
pub fn transform(s: JsValue, opts: JsValue) -> js_sys::Promise {
    // TODO: This'll be properly scheduled once wasm have standard backed thread
    // support.
    future_to_promise(async { transform_sync(s, opts) })
}

#[wasm_bindgen(js_name = "parseSync")]
pub fn parse_sync(s: JsString, opts: JsValue) -> Result<JsValue, JsValue> {
    console_error_panic_hook::set_once();

    let c = swc_core::base::Compiler::new(Arc::new(SourceMap::new(FilePathMapping::empty())));

    try_with_handler(
        c.cm.clone(),
        swc_core::base::HandlerOpts {
            ..Default::default()
        },
        |handler| {
            c.run(|| {
                let opts: ParseOptions = opts.into_serde().context("failed to parse options")?;

                let fm = c.cm.new_source_file(FileName::Anon, s.into());

                let cmts = c.comments().clone();
                let comments = if opts.comments {
                    Some(&cmts as &dyn Comments)
                } else {
                    None
                };

                let program = c
                    .parse_js(
                        fm,
                        handler,
                        opts.target,
                        opts.syntax,
                        opts.is_module,
                        comments,
                    )
                    .context("failed to parse code")?;

                let s = serde_json::to_string(&program).unwrap();
                Ok(JsValue::from_str(&s))
            })
        },
    )
    .map_err(convert_err)
}

#[wasm_bindgen(js_name = "parse")]
pub fn parse(s: JsString, opts: JsValue) -> js_sys::Promise {
    // TODO: This'll be properly scheduled once wasm have standard backed thread
    // support.
    future_to_promise(async { parse_sync(s, opts) })
}

/// Get global sourcemap
fn compiler() -> Arc<Compiler> {
    static C: Lazy<Arc<Compiler>> = Lazy::new(|| {
        let cm = Arc::new(SourceMap::new(FilePathMapping::empty()));

        Arc::new(Compiler::new(cm))
    });

    C.clone()
}
<commit_msg>Fix wasm<commit_after>use anyhow::{Context, Error};
use js_sys::JsString;
use next_swc::{custom_before_pass, TransformOptions};
use once_cell::sync::Lazy;
use std::sync::Arc;
use wasm_bindgen::{prelude::*, JsCast};
use wasm_bindgen_futures::future_to_promise;

use swc_core::{
    base::{config::JsMinifyOptions, config::ParseOptions, try_with_handler, Compiler},
    common::{
        comments::Comments, errors::ColorConfig, FileName, FilePathMapping, SourceMap, GLOBALS,
    },
    ecma::transforms::base::pass::noop,
};

fn convert_err(err: Error) -> JsValue {
    format!("{:?}", err).into()
}

#[wasm_bindgen(js_name = "minifySync")]
pub fn minify_sync(s: JsString, opts: JsValue) -> Result<JsValue, JsValue> {
    console_error_panic_hook::set_once();

    let c = compiler();

    try_with_handler(
        c.cm.clone(),
        swc_core::base::HandlerOpts {
            color: ColorConfig::Never,
            skip_filename: false,
        },
        |handler| {
            GLOBALS.set(&Default::default(), || {
                let opts: JsMinifyOptions = opts.into_serde().context("failed to parse options")?;

                let fm = c.cm.new_source_file(FileName::Anon, s.into());
                let program = c
                    .minify(fm, handler, &opts)
                    .context("failed to minify file")?;

                JsValue::from_serde(&program).context("failed to serialize json")
            })
        },
    )
    .map_err(convert_err)
}

#[wasm_bindgen(js_name = "minify")]
pub fn minify(s: JsString, opts: JsValue) -> js_sys::Promise {
    // TODO: This'll be properly scheduled once wasm have standard backed thread
    // support.
    future_to_promise(async { minify_sync(s, opts) })
}

#[wasm_bindgen(js_name = "transformSync")]
pub fn transform_sync(s: JsValue, opts: JsValue) -> Result<JsValue, JsValue> {
    console_error_panic_hook::set_once();

    let c = compiler();

    try_with_handler(
        c.cm.clone(),
        swc_core::base::HandlerOpts {
            color: ColorConfig::Never,
            skip_filename: false,
        },
        |handler| {
            GLOBALS.set(&Default::default(), || {
                let opts: TransformOptions =
                    opts.into_serde().context("failed to parse options")?;

                let s = s.dyn_into::<js_sys::JsString>();
                let out = match s {
                    Ok(s) => {
                        let fm = c.cm.new_source_file(
                            if opts.swc.filename.is_empty() {
                                FileName::Anon
                            } else {
                                FileName::Real(opts.swc.filename.clone().into())
                            },
                            s.into(),
                        );
                        let cm = c.cm.clone();
                        let file = fm.clone();
                        c.process_js_with_custom_pass(
                            fm,
                            None,
                            handler,
                            &opts.swc,
                            |_, comments| {
                                custom_before_pass(
                                    cm,
                                    file,
                                    &opts,
                                    comments.clone(),
                                    Default::default(),
                                )
                            },
                            |_, _| noop(),
                        )
                        .context("failed to process js file")?
                    }
                    Err(v) => c.process_js(handler, v.into_serde().expect(""), &opts.swc)?,
                };

                JsValue::from_serde(&out).context("failed to serialize json")
            })
        },
    )
    .map_err(convert_err)
}

#[wasm_bindgen(js_name = "transform")]
pub fn transform(s: JsValue, opts: JsValue) -> js_sys::Promise {
    // TODO: This'll be properly scheduled once wasm have standard backed thread
    // support.
    future_to_promise(async { transform_sync(s, opts) })
}

#[wasm_bindgen(js_name = "parseSync")]
pub fn parse_sync(s: JsString, opts: JsValue) -> Result<JsValue, JsValue> {
    console_error_panic_hook::set_once();

    let c = swc_core::base::Compiler::new(Arc::new(SourceMap::new(FilePathMapping::empty())));

    try_with_handler(
        c.cm.clone(),
        swc_core::base::HandlerOpts {
            ..Default::default()
        },
        |handler| {
            c.run(|| {
                GLOBALS.set(&Default::default(), || {
                    let opts: ParseOptions =
                        opts.into_serde().context("failed to parse options")?;

                    let fm = c.cm.new_source_file(FileName::Anon, s.into());

                    let cmts = c.comments().clone();
                    let comments = if opts.comments {
                        Some(&cmts as &dyn Comments)
                    } else {
                        None
                    };

                    let program = c
                        .parse_js(
                            fm,
                            handler,
                            opts.target,
                            opts.syntax,
                            opts.is_module,
                            comments,
                        )
                        .context("failed to parse code")?;

                    let s = serde_json::to_string(&program).unwrap();
                    Ok(JsValue::from_str(&s))
                })
            })
        },
    )
    .map_err(convert_err)
}

#[wasm_bindgen(js_name = "parse")]
pub fn parse(s: JsString, opts: JsValue) -> js_sys::Promise {
    // TODO: This'll be properly scheduled once wasm have standard backed thread
    // support.
    future_to_promise(async { parse_sync(s, opts) })
}

/// Get global sourcemap
fn compiler() -> Arc<Compiler> {
    static C: Lazy<Arc<Compiler>> = Lazy::new(|| {
        let cm = Arc::new(SourceMap::new(FilePathMapping::empty()));

        Arc::new(Compiler::new(cm))
    });

    C.clone()
}
<|endoftext|>


<commit_before>use std::sync::{Arc, Mutex};

use std::sync::atomic::{AtomicUsize, Ordering};

use {Cursive, Printer};
use event::*;
use theme::ColorStyle;
use view::View;

/// Display progress.
pub struct ProgressBar {
    min: usize,
    max: usize,
    value: Arc<AtomicUsize>,
    // TODO: use a Promise instead?
    callback: Option<Arc<Mutex<Option<Box<Fn(&mut Cursive) + Send>>>>>,
}

impl ProgressBar {
    /// Creates a new progress bar.
    ///
    /// Default values:
    ///
    /// * `min`: 0
    /// * `max`: 100
    /// * `value`: 0
    pub fn new() -> Self {
        ProgressBar {
            min: 0,
            max: 100,
            value: Arc::new(AtomicUsize::new(0)),
            callback: None,
        }
    }

    /// Sets the value to follow.
    pub fn with_value(mut self, value: Arc<AtomicUsize>) -> Self {
        self.value = value;
        self
    }

    /// Sets the callback to follow.
    ///
    /// Whenever `callback` is set, it will be called on the next event loop.
    pub fn with_callback(mut self,
                         callback: Arc<Mutex<Option<Box<Fn(&mut Cursive) + Send>>>>)
                         -> Self {
        self.callback = Some(callback);
        self
    }

    /// Sets the minimum value.
    ///
    /// When `value` equals `min`, the bar is at the minimum level.
    pub fn min(mut self, min: usize) -> Self {
        self.min = min;
        self
    }

    /// Sets the maximum value.
    ///
    /// When `value` equals `max`, the bar is at the maximum level.
    pub fn max(mut self, max: usize) -> Self {
        self.max = max;
        self
    }

    /// Sets the `min` and `max` range for the value.
    pub fn range(self, min: usize, max: usize) -> Self {
        self.min(min).max(max)
    }

    /// Sets the current value.
    ///
    /// Value is clamped between `min` and `max`.
    pub fn set_value(&mut self, value: usize) {
        self.value.store(value, Ordering::Relaxed);
    }
}

impl View for ProgressBar {
    fn draw(&self, printer: &Printer) {
        // Now, the bar itself...
        let available = printer.size.x;

        let value = self.value.load(Ordering::Relaxed);
        let length = ((1 + available) * (value - self.min)) / (1 + self.max - self.min);
        printer.with_color(ColorStyle::Highlight, |printer| {
            printer.print_hline((0, 0), length, " ");
        });
    }

    fn on_event(&mut self, _: Event) -> EventResult {
        if let Some(ref cb) = self.callback {
            if let Some(cb) = cb.lock().unwrap().take() {
                return EventResult::Consumed(Some(cb.into()));
            }
        }

        EventResult::Ignored
    }
}
<commit_msg>Use intermediate type for the callback promise<commit_after>use std::sync::{Arc, Mutex};

use std::sync::atomic::{AtomicUsize, Ordering};

use {Cursive, Printer};
use event::*;
use theme::ColorStyle;
use view::View;

pub type CbPromise = Option<Box<Fn(&mut Cursive) + Send>>;

/// Display progress.
pub struct ProgressBar {
    min: usize,
    max: usize,
    value: Arc<AtomicUsize>,
    // TODO: use a Promise instead?
    callback: Option<Arc<Mutex<CbPromise>>>,
}

new_default!(ProgressBar);

impl ProgressBar {
    /// Creates a new progress bar.
    ///
    /// Default values:
    ///
    /// * `min`: 0
    /// * `max`: 100
    /// * `value`: 0
    pub fn new() -> Self {
        ProgressBar {
            min: 0,
            max: 100,
            value: Arc::new(AtomicUsize::new(0)),
            callback: None,
        }
    }

    /// Sets the value to follow.
    pub fn with_value(mut self, value: Arc<AtomicUsize>) -> Self {
        self.value = value;
        self
    }

    /// Sets the callback to follow.
    ///
    /// Whenever `callback` is set, it will be called on the next event loop.
    pub fn with_callback(mut self,
                         callback: Arc<Mutex<CbPromise>>)
                         -> Self {
        self.callback = Some(callback);
        self
    }

    /// Sets the minimum value.
    ///
    /// When `value` equals `min`, the bar is at the minimum level.
    pub fn min(mut self, min: usize) -> Self {
        self.min = min;
        self
    }

    /// Sets the maximum value.
    ///
    /// When `value` equals `max`, the bar is at the maximum level.
    pub fn max(mut self, max: usize) -> Self {
        self.max = max;
        self
    }

    /// Sets the `min` and `max` range for the value.
    pub fn range(self, min: usize, max: usize) -> Self {
        self.min(min).max(max)
    }

    /// Sets the current value.
    ///
    /// Value is clamped between `min` and `max`.
    pub fn set_value(&mut self, value: usize) {
        self.value.store(value, Ordering::Relaxed);
    }
}

impl View for ProgressBar {
    fn draw(&self, printer: &Printer) {
        // Now, the bar itself...
        let available = printer.size.x;

        let value = self.value.load(Ordering::Relaxed);
        let length = ((1 + available) * (value - self.min)) / (1 + self.max - self.min);
        printer.with_color(ColorStyle::Highlight, |printer| {
            printer.print_hline((0, 0), length, " ");
        });
    }

    fn on_event(&mut self, _: Event) -> EventResult {
        if let Some(ref cb) = self.callback {
            if let Some(cb) = cb.lock().unwrap().take() {
                return EventResult::Consumed(Some(cb.into()));
            }
        }

        EventResult::Ignored
    }
}
<|endoftext|>


<commit_before>extern crate json_typegen_shared;
extern crate clap;

use json_typegen_shared::{codegen, codegen_from_macro, Options, infer_source_type};
use clap::{Arg, App};
use std::io::{self, Read, Write};
use std::fs::OpenOptions;

fn main() {
    let matches = App::new("JSON code generation CLI")
        .version("0.1.0")
        .about("Generate Rust types from JSON samples")
        .arg(
            Arg::with_name("input")
                .help("The input to generate types from. A sample, file, URL, or macro.")
                .takes_value(true)
                .required(true),
        )
        .arg(
            Arg::with_name("name")
                .short("n")
                .long("name")
                .help("Name for the root generated type. Default: Root.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("output")
                .short("o")
                .long("output")
                .help("What file to write the output to. Default: standard output.")
                .takes_value(true),
        )
        .get_matches();

    let source = matches.value_of("input").unwrap();

    let input = if source == "-" {
        let mut buffer = String::new();
        io::stdin().read_to_string(&mut buffer).unwrap();
        buffer
    } else {
        source.to_string()
    };

    let code = if input.trim().starts_with("json_typegen") {
        codegen_from_macro(&input)
    } else {
        let name = matches.value_of("name").unwrap_or("Root");
        codegen(&name, &infer_source_type(&input), Options::default())
    };

    if let Some(filename) = matches.value_of("output") {
        let mut file = OpenOptions::new()
            .read(true)
            .write(true)
            .create(true)
            .truncate(true)
            .open(filename)
            .unwrap();

        file.write_all(code.unwrap().as_bytes()).unwrap();
    } else {
        print!("{}", code.unwrap());
    }
}
<commit_msg>CLI: Use ? instead of unwrap<commit_after>extern crate json_typegen_shared;
extern crate clap;

use json_typegen_shared::{codegen, codegen_from_macro, Options, infer_source_type};
use clap::{Arg, App};
use std::io::{self, Read, Write};
use std::fs::OpenOptions;

fn main_with_result() -> Result<(), Box<std::error::Error>> {
    let matches = App::new("JSON code generation CLI")
        .version("0.1.0")
        .about("Generate Rust types from JSON samples")
        .arg(
            Arg::with_name("input")
                .help("The input to generate types from. A sample, file, URL, or macro.")
                .takes_value(true)
                .required(true),
        )
        .arg(
            Arg::with_name("name")
                .short("n")
                .long("name")
                .help("Name for the root generated type. Default: Root.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("output")
                .short("o")
                .long("output")
                .help("What file to write the output to. Default: standard output.")
                .takes_value(true),
        )
        .get_matches();

    let source = matches.value_of("input").expect("input argument is required");

    let input = if source == "-" {
        let mut buffer = String::new();
        io::stdin().read_to_string(&mut buffer)?;
        buffer
    } else {
        source.to_string()
    };

    let code = if input.trim().starts_with("json_typegen") {
        codegen_from_macro(&input)
    } else {
        let name = matches.value_of("name").unwrap_or("Root");
        codegen(&name, &infer_source_type(&input), Options::default())
    };

    if let Some(filename) = matches.value_of("output") {
        let mut file = OpenOptions::new()
            .read(true)
            .write(true)
            .create(true)
            .truncate(true)
            .open(filename)?;

        file.write_all(code?.as_bytes())?;
    } else {
        print!("{}", code?);
    }

    Ok(())
}

fn main() {
    let result = main_with_result();

    if let Err(e) = result {
        eprintln!("{}", e);
        std::process::exit(1);
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2015, The Rust-GNOME Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use std::slice;
use ffi;
use glib::translate::{FromGlibPtr, ToGlibPtr};

pub struct TreePath {
    pointer:   *mut ffi::C_GtkTreePath
}

impl TreePath {
    pub fn new() -> Option<TreePath> {
        let tmp = unsafe { ffi::gtk_tree_path_new() };

        if tmp.is_null() {
            None
        } else {
            Some(TreePath {
                pointer: tmp
            })
        }
    }

    pub fn new_from_string(path: &str) -> Option<TreePath> {
        let tmp = unsafe {
            ffi::gtk_tree_path_new_from_string(path.borrow_to_glib().0)
        };

        if tmp.is_null() {
            None
        } else {
            Some(TreePath {
                pointer: tmp
            })
        }
    }

    #[cfg(feature = "gtk_3_12")]
    pub fn new_from_indicesv(indices: &mut [i32]) -> Option<TreePath> {
        let tmp = unsafe { ffi::gtk_tree_path_new_from_indicesv(indices.as_mut_ptr(), indices.len() as ::libc::c_ulong) };

        if tmp.is_null() {
            None
        } else {
            Some(TreePath {
                pointer: tmp
            })
        }
    }

    pub fn new_first() -> Option<TreePath> {
        let tmp = unsafe { ffi::gtk_tree_path_new_first() };

        if tmp.is_null() {
            None
        } else {
            Some(TreePath {
                pointer: tmp
            })
        }
    }

    #[allow(unused_variables)]
    pub fn to_string(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::take(
                ffi::gtk_tree_path_to_string(self.pointer))
        }
    }

    pub fn append_index(&self, index_: i32) {
        unsafe { ffi::gtk_tree_path_append_index(self.pointer, index_) }
    }

    pub fn prepend_index(&self, index_: i32) {
        unsafe { ffi::gtk_tree_path_prepend_index(self.pointer, index_) }
    }

    pub fn get_depth(&self) -> i32 {
        unsafe { ffi::gtk_tree_path_get_depth(self.pointer) }
    }

    pub fn get_indices(&self) -> Vec<i32> {
        let tmp = unsafe { ffi::gtk_tree_path_get_indices(self.pointer) };
        let depth = self.get_depth();

        unsafe {
            Vec::from(
                slice::from_raw_parts(tmp as *const i32, depth as usize))
        }
    }

    pub fn copy(&self) -> Option<TreePath> {
        let tmp = unsafe { ffi::gtk_tree_path_copy(self.pointer) };

        if tmp.is_null() {
            None
        } else {
            Some(TreePath {
                pointer: tmp
            })
        }
    }

    pub fn compare(&self, other: &TreePath) -> i32 {
        unsafe { ffi::gtk_tree_path_compare(self.pointer as *const ffi::C_GtkTreePath, other.pointer as *const ffi::C_GtkTreePath) }
    }

    pub fn next(&self) {
        unsafe { ffi::gtk_tree_path_next(self.pointer) }
    }

    pub fn prev(&self) {
        unsafe { ffi::gtk_tree_path_prev(self.pointer) }
    }

    pub fn path_up(&self) -> bool {
        match unsafe { ffi::gtk_tree_path_up(self.pointer) } {
            0 => false,
            _ => true
        }
    }

    pub fn path_down(&self) {
        unsafe { ffi::gtk_tree_path_down(self.pointer) }
    }

    pub fn is_ancestor(&self, descendant: &TreePath) -> bool {
        match unsafe { ffi::gtk_tree_path_is_ancestor(self.pointer, descendant.pointer) } {
            0 => false,
            _ => true
        }
    }

    pub fn is_descendant(&self, ancestor: &TreePath) -> bool {
        match unsafe { ffi::gtk_tree_path_is_descendant(self.pointer, ancestor.pointer) } {
            0 => false,
            _ => true
        }
    }

    pub fn drop(&mut self) {
        unsafe { ffi::gtk_tree_path_free(self.pointer as *mut ffi::C_GtkTreePath) }
        self.pointer = ::std::ptr::null_mut();
    }

    #[doc(hidden)]
    pub fn unwrap_pointer(&self) -> *mut ffi::C_GtkTreePath {
        self.pointer
    }

    #[doc(hidden)]
    pub fn wrap_pointer(c_treepath: *mut ffi::C_GtkTreePath) -> TreePath {
        unsafe{
            ::glib::ffi::g_object_ref(c_treepath as *mut ::libc::c_void);
        }

        TreePath {
            pointer: c_treepath
        }
    }
}
<commit_msg>Revert "Increase the refcount when wrapping a TreePath"<commit_after>// Copyright 2013-2015, The Rust-GNOME Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use std::slice;
use ffi;
use glib::translate::{FromGlibPtr, ToGlibPtr};

pub struct TreePath {
    pointer:   *mut ffi::C_GtkTreePath
}

impl TreePath {
    pub fn new() -> Option<TreePath> {
        let tmp = unsafe { ffi::gtk_tree_path_new() };

        if tmp.is_null() {
            None
        } else {
            Some(TreePath {
                pointer: tmp
            })
        }
    }

    pub fn new_from_string(path: &str) -> Option<TreePath> {
        let tmp = unsafe {
            ffi::gtk_tree_path_new_from_string(path.borrow_to_glib().0)
        };

        if tmp.is_null() {
            None
        } else {
            Some(TreePath {
                pointer: tmp
            })
        }
    }

    #[cfg(feature = "gtk_3_12")]
    pub fn new_from_indicesv(indices: &mut [i32]) -> Option<TreePath> {
        let tmp = unsafe { ffi::gtk_tree_path_new_from_indicesv(indices.as_mut_ptr(), indices.len() as ::libc::c_ulong) };

        if tmp.is_null() {
            None
        } else {
            Some(TreePath {
                pointer: tmp
            })
        }
    }

    pub fn new_first() -> Option<TreePath> {
        let tmp = unsafe { ffi::gtk_tree_path_new_first() };

        if tmp.is_null() {
            None
        } else {
            Some(TreePath {
                pointer: tmp
            })
        }
    }

    #[allow(unused_variables)]
    pub fn to_string(&self) -> Option<String> {
        unsafe {
            FromGlibPtr::take(
                ffi::gtk_tree_path_to_string(self.pointer))
        }
    }

    pub fn append_index(&self, index_: i32) {
        unsafe { ffi::gtk_tree_path_append_index(self.pointer, index_) }
    }

    pub fn prepend_index(&self, index_: i32) {
        unsafe { ffi::gtk_tree_path_prepend_index(self.pointer, index_) }
    }

    pub fn get_depth(&self) -> i32 {
        unsafe { ffi::gtk_tree_path_get_depth(self.pointer) }
    }

    pub fn get_indices(&self) -> Vec<i32> {
        let tmp = unsafe { ffi::gtk_tree_path_get_indices(self.pointer) };
        let depth = self.get_depth();

        unsafe {
            Vec::from(
                slice::from_raw_parts(tmp as *const i32, depth as usize))
        }
    }

    pub fn copy(&self) -> Option<TreePath> {
        let tmp = unsafe { ffi::gtk_tree_path_copy(self.pointer) };

        if tmp.is_null() {
            None
        } else {
            Some(TreePath {
                pointer: tmp
            })
        }
    }

    pub fn compare(&self, other: &TreePath) -> i32 {
        unsafe { ffi::gtk_tree_path_compare(self.pointer as *const ffi::C_GtkTreePath, other.pointer as *const ffi::C_GtkTreePath) }
    }

    pub fn next(&self) {
        unsafe { ffi::gtk_tree_path_next(self.pointer) }
    }

    pub fn prev(&self) {
        unsafe { ffi::gtk_tree_path_prev(self.pointer) }
    }

    pub fn path_up(&self) -> bool {
        match unsafe { ffi::gtk_tree_path_up(self.pointer) } {
            0 => false,
            _ => true
        }
    }

    pub fn path_down(&self) {
        unsafe { ffi::gtk_tree_path_down(self.pointer) }
    }

    pub fn is_ancestor(&self, descendant: &TreePath) -> bool {
        match unsafe { ffi::gtk_tree_path_is_ancestor(self.pointer, descendant.pointer) } {
            0 => false,
            _ => true
        }
    }

    pub fn is_descendant(&self, ancestor: &TreePath) -> bool {
        match unsafe { ffi::gtk_tree_path_is_descendant(self.pointer, ancestor.pointer) } {
            0 => false,
            _ => true
        }
    }

    pub fn drop(&mut self) {
        unsafe { ffi::gtk_tree_path_free(self.pointer as *mut ffi::C_GtkTreePath) }
        self.pointer = ::std::ptr::null_mut();
    }

    #[doc(hidden)]
    pub fn unwrap_pointer(&self) -> *mut ffi::C_GtkTreePath {
        self.pointer
    }

    #[doc(hidden)]
    pub fn wrap_pointer(c_treepath: *mut ffi::C_GtkTreePath) -> TreePath {
        TreePath {
            pointer: c_treepath
        }
    }
}
<|endoftext|>


<commit_before>//! Lettre is a mailer written in Rust. It provides a simple email builder and several transports.
//!
//! This mailer contains the available transports for your emails.
//!

#![doc(html_root_url = "https://docs.rs/lettre/0.9.0")]
#![deny(
    missing_copy_implementations,
    trivial_casts,
    trivial_numeric_casts,
    unsafe_code,
    unstable_features,
    unused_import_braces
)]

pub mod error;
#[cfg(feature = "file-transport")]
pub mod file;
#[cfg(feature = "sendmail-transport")]
pub mod sendmail;
#[cfg(feature = "smtp-transport")]
pub mod smtp;
pub mod stub;

use crate::error::EmailResult;
use crate::error::Error;
#[cfg(feature = "file-transport")]
pub use crate::file::FileTransport;
#[cfg(feature = "sendmail-transport")]
pub use crate::sendmail::SendmailTransport;
#[cfg(feature = "smtp-transport")]
pub use crate::smtp::client::net::ClientTlsParameters;
#[cfg(feature = "smtp-transport")]
pub use crate::smtp::{ClientSecurity, SmtpClient, SmtpTransport};
use fast_chemail::is_valid_email;
#[cfg(all(feature = "smtp-transport", feature = "connection-pool"))]
pub use smtp::r2d2::SmtpConnectionManager;
use std::ffi::OsStr;
use std::fmt::{self, Display, Formatter};
use std::io;
use std::io::Cursor;
use std::io::Read;
use std::str::FromStr;

/// Email address
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(
    feature = "serde-impls",
    derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct EmailAddress(String);

impl EmailAddress {
    pub fn new(address: String) -> EmailResult<EmailAddress> {
        if !is_valid_email(&address) && !address.ends_with("localhost") {
            Err(Error::InvalidEmailAddress)?;
        }
        Ok(EmailAddress(address))
    }
}

impl FromStr for EmailAddress {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        EmailAddress::new(s.to_string())
    }
}

impl Display for EmailAddress {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        f.write_str(&self.0)
    }
}

impl AsRef<str> for EmailAddress {
    fn as_ref(&self) -> &str {
        &self.0
    }
}

impl AsRef<OsStr> for EmailAddress {
    fn as_ref(&self) -> &OsStr {
        &self.0.as_ref()
    }
}

/// Simple email envelope representation
///
/// We only accept mailboxes, and do not support source routes (as per RFC).
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(
    feature = "serde-impls",
    derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct Envelope {
    /// The envelope recipients' addresses
    ///
    /// This can not be empty.
    forward_path: Vec<EmailAddress>,
    /// The envelope sender address
    reverse_path: Option<EmailAddress>,
}

impl Envelope {
    /// Creates a new envelope, which may fail if `to` is empty.
    pub fn new(from: Option<EmailAddress>, to: Vec<EmailAddress>) -> EmailResult<Envelope> {
        if to.is_empty() {
            Err(Error::MissingTo)?;
        }
        Ok(Envelope {
            forward_path: to,
            reverse_path: from,
        })
    }

    /// Destination addresses of the envelope
    pub fn to(&self) -> &[EmailAddress] {
        self.forward_path.as_slice()
    }

    /// Source address of the envelope
    pub fn from(&self) -> Option<&EmailAddress> {
        self.reverse_path.as_ref()
    }
}

pub enum Message {
    Reader(Box<Read + Send>),
    Bytes(Cursor<Vec<u8>>),
}

impl Read for Message {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match *self {
            Message::Reader(ref mut rdr) => rdr.read(buf),
            Message::Bytes(ref mut rdr) => rdr.read(buf),
        }
    }
}

/// Sendable email structure
pub struct SendableEmail {
    envelope: Envelope,
    message_id: String,
    message: Message,
}

impl SendableEmail {
    pub fn new(envelope: Envelope, message_id: String, message: Vec<u8>) -> SendableEmail {
        SendableEmail {
            envelope,
            message_id,
            message: Message::Bytes(Cursor::new(message)),
        }
    }

    pub fn new_with_reader(
        envelope: Envelope,
        message_id: String,
        message: Box<Read + Send>,
    ) -> SendableEmail {
        SendableEmail {
            envelope,
            message_id,
            message: Message::Reader(message),
        }
    }

    pub fn envelope(&self) -> &Envelope {
        &self.envelope
    }

    pub fn message_id(&self) -> &str {
        &self.message_id
    }

    pub fn message(self) -> Message {
        self.message
    }

    pub fn message_to_string(mut self) -> Result<String, io::Error> {
        let mut message_content = String::new();
        self.message.read_to_string(&mut message_content)?;
        Ok(message_content)
    }
}

/// Transport method for emails
pub trait Transport<'a> {
    /// Result type for the transport
    type Result;

    /// Sends the email
    fn send(&mut self, email: SendableEmail) -> Self::Result;
}
<commit_msg>feat(all): Rust 2018 - fix for 1.31<commit_after>//! Lettre is a mailer written in Rust. It provides a simple email builder and several transports.
//!
//! This mailer contains the available transports for your emails.
//!

#![doc(html_root_url = "https://docs.rs/lettre/0.9.0")]
#![deny(
    missing_copy_implementations,
    trivial_casts,
    trivial_numeric_casts,
    unsafe_code,
    unstable_features,
    unused_import_braces
)]

pub mod error;
#[cfg(feature = "file-transport")]
pub mod file;
#[cfg(feature = "sendmail-transport")]
pub mod sendmail;
#[cfg(feature = "smtp-transport")]
pub mod smtp;
pub mod stub;

use crate::error::EmailResult;
use crate::error::Error;
#[cfg(feature = "file-transport")]
pub use crate::file::FileTransport;
#[cfg(feature = "sendmail-transport")]
pub use crate::sendmail::SendmailTransport;
#[cfg(feature = "smtp-transport")]
pub use crate::smtp::client::net::ClientTlsParameters;
#[cfg(feature = "smtp-transport")]
pub use crate::smtp::{ClientSecurity, SmtpClient, SmtpTransport};
use fast_chemail::is_valid_email;
#[cfg(all(feature = "smtp-transport", feature = "connection-pool"))]
pub use crate::smtp::r2d2::SmtpConnectionManager;
use std::ffi::OsStr;
use std::fmt::{self, Display, Formatter};
use std::io;
use std::io::Cursor;
use std::io::Read;
use std::str::FromStr;

/// Email address
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(
    feature = "serde-impls",
    derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct EmailAddress(String);

impl EmailAddress {
    pub fn new(address: String) -> EmailResult<EmailAddress> {
        if !is_valid_email(&address) && !address.ends_with("localhost") {
            Err(Error::InvalidEmailAddress)?;
        }
        Ok(EmailAddress(address))
    }
}

impl FromStr for EmailAddress {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        EmailAddress::new(s.to_string())
    }
}

impl Display for EmailAddress {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        f.write_str(&self.0)
    }
}

impl AsRef<str> for EmailAddress {
    fn as_ref(&self) -> &str {
        &self.0
    }
}

impl AsRef<OsStr> for EmailAddress {
    fn as_ref(&self) -> &OsStr {
        &self.0.as_ref()
    }
}

/// Simple email envelope representation
///
/// We only accept mailboxes, and do not support source routes (as per RFC).
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(
    feature = "serde-impls",
    derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct Envelope {
    /// The envelope recipients' addresses
    ///
    /// This can not be empty.
    forward_path: Vec<EmailAddress>,
    /// The envelope sender address
    reverse_path: Option<EmailAddress>,
}

impl Envelope {
    /// Creates a new envelope, which may fail if `to` is empty.
    pub fn new(from: Option<EmailAddress>, to: Vec<EmailAddress>) -> EmailResult<Envelope> {
        if to.is_empty() {
            Err(Error::MissingTo)?;
        }
        Ok(Envelope {
            forward_path: to,
            reverse_path: from,
        })
    }

    /// Destination addresses of the envelope
    pub fn to(&self) -> &[EmailAddress] {
        self.forward_path.as_slice()
    }

    /// Source address of the envelope
    pub fn from(&self) -> Option<&EmailAddress> {
        self.reverse_path.as_ref()
    }
}

pub enum Message {
    Reader(Box<Read + Send>),
    Bytes(Cursor<Vec<u8>>),
}

impl Read for Message {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match *self {
            Message::Reader(ref mut rdr) => rdr.read(buf),
            Message::Bytes(ref mut rdr) => rdr.read(buf),
        }
    }
}

/// Sendable email structure
pub struct SendableEmail {
    envelope: Envelope,
    message_id: String,
    message: Message,
}

impl SendableEmail {
    pub fn new(envelope: Envelope, message_id: String, message: Vec<u8>) -> SendableEmail {
        SendableEmail {
            envelope,
            message_id,
            message: Message::Bytes(Cursor::new(message)),
        }
    }

    pub fn new_with_reader(
        envelope: Envelope,
        message_id: String,
        message: Box<Read + Send>,
    ) -> SendableEmail {
        SendableEmail {
            envelope,
            message_id,
            message: Message::Reader(message),
        }
    }

    pub fn envelope(&self) -> &Envelope {
        &self.envelope
    }

    pub fn message_id(&self) -> &str {
        &self.message_id
    }

    pub fn message(self) -> Message {
        self.message
    }

    pub fn message_to_string(mut self) -> Result<String, io::Error> {
        let mut message_content = String::new();
        self.message.read_to_string(&mut message_content)?;
        Ok(message_content)
    }
}

/// Transport method for emails
pub trait Transport<'a> {
    /// Result type for the transport
    type Result;

    /// Sends the email
    fn send(&mut self, email: SendableEmail) -> Self::Result;
}
<|endoftext|>


<commit_before>//! Package ID parsing and generation
use std::collections::HashMap;
use std::fmt;

use semver::Version;
use url::Url;

use package_id::PackageId;
use util::{CraftResult, ToUrl, human, ToSemver, ChainError};

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct PackageIdSpec {
    name: String,
    version: Option<Version>,
    url: Option<Url>,
}

impl PackageIdSpec {
    pub fn parse(spec: &str) -> CraftResult<PackageIdSpec> {
        if spec.contains("/") {
            if let Ok(url) = spec.to_url() {
                return PackageIdSpec::from_url(url);
            }
            if !spec.contains("://") {
                if let Ok(url) = Url::parse(&format!("craft://{}", spec)) {
                    return PackageIdSpec::from_url(url);
                }
            }
        }
        let mut parts = spec.splitn(2, ':');
        let name = parts.next().unwrap();
        let version = match parts.next() {
            Some(version) => Some(try!(Version::parse(version).map_err(human))),
            None => None,
        };
        for ch in name.chars() {
            if !ch.is_alphanumeric() && ch != '_' && ch != '-' {
                bail!("invalid character in pkgid `{}`: `{}`", spec, ch)
            }
        }
        Ok(PackageIdSpec {
            name: name.to_string(),
            version: version,
            url: None,
        })
    }

    pub fn query_str<'a, I>(spec: &str, i: I) -> CraftResult<&'a PackageId>
        where I: IntoIterator<Item = &'a PackageId>
    {
        let spec = try!(PackageIdSpec::parse(spec)
            .chain_error(|| human(format!("invalid package id specification: `{}`", spec))));
        spec.query(i)
    }

    pub fn from_package_id(package_id: &PackageId) -> PackageIdSpec {
        PackageIdSpec {
            name: package_id.name().to_string(),
            version: Some(package_id.version().clone()),
            url: Some(package_id.source_id().url().clone()),
        }
    }

    fn from_url(mut url: Url) -> CraftResult<PackageIdSpec> {
        if url.query().is_some() {
            bail!("cannot have a query string in a pkgid: {}", url)
        }
        let frag = url.fragment().map(|s| s.to_owned());
        url.set_fragment(None);
        let (name, version) = {
            let mut path = try!(url.path_segments()
                .chain_error(|| human(format!("pkgid urls must have a path: {}", url))));
            let path_name = try!(path.next_back()
                .chain_error(|| human(format!("pkgid urls must have at least one path component: {}", url))));
            match frag {
                Some(fragment) => {
                    let mut parts = fragment.splitn(2, ':');
                    let name_or_version = parts.next().unwrap();
                    match parts.next() {
                        Some(part) => {
                            let version = try!(part.to_semver().map_err(human));
                            (name_or_version.to_string(), Some(version))
                        }
                        None => {
                            if name_or_version.chars()
                                .next()
                                .unwrap()
                                .is_alphabetic() {
                                (name_or_version.to_string(), None)
                            } else {
                                let version = try!(name_or_version.to_semver()
                                    .map_err(human));
                                (path_name.to_string(), Some(version))
                            }
                        }
                    }
                }
                None => (path_name.to_string(), None),
            }
        };
        Ok(PackageIdSpec {
            name: name,
            version: version,
            url: Some(url),
        })
    }

    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn version(&self) -> Option<&Version> {
        self.version.as_ref()
    }

    pub fn url(&self) -> Option<&Url> {
        self.url.as_ref()
    }

    pub fn set_url(&mut self, url: Url) {
        self.url = Some(url);
    }

    pub fn matches(&self, package_id: &PackageId) -> bool {
        if self.name() != package_id.name() {
            return false;
        }

        match self.version {
            Some(ref v) => {
                if v != package_id.version() {
                    return false;
                }
            }
            None => {}
        }

        match self.url {
            Some(ref u) => u == package_id.source_id().url(),
            None => true,
        }
    }

    pub fn query<'a, I>(&self, i: I) -> CraftResult<&'a PackageId>
        where I: IntoIterator<Item = &'a PackageId>
    {
        let mut ids = i.into_iter().filter(|p| self.matches(*p));
        let ret = match ids.next() {
            Some(id) => id,
            None => bail!("package id specification `{}` matched no packages", self),
        };
        return match ids.next() {
            Some(other) => {
                let mut msg = format!("There are multiple `{}` packages in your project, and the specification `{}` \
                                       is ambiguous.\nPlease re-run this command with `-p <spec>` where `<spec>` is \
                                       one of the following:",
                                      self.name(),
                                      self);
                let mut vec = vec![ret, other];
                vec.extend(ids);
                minimize(&mut msg, vec, self);
                Err(human(msg))
            }
            None => Ok(ret),
        };

        fn minimize(msg: &mut String, ids: Vec<&PackageId>, spec: &PackageIdSpec) {
            let mut version_cnt = HashMap::new();
            for id in ids.iter() {
                *version_cnt.entry(id.version()).or_insert(0) += 1;
            }
            for id in ids.iter() {
                if version_cnt[id.version()] == 1 {
                    msg.push_str(&format!("\n  {}:{}", spec.name(), id.version()));
                } else {
                    msg.push_str(&format!("\n  {}", PackageIdSpec::from_package_id(*id)));
                }
            }
        }
    }
}

impl fmt::Display for PackageIdSpec {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut printed_name = false;
        match self.url {
            Some(ref url) => {
                if url.scheme() == "craft" {
                    try!(write!(f, "{}{}", url.host().unwrap(), url.path()));
                } else {
                    try!(write!(f, "{}", url));
                }
                if url.path_segments().unwrap().next_back().unwrap() != &self.name {
                    printed_name = true;
                    try!(write!(f, "#{}", self.name));
                }
            }
            None => {
                printed_name = true;
                try!(write!(f, "{}", self.name))
            }
        }
        match self.version {
            Some(ref v) => {
                try!(write!(f, "{}{}", if printed_name { ":" } else { "#" }, v));
            }
            None => {}
        }
        Ok(())
    }
}
<commit_msg>Improved doc<commit_after>//! Package ID specifications
use std::collections::HashMap;
use std::fmt;

use semver::Version;
use url::Url;

use package_id::PackageId;
use util::{CraftResult, ToUrl, human, ToSemver, ChainError};

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct PackageIdSpec {
    name: String,
    version: Option<Version>,
    url: Option<Url>,
}

impl PackageIdSpec {
    pub fn parse(spec: &str) -> CraftResult<PackageIdSpec> {
        if spec.contains("/") {
            if let Ok(url) = spec.to_url() {
                return PackageIdSpec::from_url(url);
            }
            if !spec.contains("://") {
                if let Ok(url) = Url::parse(&format!("craft://{}", spec)) {
                    return PackageIdSpec::from_url(url);
                }
            }
        }
        let mut parts = spec.splitn(2, ':');
        let name = parts.next().unwrap();
        let version = match parts.next() {
            Some(version) => Some(try!(Version::parse(version).map_err(human))),
            None => None,
        };
        for ch in name.chars() {
            if !ch.is_alphanumeric() && ch != '_' && ch != '-' {
                bail!("invalid character in pkgid `{}`: `{}`", spec, ch)
            }
        }
        Ok(PackageIdSpec {
            name: name.to_string(),
            version: version,
            url: None,
        })
    }

    pub fn query_str<'a, I>(spec: &str, i: I) -> CraftResult<&'a PackageId>
        where I: IntoIterator<Item = &'a PackageId>
    {
        let spec = try!(PackageIdSpec::parse(spec)
            .chain_error(|| human(format!("invalid package id specification: `{}`", spec))));
        spec.query(i)
    }

    pub fn from_package_id(package_id: &PackageId) -> PackageIdSpec {
        PackageIdSpec {
            name: package_id.name().to_string(),
            version: Some(package_id.version().clone()),
            url: Some(package_id.source_id().url().clone()),
        }
    }

    fn from_url(mut url: Url) -> CraftResult<PackageIdSpec> {
        if url.query().is_some() {
            bail!("cannot have a query string in a pkgid: {}", url)
        }
        let frag = url.fragment().map(|s| s.to_owned());
        url.set_fragment(None);
        let (name, version) = {
            let mut path = try!(url.path_segments()
                .chain_error(|| human(format!("pkgid urls must have a path: {}", url))));
            let path_name = try!(path.next_back()
                .chain_error(|| human(format!("pkgid urls must have at least one path component: {}", url))));
            match frag {
                Some(fragment) => {
                    let mut parts = fragment.splitn(2, ':');
                    let name_or_version = parts.next().unwrap();
                    match parts.next() {
                        Some(part) => {
                            let version = try!(part.to_semver().map_err(human));
                            (name_or_version.to_string(), Some(version))
                        }
                        None => {
                            if name_or_version.chars()
                                .next()
                                .unwrap()
                                .is_alphabetic() {
                                (name_or_version.to_string(), None)
                            } else {
                                let version = try!(name_or_version.to_semver()
                                    .map_err(human));
                                (path_name.to_string(), Some(version))
                            }
                        }
                    }
                }
                None => (path_name.to_string(), None),
            }
        };
        Ok(PackageIdSpec {
            name: name,
            version: version,
            url: Some(url),
        })
    }

    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn version(&self) -> Option<&Version> {
        self.version.as_ref()
    }

    pub fn url(&self) -> Option<&Url> {
        self.url.as_ref()
    }

    pub fn set_url(&mut self, url: Url) {
        self.url = Some(url);
    }

    pub fn matches(&self, package_id: &PackageId) -> bool {
        if self.name() != package_id.name() {
            return false;
        }

        match self.version {
            Some(ref v) => {
                if v != package_id.version() {
                    return false;
                }
            }
            None => {}
        }

        match self.url {
            Some(ref u) => u == package_id.source_id().url(),
            None => true,
        }
    }

    pub fn query<'a, I>(&self, i: I) -> CraftResult<&'a PackageId>
        where I: IntoIterator<Item = &'a PackageId>
    {
        let mut ids = i.into_iter().filter(|p| self.matches(*p));
        let ret = match ids.next() {
            Some(id) => id,
            None => bail!("package id specification `{}` matched no packages", self),
        };
        return match ids.next() {
            Some(other) => {
                let mut msg = format!("There are multiple `{}` packages in your project, and the specification `{}` \
                                       is ambiguous.\nPlease re-run this command with `-p <spec>` where `<spec>` is \
                                       one of the following:",
                                      self.name(),
                                      self);
                let mut vec = vec![ret, other];
                vec.extend(ids);
                minimize(&mut msg, vec, self);
                Err(human(msg))
            }
            None => Ok(ret),
        };

        fn minimize(msg: &mut String, ids: Vec<&PackageId>, spec: &PackageIdSpec) {
            let mut version_cnt = HashMap::new();
            for id in ids.iter() {
                *version_cnt.entry(id.version()).or_insert(0) += 1;
            }
            for id in ids.iter() {
                if version_cnt[id.version()] == 1 {
                    msg.push_str(&format!("\n  {}:{}", spec.name(), id.version()));
                } else {
                    msg.push_str(&format!("\n  {}", PackageIdSpec::from_package_id(*id)));
                }
            }
        }
    }
}

impl fmt::Display for PackageIdSpec {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut printed_name = false;
        match self.url {
            Some(ref url) => {
                if url.scheme() == "craft" {
                    try!(write!(f, "{}{}", url.host().unwrap(), url.path()));
                } else {
                    try!(write!(f, "{}", url));
                }
                if url.path_segments().unwrap().next_back().unwrap() != &self.name {
                    printed_name = true;
                    try!(write!(f, "#{}", self.name));
                }
            }
            None => {
                printed_name = true;
                try!(write!(f, "{}", self.name))
            }
        }
        match self.version {
            Some(ref v) => {
                try!(write!(f, "{}{}", if printed_name { ":" } else { "#" }, v));
            }
            None => {}
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::borrow::Borrow;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::mem;
use std::ptr;
use std::ops::{Deref, DerefMut};
use std::str;
use std::slice;

use array::Array;
use array::Index;
use CapacityError;

/// A string with a fixed capacity.
///
/// The `ArrayString` is a string backed by a fixed size array. It keeps track
/// of its length.
///
/// The string is a contiguous value that you can store directly on the stack
/// if needed.
#[derive(Copy)]
pub struct ArrayString<A: Array<Item=u8>> {
    xs: A,
    len: A::Index,
}

impl<A: Array<Item=u8>> ArrayString<A> {
    /// Create a new empty `ArrayString`.
    ///
    /// Capacity is inferred from the type parameter.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 16]>::new();
    /// string.push_str("foo");
    /// assert_eq!(&string[..], "foo");
    /// assert_eq!(string.capacity(), 16);
    /// ```
    pub fn new() -> ArrayString<A> {
        unsafe {
            ArrayString {
                xs: ::new_array(),
                len: Index::from(0),
            }
        }
    }

    /// Create a new `ArrayString` from a `str`.
    ///
    /// Capacity is inferred from the type parameter.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 3]>::from("foo").unwrap();
    /// assert_eq!(&string[..], "foo");
    /// assert_eq!(string.len(), 3);
    /// assert_eq!(string.capacity(), 3);
    /// ```
    pub fn from(s: &str) -> Result<Self, CapacityError<&str>> {
        let mut arraystr = Self::new();
        try!(arraystr.push_str(s));
        Ok(arraystr)
    }

    /// Return the capacity of the `ArrayString`.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let string = ArrayString::<[_; 3]>::new();
    /// assert_eq!(string.capacity(), 3);
    /// ```
    #[inline]
    pub fn capacity(&self) -> usize { A::capacity() }

    /// Adds the given char to the end of the string.
    ///
    /// Returns `Ok` if the push succeeds, and returns `Err` if the backing
    /// array is not large enough to fit the additional char.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 2]>::new();
    ///
    /// string.push('a').unwrap();
    /// string.push('b').unwrap();
    /// let overflow = string.push('c');
    ///
    /// assert_eq!(&string[..], "ab");
    /// assert_eq!(overflow.unwrap_err().element(), 'c');
    /// ```
    pub fn push(&mut self, c: char) -> Result<(), CapacityError<char>> {
        use std::fmt::Write;
        self.write_char(c).map_err(|_| CapacityError::new(c))
    }

    /// Adds the given string slice to the end of the string.
    ///
    /// Returns `Ok` if the push succeeds, and returns `Err` if the
    /// backing array is not large enough to fit the string.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 2]>::new();
    ///
    /// string.push_str("a").unwrap();
    /// let overflow1 = string.push_str("bc");
    /// string.push_str("d").unwrap();
    /// let overflow2 = string.push_str("ef");
    ///
    /// assert_eq!(&string[..], "ad");
    /// assert_eq!(overflow1.unwrap_err().element(), "bc");
    /// assert_eq!(overflow2.unwrap_err().element(), "ef");
    /// ```
    pub fn push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
        if s.len() > self.capacity() - self.len() {
            return Err(CapacityError::new(s));
        }
        unsafe {
            let dst = self.xs.as_mut_ptr().offset(self.len() as isize);
            let src = s.as_ptr();
            ptr::copy_nonoverlapping(src, dst, s.len());
            let newl = self.len() + s.len();
            self.set_len(newl);
        }
        Ok(())
    }

    /// Make the string empty.
    pub fn clear(&mut self) {
        unsafe {
            self.set_len(0);
        }
    }

    /// Set the strings's length.
    ///
    /// May panic if `length` is greater than the capacity.
    ///
    /// This function is `unsafe` because it changes the notion of the
    /// number of “valid” bytes in the string. Use with care.
    #[inline]
    pub unsafe fn set_len(&mut self, length: usize) {
        debug_assert!(length <= self.capacity());
        self.len = Index::from(length);
    }
}

impl<A: Array<Item=u8>> Deref for ArrayString<A> {
    type Target = str;
    #[inline]
    fn deref(&self) -> &str {
        unsafe {
            let sl = slice::from_raw_parts(self.xs.as_ptr(), self.len.to_usize());
            str::from_utf8_unchecked(sl)
        }
    }
}

impl<A: Array<Item=u8>> DerefMut for ArrayString<A> {
    #[inline]
    fn deref_mut(&mut self) -> &mut str {
        unsafe {
            let sl = slice::from_raw_parts_mut(self.xs.as_mut_ptr(), self.len.to_usize());
            // FIXME: Nothing but transmute to do this right now
            mem::transmute(sl)
        }
    }
}

impl<A: Array<Item=u8>> PartialEq for ArrayString<A> {
    fn eq(&self, rhs: &Self) -> bool {
        **self == **rhs
    }
}

impl<A: Array<Item=u8>> PartialEq<str> for ArrayString<A> {
    fn eq(&self, rhs: &str) -> bool {
        &**self == rhs
    }
}

impl<A: Array<Item=u8>> PartialEq<ArrayString<A>> for str {
    fn eq(&self, rhs: &ArrayString<A>) -> bool {
        self == &**rhs
    }
}

impl<A: Array<Item=u8>> Eq for ArrayString<A> { }

impl<A: Array<Item=u8>> Hash for ArrayString<A> {
    fn hash<H: Hasher>(&self, h: &mut H) {
        (**self).hash(h)
    }
}

impl<A: Array<Item=u8>> Borrow<str> for ArrayString<A> {
    fn borrow(&self) -> &str { self }
}

impl<A: Array<Item=u8>> AsRef<str> for ArrayString<A> {
    fn as_ref(&self) -> &str { self }
}

impl<A: Array<Item=u8>> fmt::Debug for ArrayString<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
}

impl<A: Array<Item=u8>> fmt::Display for ArrayString<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
}

/// `Write` appends written data to the end of the string.
impl<A: Array<Item=u8>> fmt::Write for ArrayString<A> {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.push_str(s).map_err(|_| fmt::Error)
    }
}

impl<A: Array<Item=u8> + Copy> Clone for ArrayString<A> {
    fn clone(&self) -> ArrayString<A> {
        *self
    }

    fn clone_from(&mut self, rhs: &Self) {
        // guaranteed to fit due to types matching.
        self.clear();
        self.push_str(rhs).ok();
    }
}
<commit_msg>Edit docs for methods returning Result<commit_after>use std::borrow::Borrow;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::mem;
use std::ptr;
use std::ops::{Deref, DerefMut};
use std::str;
use std::slice;

use array::Array;
use array::Index;
use CapacityError;

/// A string with a fixed capacity.
///
/// The `ArrayString` is a string backed by a fixed size array. It keeps track
/// of its length.
///
/// The string is a contiguous value that you can store directly on the stack
/// if needed.
#[derive(Copy)]
pub struct ArrayString<A: Array<Item=u8>> {
    xs: A,
    len: A::Index,
}

impl<A: Array<Item=u8>> ArrayString<A> {
    /// Create a new empty `ArrayString`.
    ///
    /// Capacity is inferred from the type parameter.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 16]>::new();
    /// string.push_str("foo");
    /// assert_eq!(&string[..], "foo");
    /// assert_eq!(string.capacity(), 16);
    /// ```
    pub fn new() -> ArrayString<A> {
        unsafe {
            ArrayString {
                xs: ::new_array(),
                len: Index::from(0),
            }
        }
    }

    /// Create a new `ArrayString` from a `str`.
    ///
    /// Capacity is inferred from the type parameter.
    ///
    /// **Errors** if the backing array is not large enough to fit the string.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 3]>::from("foo").unwrap();
    /// assert_eq!(&string[..], "foo");
    /// assert_eq!(string.len(), 3);
    /// assert_eq!(string.capacity(), 3);
    /// ```
    pub fn from(s: &str) -> Result<Self, CapacityError<&str>> {
        let mut arraystr = Self::new();
        try!(arraystr.push_str(s));
        Ok(arraystr)
    }

    /// Return the capacity of the `ArrayString`.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let string = ArrayString::<[_; 3]>::new();
    /// assert_eq!(string.capacity(), 3);
    /// ```
    #[inline]
    pub fn capacity(&self) -> usize { A::capacity() }

    /// Adds the given char to the end of the string.
    ///
    /// Returns `Ok` if the push succeeds.
    ///
    /// **Errors** if the backing array is not large enough to fit the additional char.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 2]>::new();
    ///
    /// string.push('a').unwrap();
    /// string.push('b').unwrap();
    /// let overflow = string.push('c');
    ///
    /// assert_eq!(&string[..], "ab");
    /// assert_eq!(overflow.unwrap_err().element(), 'c');
    /// ```
    pub fn push(&mut self, c: char) -> Result<(), CapacityError<char>> {
        use std::fmt::Write;
        self.write_char(c).map_err(|_| CapacityError::new(c))
    }

    /// Adds the given string slice to the end of the string.
    ///
    /// Returns `Ok` if the push succeeds.
    ///
    /// **Errors** if the backing array is not large enough to fit the string.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 2]>::new();
    ///
    /// string.push_str("a").unwrap();
    /// let overflow1 = string.push_str("bc");
    /// string.push_str("d").unwrap();
    /// let overflow2 = string.push_str("ef");
    ///
    /// assert_eq!(&string[..], "ad");
    /// assert_eq!(overflow1.unwrap_err().element(), "bc");
    /// assert_eq!(overflow2.unwrap_err().element(), "ef");
    /// ```
    pub fn push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
        if s.len() > self.capacity() - self.len() {
            return Err(CapacityError::new(s));
        }
        unsafe {
            let dst = self.xs.as_mut_ptr().offset(self.len() as isize);
            let src = s.as_ptr();
            ptr::copy_nonoverlapping(src, dst, s.len());
            let newl = self.len() + s.len();
            self.set_len(newl);
        }
        Ok(())
    }

    /// Make the string empty.
    pub fn clear(&mut self) {
        unsafe {
            self.set_len(0);
        }
    }

    /// Set the strings's length.
    ///
    /// May panic if `length` is greater than the capacity.
    ///
    /// This function is `unsafe` because it changes the notion of the
    /// number of “valid” bytes in the string. Use with care.
    #[inline]
    pub unsafe fn set_len(&mut self, length: usize) {
        debug_assert!(length <= self.capacity());
        self.len = Index::from(length);
    }
}

impl<A: Array<Item=u8>> Deref for ArrayString<A> {
    type Target = str;
    #[inline]
    fn deref(&self) -> &str {
        unsafe {
            let sl = slice::from_raw_parts(self.xs.as_ptr(), self.len.to_usize());
            str::from_utf8_unchecked(sl)
        }
    }
}

impl<A: Array<Item=u8>> DerefMut for ArrayString<A> {
    #[inline]
    fn deref_mut(&mut self) -> &mut str {
        unsafe {
            let sl = slice::from_raw_parts_mut(self.xs.as_mut_ptr(), self.len.to_usize());
            // FIXME: Nothing but transmute to do this right now
            mem::transmute(sl)
        }
    }
}

impl<A: Array<Item=u8>> PartialEq for ArrayString<A> {
    fn eq(&self, rhs: &Self) -> bool {
        **self == **rhs
    }
}

impl<A: Array<Item=u8>> PartialEq<str> for ArrayString<A> {
    fn eq(&self, rhs: &str) -> bool {
        &**self == rhs
    }
}

impl<A: Array<Item=u8>> PartialEq<ArrayString<A>> for str {
    fn eq(&self, rhs: &ArrayString<A>) -> bool {
        self == &**rhs
    }
}

impl<A: Array<Item=u8>> Eq for ArrayString<A> { }

impl<A: Array<Item=u8>> Hash for ArrayString<A> {
    fn hash<H: Hasher>(&self, h: &mut H) {
        (**self).hash(h)
    }
}

impl<A: Array<Item=u8>> Borrow<str> for ArrayString<A> {
    fn borrow(&self) -> &str { self }
}

impl<A: Array<Item=u8>> AsRef<str> for ArrayString<A> {
    fn as_ref(&self) -> &str { self }
}

impl<A: Array<Item=u8>> fmt::Debug for ArrayString<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
}

impl<A: Array<Item=u8>> fmt::Display for ArrayString<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
}

/// `Write` appends written data to the end of the string.
impl<A: Array<Item=u8>> fmt::Write for ArrayString<A> {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.push_str(s).map_err(|_| fmt::Error)
    }
}

impl<A: Array<Item=u8> + Copy> Clone for ArrayString<A> {
    fn clone(&self) -> ArrayString<A> {
        *self
    }

    fn clone_from(&mut self, rhs: &Self) {
        // guaranteed to fit due to types matching.
        self.clear();
        self.push_str(rhs).ok();
    }
}
<|endoftext|>


<commit_before>use utils::json_helper::*;
use std::collections::HashMap;
use std::sync::Mutex;
use ErrorCode;

lazy_static! {
    static ref RESPONSES: Mutex<HashMap<String, String>> = Default::default();
}

pub fn add_response(request: &str, response: &str) -> Result<(), ErrorCode> {
    let req_id = parse_req_id_from_request(request)?;
    let mut responses = RESPONSES.lock().unwrap();
    responses.insert(req_id.to_string(), response.to_string());
    Ok(())
}

pub fn parse_req_id_from_request(request: &str) -> Result<u64, ErrorCode> {
    let val = str_to_val(request)?;
    let object = val_to_obj(&val)?;
    let req_id = get_val_from_obj(object, "reqId")?;
    val_to_u64(req_id)
}

pub fn get_response(response: &str) -> Result<String, ErrorCode> {
    let val = str_to_val(response)?;
    let object = val_to_obj(&val)?;
    let result = get_val_from_obj(object, "result")?;
    let result_obj = val_to_obj(result)?;
    let req_id = get_val_from_obj(result_obj, "reqId")?;
    let req_id = val_to_u64(req_id)?;

    let mut responses = RESPONSES.lock().unwrap();
    match responses.remove(req_id.to_string().as_str()) {
        Some(ref resp) if resp == "INSUFFICIENT_FUNDS" => Err(ErrorCode::PaymentInsufficientFundsError),
        Some(resp) => Ok(resp),
        None => Err(ErrorCode::CommonInvalidState)
    }
}

<commit_msg>Fixed Libnullpay integration tests<commit_after>use utils::json_helper::*;
use std::collections::HashMap;
use std::sync::Mutex;
use ErrorCode;

lazy_static! {
    static ref RESPONSES: Mutex<HashMap<String, String>> = Default::default();
}

pub fn add_response(request: &str, response: &str) -> Result<(), ErrorCode> {
    let req_id = parse_req_id_from_request(request)?;
    let mut responses = RESPONSES.lock().unwrap();
    responses.insert(req_id.to_string(), response.to_string());
    Ok(())
}

pub fn parse_req_id_from_request(request: &str) -> Result<u64, ErrorCode> {
    let val = str_to_val(request)?;
    let object = val_to_obj(&val)?;
    let req_id = get_val_from_obj(object, "reqId")?;
    val_to_u64(req_id)
}

pub fn get_response(response: &str) -> Result<String, ErrorCode> {
    let val = str_to_val(response)?;

    let req_id = match val["result"]["ver"].as_str() {
        Some("1") =>
            val.get("result")
                .and_then(|result| result.as_object())
                .and_then(|result| result.get("txn"))
                .and_then(|txn| txn.as_object())
                .and_then(|txn| txn.get("metadata"))
                .and_then(|metadata| metadata.as_object())
                .and_then(|metadata| metadata.get("reqId"))
                .and_then(|req_id| req_id.as_i64()),
        None =>
            val.get("result")
                .and_then(|result| result.as_object())
                .and_then(|result| result.get("reqId"))
                .and_then(|req_id| req_id.as_i64()),
        _ => return Err(ErrorCode::CommonInvalidState)
    };

    let req_id = req_id.ok_or(ErrorCode::CommonInvalidStructure)?;

    let mut responses = RESPONSES.lock().unwrap();
    match responses.remove(req_id.to_string().as_str()) {
        Some(ref resp) if resp == "INSUFFICIENT_FUNDS" => Err(ErrorCode::PaymentInsufficientFundsError),
        Some(resp) => Ok(resp),
        None => Err(ErrorCode::CommonInvalidState)
    }
}

<|endoftext|>


<commit_before>//! Layout handling

use rustwlc::handle::{WlcView, WlcOutput};
use std::rc::{Rc, Weak};

#[derive(PartialEq, Clone, Copy)]
pub enum ContainerType {
    Root,        /* Root container, only one exists */
    Output,      /* Output, like a monitor or head */
    Workspace,   /* A workspace */
    View         /* A view (aka a window) */
}

/// Types of container
enum ContainerTypes {
    /// Root container, only one exists
    Root,
    /// WlcOutput/monitor
    Output,
    /// A workspace
    Workspace,
    /// A view (window)
    View
}

/// Layout mode for a container
enum Layout {
    None,
    Horizontal,
    Vertical,
    Stacked,
    Tabbed,
    Floating
}

/// Like i3, everything (workspaces, containers, views) are containable.
pub trait Containable {
    /// Gets the parent that this container sits in.
    ///
    /// If the container is the root, it returns None
    fn get_parent(&self) -> Option<&Containable>;

    /// Gets the children of this container.
    ///
    /// Views never have children
    fn get_children(&self) -> Option<Vec<Weak<Box<Containable>>>>;

    /// Gets the type of the container
    fn get_type(&self) -> ContainerType;

    /// Returns true if this container is focused.
    fn is_focused(&self) -> bool;

    /// Removes this container and all of its children
    fn remove_container(&self) -> Result<(), &'static str>;

    /// Sets this container (and everything in it) to given visibility
    fn set_visibility(&mut self, visibility: bool);

    /// Gets the X and Y dimensions of the container
    fn get_dimensions(&self) -> (u64, u64);

    /// Gets the position of this container on the screen
    fn get_position(&self) -> (i64, i64);

    /// Finds a parent container with the given type, if there is any
    fn get_parent_by_type(&self, type_: ContainerType) -> Option<&Containable> {
        let mut container = self.get_parent();
        while container.is_some() && container.unwrap().get_type() != type_ {
            container = container.unwrap().get_parent();
        }
        container
    }
}

/// View specific functions
pub trait Viewable {
    /// Determines if the view is full screen
    fn is_fullscreen(&self) -> bool;

    /// Figures out if the view is focused
    fn is_active(&self) -> bool;

    /// Returns true if this view is a parent is an ancestor of the child
    fn is_parent_of<T: Containable>(&self, child: T) -> bool;

    /// Returns true if this view is a child is an decedent of the parent
    fn is_child_of<T: Containable>(&self, parent: T) -> bool;

    /// Gets the active workspace of the view
    fn active_workspace<T: Containable>(&self) -> T;
}

struct Container {
    handle: Option<WlcOutput>,

    parent: Box<Containable>,
    children: Vec<Rc<Box<Containable>>>,
    type_: ContainerType,
    layout: Layout,

    width: u64,
    height: u64,

    x: i64,
    y: i64,

    visible: bool,
    is_focused: bool,
    is_floating: bool,
}

impl Containable for Container {

    /// Gets the parent that this container sits in.
    ///
    /// If the container is the root, it returns None
    fn get_parent(&self) -> Option<&Containable> {
        match self.type_ {
            ContainerType::Root => None,
            _ => Some(&*self.parent),
        }
    }
    /// Gets the children of this container.
    ///
    /// Views never have children
    fn get_children(&self) -> Option<Vec<Weak<Box<Containable>>>> {
        if self.children.len() == 0 {
            None
        } else {
            Some(self.children.iter().map(|child| Rc::downgrade(&child)).collect())
        }
    }

    fn get_type(&self) -> ContainerType {
        self.type_
    }

    /// Returns true if this container is focused.
    fn is_focused(&self) -> bool {
        self.is_focused
    }

    /// Removes this container and all of its children
    fn remove_container(&self) -> Result<(), &'static str> {
        for child in self.get_children().expect("No children") {
            if let Some(child) = child.upgrade() {
                if let Ok(child) = Rc::try_unwrap(child) {
                    child.remove_container();
                    drop(child);
                }
            }
        }
        Ok(())
    }

    /// Sets this container (and everything in it) to given visibility
    fn set_visibility(&mut self, visibility: bool) {
        self.visible = visibility
    }

    /// Gets the X (width) and Y (height) dimensions of the container
    fn get_dimensions(&self) -> (u64, u64) {
        (self.width, self.height)
    }

    /// Gets the position of this container on the screen
    fn get_position(&self) -> (i64, i64) {
        (self.x, self.y)
    }

}

struct View {
    handle: Option<WlcView>,
    parent: Box<Containable>,

    width: u64,
    height: u64,

    x: i64,
    y: i64,

    visible: bool,
    is_focused: bool,
    is_floating: bool,
}

impl Containable for View {
    /// Gets the parent that this container sits in.
    ///
    /// If the container is the root, it returns None
    fn get_parent(&self) -> Option<&Containable> {
        Some(&*self.parent)
    }

    /// Gets the children of this container.
    ///
    /// Views never have children
    fn get_children(&self) -> Option<Vec<Weak<Box<Containable>>>> {
        None
    }

    /// Gets the type of the container
    fn get_type(&self) -> ContainerType {
        ContainerType::View
    }

    /// Returns true if this container is focused.
    fn is_focused(&self) -> bool {
        self.is_focused
    }

    /// Removes this container and all of its children
    fn remove_container(&self) -> Result<(), &'static str> {
        unimplemented!();
    }

    /// Sets this container (and everything in it) to given visibility
    fn set_visibility(&mut self, visibility: bool) {
        self.visible = visibility
    }

    /// Gets the X and Y dimensions of the container
    fn get_dimensions(&self) -> (u64, u64) {
        (self.width, self.height)
    }

    /// Gets the position of this container on the screen
    fn get_position(&self) -> (i64, i64) {
        (self.x, self.y)
    }
}
<commit_msg>Added Node type alias, for Box<Containable><commit_after>//! Layout handling

use rustwlc::handle::{WlcView, WlcOutput};
use std::rc::{Rc, Weak};

type Node = Box<Containable>;

#[derive(PartialEq, Clone, Copy)]
pub enum ContainerType {
    Root,        /* Root container, only one exists */
    Output,      /* Output, like a monitor or head */
    Workspace,   /* A workspace */
    View         /* A view (aka a window) */
}

/// Types of container
enum ContainerTypes {
    /// Root container, only one exists
    Root,
    /// WlcOutput/monitor
    Output,
    /// A workspace
    Workspace,
    /// A view (window)
    View
}

/// Layout mode for a container
enum Layout {
    None,
    Horizontal,
    Vertical,
    Stacked,
    Tabbed,
    Floating
}

/// Like i3, everything (workspaces, containers, views) are containable.
pub trait Containable {
    /// Gets the parent that this container sits in.
    ///
    /// If the container is the root, it returns None
    fn get_parent(&self) -> Option<&Containable>;

    /// Gets the children of this container.
    ///
    /// Views never have children
    fn get_children(&self) -> Option<Vec<Weak<Node>>>;

    /// Gets the type of the container
    fn get_type(&self) -> ContainerType;

    /// Returns true if this container is focused.
    fn is_focused(&self) -> bool;

    /// Removes this container and all of its children
    fn remove_container(&self) -> Result<(), &'static str>;

    /// Sets this container (and everything in it) to given visibility
    fn set_visibility(&mut self, visibility: bool);

    /// Gets the X and Y dimensions of the container
    fn get_dimensions(&self) -> (u64, u64);

    /// Gets the position of this container on the screen
    fn get_position(&self) -> (i64, i64);

    /// Finds a parent container with the given type, if there is any
    fn get_parent_by_type(&self, type_: ContainerType) -> Option<&Containable> {
        let mut container = self.get_parent();
        while container.is_some() && container.unwrap().get_type() != type_ {
            container = container.unwrap().get_parent();
        }
        container
    }
}

/// View specific functions
pub trait Viewable {
    /// Determines if the view is full screen
    fn is_fullscreen(&self) -> bool;

    /// Figures out if the view is focused
    fn is_active(&self) -> bool;

    /// Returns true if this view is a parent is an ancestor of the child
    fn is_parent_of<T: Containable>(&self, child: T) -> bool;

    /// Returns true if this view is a child is an decedent of the parent
    fn is_child_of<T: Containable>(&self, parent: T) -> bool;

    /// Gets the active workspace of the view
    fn active_workspace<T: Containable>(&self) -> T;
}

struct Container {
    handle: Option<WlcOutput>,

    parent: Node,
    children: Vec<Rc<Node>>,
    type_: ContainerType,
    layout: Layout,

    width: u64,
    height: u64,

    x: i64,
    y: i64,

    visible: bool,
    is_focused: bool,
    is_floating: bool,
}

impl Containable for Container {

    /// Gets the parent that this container sits in.
    ///
    /// If the container is the root, it returns None
    fn get_parent(&self) -> Option<&Containable> {
        match self.type_ {
            ContainerType::Root => None,
            _ => Some(&*self.parent),
        }
    }
    /// Gets the children of this container.
    ///
    /// Views never have children
    fn get_children(&self) -> Option<Vec<Weak<Node>>> {
        if self.children.len() == 0 {
            None
        } else {
            Some(self.children.iter().map(|child| Rc::downgrade(&child)).collect())
        }
    }

    fn get_type(&self) -> ContainerType {
        self.type_
    }

    /// Returns true if this container is focused.
    fn is_focused(&self) -> bool {
        self.is_focused
    }

    /// Removes this container and all of its children
    fn remove_container(&self) -> Result<(), &'static str> {
        for child in self.get_children().expect("No children") {
            if let Some(child) = child.upgrade() {
                if let Ok(child) = Rc::try_unwrap(child) {
                    child.remove_container();
                    drop(child);
                }
            }
        }
        Ok(())
    }

    /// Sets this container (and everything in it) to given visibility
    fn set_visibility(&mut self, visibility: bool) {
        self.visible = visibility
    }

    /// Gets the X (width) and Y (height) dimensions of the container
    fn get_dimensions(&self) -> (u64, u64) {
        (self.width, self.height)
    }

    /// Gets the position of this container on the screen
    fn get_position(&self) -> (i64, i64) {
        (self.x, self.y)
    }

}

struct View {
    handle: Option<WlcView>,
    parent: Node,

    width: u64,
    height: u64,

    x: i64,
    y: i64,

    visible: bool,
    is_focused: bool,
    is_floating: bool,
}

impl Containable for View {
    /// Gets the parent that this container sits in.
    ///
    /// If the container is the root, it returns None
    fn get_parent(&self) -> Option<&Containable> {
        Some(&*self.parent)
    }

    /// Gets the children of this container.
    ///
    /// Views never have children
    fn get_children(&self) -> Option<Vec<Weak<Node>>> {
        None
    }

    /// Gets the type of the container
    fn get_type(&self) -> ContainerType {
        ContainerType::View
    }

    /// Returns true if this container is focused.
    fn is_focused(&self) -> bool {
        self.is_focused
    }

    /// Removes this container and all of its children
    fn remove_container(&self) -> Result<(), &'static str> {
        unimplemented!();
    }

    /// Sets this container (and everything in it) to given visibility
    fn set_visibility(&mut self, visibility: bool) {
        self.visible = visibility
    }

    /// Gets the X and Y dimensions of the container
    fn get_dimensions(&self) -> (u64, u64) {
        (self.width, self.height)
    }

    /// Gets the position of this container on the screen
    fn get_position(&self) -> (i64, i64) {
        (self.x, self.y)
    }
}
<|endoftext|>


<commit_before>extern crate rand;
use ::rand::Rng;

static mut ERROR: isize = 0;

struct File;

#[allow(unused_variables)]
fn read(f: &File, save_to: Vec<u8>) -> usize {
    if rand::thread_rng().gen_weighted_bool(3) {
        unsafe {
            ERROR = 1;
        }
    }
    0
}

#[allow(unused_mut)]
fn main() {
    let mut f = File;
    let mut buffer = vec![];

    read(&f, buffer);
    unsafe {
        if ERROR != 0 {
            panic!("An error has occurred!")
        }
    }
}
<commit_msg>using Result to return from functions that are susceptible to failure<commit_after>extern crate rand;
use ::rand::Rng;

fn one_in(n: u32) -> bool {
    rand::thread_rng().gen_weighted_bool(n)
}

#[derive(Debug)]
struct File {
    name: String,
    data: Vec<u8>,
}

impl File {
    fn new(name: &str) -> File {
        File { name: String::from(name), data: Vec::new() }
    }

    fn new_with_data(name: &str, data: &Vec<u8>) -> File {
        let mut f = File::new(name);
        f.data = data.clone();
        f
    }

    fn read(self: &File, save_to: &mut Vec<u8>) -> Result<usize, String> {
        let mut tmp = self.data.clone();
        let read_length = tmp.len();
        save_to.reserve(read_length);
        save_to.append(&mut tmp);
        Ok(read_length)
    }
}

fn  open(f: File) -> Result<File, String> {
    if one_in(10_000) {
        let err_msg = String::from("Permission denied");
        return Err(err_msg);
    }
    Ok(f)
}

fn close(f: File) -> Result<File, String> {
    if one_in(100_000) {
        let err_msg = String::from("Interrupted by signal!");
        return Err(err_msg);
    }
    Ok(f)
}

fn main() {
    let f4_data: Vec<u8> = vec![114, 117, 115, 116, 33];
    let mut f4 = File::new_with_data("4.txt", &f4_data);

    let mut buffer: Vec<u8> = vec![];

    f4 = open(f4).unwrap();
    let f4_length = f4.read(&mut buffer).unwrap();
    f4 = close(f4).unwrap();

    let text = String::from_utf8_lossy(&buffer);

    println!("{:?}", f4);
    println!("{} is {} bytes long", &f4.name, f4_length);
    println!("{}", text);
}
<|endoftext|>