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

#![comment = "Wrapper for libxml2's SAX parser."]
#![crate_id = "github.com/bjz/sax-rs#sax:0.1"]

#![crate_type = "lib"]

#![feature(globs)]

extern crate libc;
extern crate sync;

use libc::{c_char, c_int};
use std::mem;
use std::comm::{Receiver, channel};
use std::str;
use std::io::{File, IoResult};
use std::fmt;

use error::ErrorData;

pub mod error;
pub mod ffi;
mod extfn;

/// Events to be sent by the parser.
#[deriving(Eq, Clone)]
pub enum ParseEvent {
    /// The document has begun to be processed.
    StartDocument,
    /// The document processing has finished.
    EndDocument,
    /// An opening tag has was parsed.
    StartElement(StrBuf, Attributes),
    /// A closing tag was parsed.
    EndElement(StrBuf),
    /// Some characters between tags have been recived.
    Characters(StrBuf),
    /// A comment tag was parsed.
    Comment(StrBuf),
    /// A `CDATA` block was parsed.
    CdataBlock(StrBuf),
}

impl fmt::Show for ParseEvent {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            StartDocument => write!(fmt, "START DOCUMENT"),
            EndDocument => write!(fmt, "END DOCUMENT"),
            StartElement(ref name, ref atts) => write!(fmt, "<{}{}>", *name, atts),
            EndElement(ref name) => write!(fmt, "</{}>", *name),
            Characters(ref ch) => write!(fmt, "{}", ch.clone()),
            Comment(ref value) => write!(fmt, "", *value),
            CdataBlock(ref value) => write!(fmt, "<![CDATA[{}]]>", *value),
        }
    }
}

#[deriving(Eq, Clone)]
pub struct Attribute {
    name: StrBuf,
    value: StrBuf,
}

/// A list of attributes
#[deriving(Eq, Clone)]
pub struct Attributes(Vec<Attribute>);

impl Attributes {
    unsafe fn from_buf(atts: **ffi::xmlChar) -> Attributes {
        let mut ret = Vec::new();
        let mut ptr = atts as **c_char;
        while !ptr.is_null() && !(*ptr).is_null() {
            ret.push(
                Attribute {
                    name: str::raw::from_c_str(*ptr).to_strbuf(),
                    value: str::raw::from_c_str(*ptr.offset(1)).to_strbuf(),
                }
            );
            ptr = ptr.offset(2);
        }
        Attributes(ret)
    }

    pub fn find<'a>(&'a self, name: &str) -> Option<&'a str> {
        let Attributes(ref s) = *self;
        s.iter().find(|att| name == att.name.as_slice())
                .map(|att| att.value.as_slice())
    }

    pub fn get<'a>(&'a self, name: &str) -> &'a str {
        self.find(name).expect(format!("Could not find an attribute with the name \"{}\"", name))
    }

    pub fn find_clone(&self, name: &str) -> Option<StrBuf> {
        self.find(name).map(|v| v.to_strbuf())
    }

    pub fn get_clone(&self, name: &str) -> StrBuf {
        self.get(name).to_strbuf()
    }
}

impl fmt::Show for Attributes {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let Attributes(ref s) = *self;
        for att in s.iter() {
            try!(write!(fmt, " {}=\"{}\"", att.name, att.value));
        }
        Ok(())
    }
}

/// Either a parse event wrapped in `Ok` or some Error data wrapped in `Err`.
pub type ParseResult = Result<ParseEvent, ErrorData>;

/// Parses the entire XML string.
///
/// # Returns
///
/// A receiver that recieves parse results.
///
/// # Example
///
/// ~~~rust
/// let parser = sax::parse_str(XML_DATA);
/// for result in parser.iter() {
///     match result {
///         Ok(sax::StartDocument) => (),
///         Ok(sax::EndDocument) => break,
///         Ok(event) => println!("{}", event),
///         Err(err) => println!("{}", err),
///     }
/// }
/// ~~~
#[inline(never)]
pub fn parse_str(src: &str) -> Receiver<ParseResult> {
    // ensure that the xml library is ready for use
    use sync::one::{Once, ONCE_INIT};
    static mut INIT: Once = ONCE_INIT;
    unsafe {
        INIT.doit(|| {
            ffi::xmlInitParser();
            std::rt::at_exit(proc() ffi::xmlCleanupParser());
        })
    }

    let len = src.len() as c_int;
    src.to_c_str().with_ref(|c_str| {
        let (sender, receiver) = channel();
        unsafe {
            ffi::xmlSAXUserParseMemory(&extfn::new_handler(),
                                       mem::transmute(&sender),
                                       c_str, len);
        }
        receiver
    })
}

pub fn parse_file(path: &Path) -> IoResult<Receiver<ParseResult>> {
    File::open(path).and_then(|mut file| file.read_to_str())
                    .and_then(|contents| Ok(parse_str(contents)))
}

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

    fn get_mock_atts() -> Attributes {
        Attributes(Vec::from_slice([
            Attribute { name: box "foo", value: box "0" },
            Attribute { name: box "bar", value: box "1" },
            Attribute { name: box "baz", value: box "2" }
        ]))
    }

    #[test]
    fn test_att_get() {
        let atts = get_mock_atts();
        assert_eq!(atts.get("foo"), "0");
        assert_eq!(atts.get("bar"), "1");
        assert_eq!(atts.get("baz"), "2");
    }

    #[test]
    fn test_att_find() {
        let atts = get_mock_atts();
        assert_eq!(atts.find("foo"), Some("0"));
        assert_eq!(atts.find("bar"), Some("1"));
        assert_eq!(atts.find("baz"), Some("2"));
    }

    #[test]
    fn test() {
        let sax = parse_str(
            "<hello><this />test</hello>"
        );
        loop {
            match sax.recv() {
                Ok(StartDocument) => (),
                Ok(EndDocument) => break,
                Ok(event) => println!("{}", event.to_str()),
                Err(err) => println!("{}", err.to_str()),
            }
        }
    }
}
<commit_msg>Updated to latest Rust<commit_after>// Copyright 2013 The SAX-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![comment = "Wrapper for libxml2's SAX parser."]
#![crate_id = "github.com/bjz/sax-rs#sax:0.1"]

#![crate_type = "lib"]

#![feature(globs)]

extern crate libc;
extern crate sync;

use libc::{c_char, c_int};
use std::mem;
use std::comm::{Receiver, channel};
use std::str;
use std::io::{File, IoResult};
use std::fmt;

use error::ErrorData;

pub mod error;
pub mod ffi;
mod extfn;

/// Events to be sent by the parser.
#[deriving(Eq, Clone)]
pub enum ParseEvent {
    /// The document has begun to be processed.
    StartDocument,
    /// The document processing has finished.
    EndDocument,
    /// An opening tag has was parsed.
    StartElement(StrBuf, Attributes),
    /// A closing tag was parsed.
    EndElement(StrBuf),
    /// Some characters between tags have been recived.
    Characters(StrBuf),
    /// A comment tag was parsed.
    Comment(StrBuf),
    /// A `CDATA` block was parsed.
    CdataBlock(StrBuf),
}

impl fmt::Show for ParseEvent {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            StartDocument => write!(fmt, "START DOCUMENT"),
            EndDocument => write!(fmt, "END DOCUMENT"),
            StartElement(ref name, ref atts) => write!(fmt, "<{}{}>", *name, atts),
            EndElement(ref name) => write!(fmt, "</{}>", *name),
            Characters(ref ch) => write!(fmt, "{}", ch.clone()),
            Comment(ref value) => write!(fmt, "", *value),
            CdataBlock(ref value) => write!(fmt, "<![CDATA[{}]]>", *value),
        }
    }
}

#[deriving(Eq, Clone)]
pub struct Attribute {
    name: StrBuf,
    value: StrBuf,
}

/// A list of attributes
#[deriving(Eq, Clone)]
pub struct Attributes(Vec<Attribute>);

impl Attributes {
    unsafe fn from_buf(atts: **ffi::xmlChar) -> Attributes {
        let mut ret = Vec::new();
        let mut ptr = atts as **c_char;
        while !ptr.is_null() && !(*ptr).is_null() {
            ret.push(
                Attribute {
                    name: str::raw::from_c_str(*ptr).to_strbuf(),
                    value: str::raw::from_c_str(*ptr.offset(1)).to_strbuf(),
                }
            );
            ptr = ptr.offset(2);
        }
        Attributes(ret)
    }

    pub fn find<'a>(&'a self, name: &str) -> Option<&'a str> {
        let Attributes(ref s) = *self;
        s.iter().find(|att| name == att.name.as_slice())
                .map(|att| att.value.as_slice())
    }

    pub fn get<'a>(&'a self, name: &str) -> &'a str {
        self.find(name).expect(format!("Could not find an attribute with the name \"{}\"", name))
    }

    pub fn find_clone(&self, name: &str) -> Option<StrBuf> {
        self.find(name).map(|v| v.to_strbuf())
    }

    pub fn get_clone(&self, name: &str) -> StrBuf {
        self.get(name).to_strbuf()
    }
}

impl fmt::Show for Attributes {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let Attributes(ref s) = *self;
        for att in s.iter() {
            try!(write!(fmt, " {}=\"{}\"", att.name, att.value));
        }
        Ok(())
    }
}

/// Either a parse event wrapped in `Ok` or some Error data wrapped in `Err`.
pub type ParseResult = Result<ParseEvent, ErrorData>;

/// Parses the entire XML string.
///
/// # Returns
///
/// A receiver that recieves parse results.
///
/// # Example
///
/// ~~~rust
/// let parser = sax::parse_str(XML_DATA);
/// for result in parser.iter() {
///     match result {
///         Ok(sax::StartDocument) => (),
///         Ok(sax::EndDocument) => break,
///         Ok(event) => println!("{}", event),
///         Err(err) => println!("{}", err),
///     }
/// }
/// ~~~
#[inline(never)]
pub fn parse_str(src: &str) -> Receiver<ParseResult> {
    // ensure that the xml library is ready for use
    use sync::one::{Once, ONCE_INIT};
    static mut INIT: Once = ONCE_INIT;
    unsafe {
        INIT.doit(|| {
            ffi::xmlInitParser();
            std::rt::at_exit(proc() ffi::xmlCleanupParser());
        })
    }

    let len = src.len() as c_int;
    src.to_c_str().with_ref(|c_str| {
        let (sender, receiver) = channel();
        unsafe {
            ffi::xmlSAXUserParseMemory(&extfn::new_handler(),
                                       mem::transmute(&sender),
                                       c_str, len);
        }
        receiver
    })
}

pub fn parse_file(path: &Path) -> IoResult<Receiver<ParseResult>> {
    File::open(path).and_then(|mut file| file.read_to_str())
                    .and_then(|contents| Ok(parse_str(contents.as_slice())))
}

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

    fn get_mock_atts() -> Attributes {
        Attributes(Vec::from_slice([
            Attribute { name: box "foo", value: box "0" },
            Attribute { name: box "bar", value: box "1" },
            Attribute { name: box "baz", value: box "2" }
        ]))
    }

    #[test]
    fn test_att_get() {
        let atts = get_mock_atts();
        assert_eq!(atts.get("foo"), "0");
        assert_eq!(atts.get("bar"), "1");
        assert_eq!(atts.get("baz"), "2");
    }

    #[test]
    fn test_att_find() {
        let atts = get_mock_atts();
        assert_eq!(atts.find("foo"), Some("0"));
        assert_eq!(atts.find("bar"), Some("1"));
        assert_eq!(atts.find("baz"), Some("2"));
    }

    #[test]
    fn test() {
        let sax = parse_str(
            "<hello><this />test</hello>"
        );
        loop {
            match sax.recv() {
                Ok(StartDocument) => (),
                Ok(EndDocument) => break,
                Ok(event) => println!("{}", event.to_str()),
                Err(err) => println!("{}", err.to_str()),
            }
        }
    }
}
<|endoftext|>


<commit_before>#[link(name = "sdl",
       vers = "0.3.0",
       uuid = "0ce89b41-2f92-459e-bbc1-8f5fe32f16cf",
       url = "http://github.com/brson/rust-sdl")];

#[comment = "SDL bindings"];
#[license = "MIT"];
#[crate_type = "lib"];

#[feature(globs)];
#[feature(link_args)];

pub use sdl::*;

pub mod audio;
pub mod cd;
pub mod event;
pub mod joy;
pub mod mouse;
pub mod video;
pub mod gl;
pub mod wm;

#[cfg(image)]
pub mod img;

#[cfg(mixer)]
pub mod mixer;

pub mod sdl;

<commit_msg>Changed link to crate_id<commit_after>#[crate_id="sdl#0.3.1"];
#[comment = "SDL bindings"];
#[license = "MIT"];
#[crate_type = "lib"];

#[feature(globs)];
#[feature(link_args)];

pub use sdl::*;

pub mod audio;
pub mod cd;
pub mod event;
pub mod joy;
pub mod mouse;
pub mod video;
pub mod gl;
pub mod wm;

#[cfg(image)]
pub mod img;

#[cfg(mixer)]
pub mod mixer;

pub mod sdl;

<|endoftext|>


<commit_before><commit_msg>Allow passing additional arguments to the Clang executable (#57)<commit_after><|endoftext|>


<commit_before><commit_msg>Impl write/read byte in VRAM<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::error;
use std::fmt;
use std::mem;
use std::ptr;
use std::sync::Arc;
use smallvec::SmallVec;

use check_errors;
use Error;
use OomError;
use VulkanObject;
use VulkanPointers;
use vk;

use descriptor::descriptor::ShaderStages;
use descriptor::descriptor_set::UnsafeDescriptorSetLayout;
use descriptor::pipeline_layout::PipelineLayoutDesc;
use descriptor::pipeline_layout::PipelineLayoutDescNames;
use descriptor::pipeline_layout::PipelineLayoutDescPcRange;
use descriptor::pipeline_layout::PipelineLayoutRef;
use device::Device;

/// Wrapper around the `PipelineLayout` Vulkan object. Describes to the Vulkan implementation the
/// descriptor sets and push constants available to your shaders
pub struct PipelineLayout<L = Box<PipelineLayoutDescNames + Send + Sync>> {
    device: Arc<Device>,
    layout: vk::PipelineLayout,
    layouts: SmallVec<[Arc<UnsafeDescriptorSetLayout>; 16]>,
    desc: L,
}

impl<L> PipelineLayout<L> where L: PipelineLayoutDesc {
    /// Creates a new `PipelineLayout`.
    ///
    /// # Panic
    ///
    /// - Panics if one of the layout returned by `provided_set_layout()` belongs to a different
    ///   device than the one passed as parameter.
    #[inline]
    pub fn new(device: &Arc<Device>, desc: L)
               -> Result<PipelineLayout<L>, PipelineLayoutCreationError>
    {
        let vk = device.pointers();
        let limits = device.physical_device().limits();

        // Building the list of `UnsafeDescriptorSetLayout` objects.
        let layouts = {
            let mut layouts: SmallVec<[_; 16]> = SmallVec::new();
            for num in 0 .. desc.num_sets() {
                layouts.push(match desc.provided_set_layout(num) {
                    Some(l) => {
                        assert_eq!(&**l.device() as *const Device, &**device as *const Device);
                        l
                    },
                    None => {
                        let sets_iter = 0 .. desc.num_bindings_in_set(num).unwrap_or(0);
                        let desc_iter = sets_iter.map(|d| desc.descriptor(num, d));
                        Arc::new(try!(UnsafeDescriptorSetLayout::raw(device.clone(), desc_iter)))
                    },
                });
            }
            layouts
        };

        // Grab the list of `vkDescriptorSetLayout` objects from `layouts`.
        let layouts_ids = layouts.iter().map(|l| {
            l.internal_object()
        }).collect::<SmallVec<[_; 16]>>();

        // FIXME: must also check per-descriptor-type limits (eg. max uniform buffer descriptors)

        if layouts_ids.len() > limits.max_bound_descriptor_sets() as usize {
            return Err(PipelineLayoutCreationError::MaxDescriptorSetsLimitExceeded);
        }

        // Builds a list of `vkPushConstantRange` that describe the push constants.
        let push_constants = {
            let mut out: SmallVec<[_; 8]> = SmallVec::new();

            for pc_id in 0 .. desc.num_push_constants_ranges() {
                let PipelineLayoutDescPcRange { offset, size, stages } = {
                    match desc.push_constants_range(pc_id) {
                        Some(o) => o,
                        None => continue,
                    }
                };

                if stages == ShaderStages::none() || size == 0 || (size % 4) != 0 {
                    return Err(PipelineLayoutCreationError::InvalidPushConstant);
                }

                if offset + size > limits.max_push_constants_size() as usize {
                    return Err(PipelineLayoutCreationError::MaxPushConstantsSizeExceeded);
                }

                out.push(vk::PushConstantRange {
                    stageFlags: stages.into(),
                    offset: offset as u32,
                    size: size as u32,
                });
            }

            out
        };

        // FIXME: validity: > Any two elements of pPushConstantRanges must not include the same stage in stageFlags
        // I don't even know what that means

        // Build the final object.
        let layout = unsafe {
            let infos = vk::PipelineLayoutCreateInfo {
                sType: vk::STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
                pNext: ptr::null(),
                flags: 0,   // reserved
                setLayoutCount: layouts_ids.len() as u32,
                pSetLayouts: layouts_ids.as_ptr(),
                pushConstantRangeCount: push_constants.len() as u32,
                pPushConstantRanges: push_constants.as_ptr(),
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreatePipelineLayout(device.internal_object(), &infos,
                                                      ptr::null(), &mut output)));
            output
        };

        Ok(PipelineLayout {
            device: device.clone(),
            layout: layout,
            layouts: layouts,
            desc: desc,
        })
    }
}

impl<L> PipelineLayout<L> where L: PipelineLayoutDesc {
    /// Returns the description of the pipeline layout.
    #[inline]
    pub fn desc(&self) -> &L {
        &self.desc
    }
}

unsafe impl<D> PipelineLayoutRef for PipelineLayout<D> where D: PipelineLayoutDescNames {
    #[inline]
    fn sys(&self) -> PipelineLayoutSys {
        PipelineLayoutSys(&self.layout)
    }

    #[inline]
    fn desc(&self) -> &PipelineLayoutDescNames {
        &self.desc
    }

    #[inline]
    fn device(&self) -> &Arc<Device> {
        &self.device
    }

    #[inline]
    fn descriptor_set_layout(&self, index: usize) -> Option<&Arc<UnsafeDescriptorSetLayout>> {
        self.layouts.get(index)
    }
}

impl<L> Drop for PipelineLayout<L> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.device.pointers();
            vk.DestroyPipelineLayout(self.device.internal_object(), self.layout, ptr::null());
        }
    }
}

/// Opaque object that is borrowed from a `PipelineLayout`.
///
/// This object exists so that we can pass it around without having to be generic over the template
/// parameter of the `PipelineLayout`.
#[derive(Copy, Clone)]
pub struct PipelineLayoutSys<'a>(&'a vk::PipelineLayout);

unsafe impl<'a> VulkanObject for PipelineLayoutSys<'a> {
    type Object = vk::PipelineLayout;

    #[inline]
    fn internal_object(&self) -> vk::PipelineLayout {
        *self.0
    }
}

/// Error that can happen when creating an instance.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum PipelineLayoutCreationError {
    /// Not enough memory.
    OomError(OomError),
    /// The maximum number of descriptor sets has been exceeded.
    MaxDescriptorSetsLimitExceeded,
    /// The maximum size of push constants has been exceeded.
    MaxPushConstantsSizeExceeded,
    /// One of the push constants range didn't obey the rules. The list of stages must not be
    /// empty, the size must not be 0, and the size must be a multiple or 4.
    InvalidPushConstant,
}

impl error::Error for PipelineLayoutCreationError {
    #[inline]
    fn description(&self) -> &str {
        match *self {
            PipelineLayoutCreationError::OomError(_) => {
                "not enough memory available"
            },
            PipelineLayoutCreationError::MaxDescriptorSetsLimitExceeded => {
                "the maximum number of descriptor sets has been exceeded"
            },
            PipelineLayoutCreationError::MaxPushConstantsSizeExceeded => {
                "the maximum size of push constants has been exceeded"
            },
            PipelineLayoutCreationError::InvalidPushConstant => {
                "one of the push constants range didn't obey the rules"
            },
        }
    }

    #[inline]
    fn cause(&self) -> Option<&error::Error> {
        match *self {
            PipelineLayoutCreationError::OomError(ref err) => Some(err),
            _ => None
        }
    }
}

impl fmt::Display for PipelineLayoutCreationError {
    #[inline]
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(fmt, "{}", error::Error::description(self))
    }
}

impl From<OomError> for PipelineLayoutCreationError {
    #[inline]
    fn from(err: OomError) -> PipelineLayoutCreationError {
        PipelineLayoutCreationError::OomError(err)
    }
}

impl From<Error> for PipelineLayoutCreationError {
    #[inline]
    fn from(err: Error) -> PipelineLayoutCreationError {
        match err {
            err @ Error::OutOfHostMemory => {
                PipelineLayoutCreationError::OomError(OomError::from(err))
            },
            err @ Error::OutOfDeviceMemory => {
                PipelineLayoutCreationError::OomError(OomError::from(err))
            },
            _ => panic!("unexpected error: {:?}", err)
        }
    }
}

#[cfg(test)]
mod tests {
    use std::iter;
    use std::sync::Arc;
    use descriptor::descriptor::ShaderStages;
    use descriptor::descriptor_set::UnsafeDescriptorSetLayout;
    use descriptor::pipeline_layout::sys::PipelineLayout;
    use descriptor::pipeline_layout::sys::PipelineLayoutCreationError;

    #[test]
    fn empty() {
        let (device, _) = gfx_dev_and_queue!();
        let _layout = PipelineLayout::new(&device, iter::empty(), iter::empty()).unwrap();
    }

    #[test]
    #[should_panic]
    fn wrong_device_panic() {
        let (device1, _) = gfx_dev_and_queue!();
        let (device2, _) = gfx_dev_and_queue!();

        let set = match UnsafeDescriptorSetLayout::raw(device1, iter::empty()) {
            Ok(s) => Arc::new(s),
            Err(_) => return
        };

        let _ = PipelineLayout::new(&device2, Some(&set), iter::empty());
    }

    #[test]
    fn invalid_push_constant_stages() {
        let (device, _) = gfx_dev_and_queue!();

        let push_constant = (0, 8, ShaderStages::none());

        match PipelineLayout::new(&device, iter::empty(), Some(push_constant)) {
            Err(PipelineLayoutCreationError::InvalidPushConstant) => (),
            _ => panic!()
        }
    }

    #[test]
    fn invalid_push_constant_size1() {
        let (device, _) = gfx_dev_and_queue!();

        let push_constant = (0, 0, ShaderStages::all_graphics());

        match PipelineLayout::new(&device, iter::empty(), Some(push_constant)) {
            Err(PipelineLayoutCreationError::InvalidPushConstant) => (),
            _ => panic!()
        }
    }

    #[test]
    fn invalid_push_constant_size2() {
        let (device, _) = gfx_dev_and_queue!();

        let push_constant = (0, 11, ShaderStages::all_graphics());

        match PipelineLayout::new(&device, iter::empty(), Some(push_constant)) {
            Err(PipelineLayoutCreationError::InvalidPushConstant) => (),
            _ => panic!()
        }
    }
}
<commit_msg>Compare internal device objects instead of pointers<commit_after>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::error;
use std::fmt;
use std::mem;
use std::ptr;
use std::sync::Arc;
use smallvec::SmallVec;

use check_errors;
use Error;
use OomError;
use VulkanObject;
use VulkanPointers;
use vk;

use descriptor::descriptor::ShaderStages;
use descriptor::descriptor_set::UnsafeDescriptorSetLayout;
use descriptor::pipeline_layout::PipelineLayoutDesc;
use descriptor::pipeline_layout::PipelineLayoutDescNames;
use descriptor::pipeline_layout::PipelineLayoutDescPcRange;
use descriptor::pipeline_layout::PipelineLayoutRef;
use device::Device;

/// Wrapper around the `PipelineLayout` Vulkan object. Describes to the Vulkan implementation the
/// descriptor sets and push constants available to your shaders
pub struct PipelineLayout<L = Box<PipelineLayoutDescNames + Send + Sync>> {
    device: Arc<Device>,
    layout: vk::PipelineLayout,
    layouts: SmallVec<[Arc<UnsafeDescriptorSetLayout>; 16]>,
    desc: L,
}

impl<L> PipelineLayout<L> where L: PipelineLayoutDesc {
    /// Creates a new `PipelineLayout`.
    ///
    /// # Panic
    ///
    /// - Panics if one of the layout returned by `provided_set_layout()` belongs to a different
    ///   device than the one passed as parameter.
    #[inline]
    pub fn new(device: &Arc<Device>, desc: L)
               -> Result<PipelineLayout<L>, PipelineLayoutCreationError>
    {
        let vk = device.pointers();
        let limits = device.physical_device().limits();

        // Building the list of `UnsafeDescriptorSetLayout` objects.
        let layouts = {
            let mut layouts: SmallVec<[_; 16]> = SmallVec::new();
            for num in 0 .. desc.num_sets() {
                layouts.push(match desc.provided_set_layout(num) {
                    Some(l) => {
                        assert_eq!(l.device().internal_object(), device.internal_object());
                        l
                    },
                    None => {
                        let sets_iter = 0 .. desc.num_bindings_in_set(num).unwrap_or(0);
                        let desc_iter = sets_iter.map(|d| desc.descriptor(num, d));
                        Arc::new(try!(UnsafeDescriptorSetLayout::raw(device.clone(), desc_iter)))
                    },
                });
            }
            layouts
        };

        // Grab the list of `vkDescriptorSetLayout` objects from `layouts`.
        let layouts_ids = layouts.iter().map(|l| {
            l.internal_object()
        }).collect::<SmallVec<[_; 16]>>();

        // FIXME: must also check per-descriptor-type limits (eg. max uniform buffer descriptors)

        if layouts_ids.len() > limits.max_bound_descriptor_sets() as usize {
            return Err(PipelineLayoutCreationError::MaxDescriptorSetsLimitExceeded);
        }

        // Builds a list of `vkPushConstantRange` that describe the push constants.
        let push_constants = {
            let mut out: SmallVec<[_; 8]> = SmallVec::new();

            for pc_id in 0 .. desc.num_push_constants_ranges() {
                let PipelineLayoutDescPcRange { offset, size, stages } = {
                    match desc.push_constants_range(pc_id) {
                        Some(o) => o,
                        None => continue,
                    }
                };

                if stages == ShaderStages::none() || size == 0 || (size % 4) != 0 {
                    return Err(PipelineLayoutCreationError::InvalidPushConstant);
                }

                if offset + size > limits.max_push_constants_size() as usize {
                    return Err(PipelineLayoutCreationError::MaxPushConstantsSizeExceeded);
                }

                out.push(vk::PushConstantRange {
                    stageFlags: stages.into(),
                    offset: offset as u32,
                    size: size as u32,
                });
            }

            out
        };

        // FIXME: validity: > Any two elements of pPushConstantRanges must not include the same stage in stageFlags
        // I don't even know what that means

        // Build the final object.
        let layout = unsafe {
            let infos = vk::PipelineLayoutCreateInfo {
                sType: vk::STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
                pNext: ptr::null(),
                flags: 0,   // reserved
                setLayoutCount: layouts_ids.len() as u32,
                pSetLayouts: layouts_ids.as_ptr(),
                pushConstantRangeCount: push_constants.len() as u32,
                pPushConstantRanges: push_constants.as_ptr(),
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreatePipelineLayout(device.internal_object(), &infos,
                                                      ptr::null(), &mut output)));
            output
        };

        Ok(PipelineLayout {
            device: device.clone(),
            layout: layout,
            layouts: layouts,
            desc: desc,
        })
    }
}

impl<L> PipelineLayout<L> where L: PipelineLayoutDesc {
    /// Returns the description of the pipeline layout.
    #[inline]
    pub fn desc(&self) -> &L {
        &self.desc
    }
}

unsafe impl<D> PipelineLayoutRef for PipelineLayout<D> where D: PipelineLayoutDescNames {
    #[inline]
    fn sys(&self) -> PipelineLayoutSys {
        PipelineLayoutSys(&self.layout)
    }

    #[inline]
    fn desc(&self) -> &PipelineLayoutDescNames {
        &self.desc
    }

    #[inline]
    fn device(&self) -> &Arc<Device> {
        &self.device
    }

    #[inline]
    fn descriptor_set_layout(&self, index: usize) -> Option<&Arc<UnsafeDescriptorSetLayout>> {
        self.layouts.get(index)
    }
}

impl<L> Drop for PipelineLayout<L> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.device.pointers();
            vk.DestroyPipelineLayout(self.device.internal_object(), self.layout, ptr::null());
        }
    }
}

/// Opaque object that is borrowed from a `PipelineLayout`.
///
/// This object exists so that we can pass it around without having to be generic over the template
/// parameter of the `PipelineLayout`.
#[derive(Copy, Clone)]
pub struct PipelineLayoutSys<'a>(&'a vk::PipelineLayout);

unsafe impl<'a> VulkanObject for PipelineLayoutSys<'a> {
    type Object = vk::PipelineLayout;

    #[inline]
    fn internal_object(&self) -> vk::PipelineLayout {
        *self.0
    }
}

/// Error that can happen when creating an instance.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum PipelineLayoutCreationError {
    /// Not enough memory.
    OomError(OomError),
    /// The maximum number of descriptor sets has been exceeded.
    MaxDescriptorSetsLimitExceeded,
    /// The maximum size of push constants has been exceeded.
    MaxPushConstantsSizeExceeded,
    /// One of the push constants range didn't obey the rules. The list of stages must not be
    /// empty, the size must not be 0, and the size must be a multiple or 4.
    InvalidPushConstant,
}

impl error::Error for PipelineLayoutCreationError {
    #[inline]
    fn description(&self) -> &str {
        match *self {
            PipelineLayoutCreationError::OomError(_) => {
                "not enough memory available"
            },
            PipelineLayoutCreationError::MaxDescriptorSetsLimitExceeded => {
                "the maximum number of descriptor sets has been exceeded"
            },
            PipelineLayoutCreationError::MaxPushConstantsSizeExceeded => {
                "the maximum size of push constants has been exceeded"
            },
            PipelineLayoutCreationError::InvalidPushConstant => {
                "one of the push constants range didn't obey the rules"
            },
        }
    }

    #[inline]
    fn cause(&self) -> Option<&error::Error> {
        match *self {
            PipelineLayoutCreationError::OomError(ref err) => Some(err),
            _ => None
        }
    }
}

impl fmt::Display for PipelineLayoutCreationError {
    #[inline]
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(fmt, "{}", error::Error::description(self))
    }
}

impl From<OomError> for PipelineLayoutCreationError {
    #[inline]
    fn from(err: OomError) -> PipelineLayoutCreationError {
        PipelineLayoutCreationError::OomError(err)
    }
}

impl From<Error> for PipelineLayoutCreationError {
    #[inline]
    fn from(err: Error) -> PipelineLayoutCreationError {
        match err {
            err @ Error::OutOfHostMemory => {
                PipelineLayoutCreationError::OomError(OomError::from(err))
            },
            err @ Error::OutOfDeviceMemory => {
                PipelineLayoutCreationError::OomError(OomError::from(err))
            },
            _ => panic!("unexpected error: {:?}", err)
        }
    }
}

#[cfg(test)]
mod tests {
    use std::iter;
    use std::sync::Arc;
    use descriptor::descriptor::ShaderStages;
    use descriptor::descriptor_set::UnsafeDescriptorSetLayout;
    use descriptor::pipeline_layout::sys::PipelineLayout;
    use descriptor::pipeline_layout::sys::PipelineLayoutCreationError;

    #[test]
    fn empty() {
        let (device, _) = gfx_dev_and_queue!();
        let _layout = PipelineLayout::new(&device, iter::empty(), iter::empty()).unwrap();
    }

    #[test]
    #[should_panic]
    fn wrong_device_panic() {
        let (device1, _) = gfx_dev_and_queue!();
        let (device2, _) = gfx_dev_and_queue!();

        let set = match UnsafeDescriptorSetLayout::raw(device1, iter::empty()) {
            Ok(s) => Arc::new(s),
            Err(_) => return
        };

        let _ = PipelineLayout::new(&device2, Some(&set), iter::empty());
    }

    #[test]
    fn invalid_push_constant_stages() {
        let (device, _) = gfx_dev_and_queue!();

        let push_constant = (0, 8, ShaderStages::none());

        match PipelineLayout::new(&device, iter::empty(), Some(push_constant)) {
            Err(PipelineLayoutCreationError::InvalidPushConstant) => (),
            _ => panic!()
        }
    }

    #[test]
    fn invalid_push_constant_size1() {
        let (device, _) = gfx_dev_and_queue!();

        let push_constant = (0, 0, ShaderStages::all_graphics());

        match PipelineLayout::new(&device, iter::empty(), Some(push_constant)) {
            Err(PipelineLayoutCreationError::InvalidPushConstant) => (),
            _ => panic!()
        }
    }

    #[test]
    fn invalid_push_constant_size2() {
        let (device, _) = gfx_dev_and_queue!();

        let push_constant = (0, 11, ShaderStages::all_graphics());

        match PipelineLayout::new(&device, iter::empty(), Some(push_constant)) {
            Err(PipelineLayoutCreationError::InvalidPushConstant) => (),
            _ => panic!()
        }
    }
}
<|endoftext|>


<commit_before>extern crate anagram;

#[test]
fn test_no_matches() {
    let inputs = ["hello", "world", "zombies", "pants"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("diaper", &inputs), outputs);
}

#[test]
#[ignore]
fn test_detect_simple_anagram() {
    let inputs = ["tan", "stand", "at"];
    let outputs: Vec<&str> = vec!["tan"];
    assert_eq!(anagram::anagrams_for("ant", &inputs), outputs);
}

#[test]
#[ignore]
fn test_does_not_confuse_different_duplicates() {
    let inputs = ["eagle"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("galea", &inputs), outputs);
}

#[test]
#[ignore]
fn test_eliminate_anagram_subsets() {
    let inputs = ["dog", "goody"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("good", &inputs), outputs);
}

#[test]
#[ignore]
fn test_detect_anagram() {
    let inputs = ["enlists", "google", "inlets", "banana"];
    let outputs: Vec<&str> = vec!["inlets"];
    assert_eq!(anagram::anagrams_for("listen", &inputs), outputs);
}

#[test]
#[ignore]
fn test_multiple_anagrams() {
    let inputs = ["gallery", "ballerina", "regally", "clergy", "largely", "leading"];
    let mut outputs: Vec<&str> = vec!["gallery", "regally", "largely"];
    outputs.sort();
    let mut result = anagram::anagrams_for("allergy", &inputs);
    result.sort();
    assert_eq!(result, outputs);
}

#[test]
#[ignore]
fn test_case_insensitive_anagrams() {
    let inputs = ["cashregister", "Carthorse", "radishes"];
    let outputs: Vec<&str> = vec!["Carthorse"];
    assert_eq!(anagram::anagrams_for("Orchestra", &inputs), outputs);
}

#[test]
#[ignore]
fn test_unicode_anagrams() {
    // These words don't make sense, they're just greek letters cobbled together.
    let inputs = ["ΒΓΑ", "ΒΓΔ", "γβα"];
    let outputs: Vec<&str> = vec!["ΒΓΑ", "γβα"];
    assert_eq!(anagram::anagrams_for("ΑΒΓ", &inputs), outputs);
}

#[test]
#[ignore]
fn test_misleading_unicode_anagrams() {
    // Despite what a human might think these words different letters, the input uses Greek A and B
    // while the list of potential anagrams uses Latin A and B.
    let inputs = ["ABΓ"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("ΑΒΓ", &inputs), outputs);
}

#[test]
#[ignore]
fn test_does_not_detect_a_word_as_its_own_anagram() {
    let inputs = ["banana"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("banana", &inputs), outputs);
}

#[test]
#[ignore]
fn test_does_not_detect_a_differently_cased_word_as_its_own_anagram() {
    let inputs = ["bAnana"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("banana", &inputs), outputs);
}
<commit_msg>Detect false positive from `eq_ignore_ascii_case`<commit_after>extern crate anagram;

#[test]
fn test_no_matches() {
    let inputs = ["hello", "world", "zombies", "pants"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("diaper", &inputs), outputs);
}

#[test]
#[ignore]
fn test_detect_simple_anagram() {
    let inputs = ["tan", "stand", "at"];
    let outputs: Vec<&str> = vec!["tan"];
    assert_eq!(anagram::anagrams_for("ant", &inputs), outputs);
}

#[test]
#[ignore]
fn test_does_not_confuse_different_duplicates() {
    let inputs = ["eagle"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("galea", &inputs), outputs);
}

#[test]
#[ignore]
fn test_eliminate_anagram_subsets() {
    let inputs = ["dog", "goody"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("good", &inputs), outputs);
}

#[test]
#[ignore]
fn test_detect_anagram() {
    let inputs = ["enlists", "google", "inlets", "banana"];
    let outputs: Vec<&str> = vec!["inlets"];
    assert_eq!(anagram::anagrams_for("listen", &inputs), outputs);
}

#[test]
#[ignore]
fn test_multiple_anagrams() {
    let inputs = ["gallery", "ballerina", "regally", "clergy", "largely", "leading"];
    let mut outputs: Vec<&str> = vec!["gallery", "regally", "largely"];
    outputs.sort();
    let mut result = anagram::anagrams_for("allergy", &inputs);
    result.sort();
    assert_eq!(result, outputs);
}

#[test]
#[ignore]
fn test_case_insensitive_anagrams() {
    let inputs = ["cashregister", "Carthorse", "radishes"];
    let outputs: Vec<&str> = vec!["Carthorse"];
    assert_eq!(anagram::anagrams_for("Orchestra", &inputs), outputs);
}

#[test]
#[ignore]
fn test_unicode_anagrams() {
    // These words don't make sense, they're just greek letters cobbled together.
    let inputs = ["ΒΓΑ", "ΒΓΔ", "γβα"];
    let outputs: Vec<&str> = vec!["ΒΓΑ", "γβα"];
    assert_eq!(anagram::anagrams_for("ΑΒΓ", &inputs), outputs);
}

#[test]
#[ignore]
fn test_misleading_unicode_anagrams() {
    // Despite what a human might think these words different letters, the input uses Greek A and B
    // while the list of potential anagrams uses Latin A and B.
    let inputs = ["ABΓ"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("ΑΒΓ", &inputs), outputs);
}

#[test]
#[ignore]
fn test_does_not_detect_a_word_as_its_own_anagram() {
    let inputs = ["banana"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("banana", &inputs), outputs);
}

#[test]
#[ignore]
fn test_does_not_detect_a_differently_cased_word_as_its_own_anagram() {
    let inputs = ["bAnana"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("banana", &inputs), outputs);
}

#[test]
#[ignore]
fn test_does_not_detect_a_differently_cased_unicode_word_as_its_own_anagram() {
    let inputs = ["ΑΒγ"];
    let outputs: Vec<&str> = vec![];
    assert_eq!(anagram::anagrams_for("ΑΒΓ", &inputs), outputs);
}
<|endoftext|>


<commit_before>#![crate_type = "lib"]
#![feature(unsafe_destructor)]

use std::sync::atomics::{AtomicBool, SeqCst};
use std::ty::Unsafe;
use std::rt::local::Local;
use std::rt::task::Task;

pub struct SpinLock<T>
{
    lock: AtomicBool,
    data: Unsafe<T>,
}

pub struct SpinLockGuard<'a, T>
{
    lock: &'a AtomicBool,
    data: &'a mut T,
}

impl<T: Send> SpinLock<T>
{
    pub fn new(user_data: T) -> SpinLock<T>
    {
        SpinLock
        {
            lock: AtomicBool::new(false),
            data: Unsafe::new(user_data),
        }
    }

    fn _lock(&self)
    {
        while self.lock.swap(true, SeqCst) == true
        {
            if Local::exists(None::<Task>)
            {
                std::task::deschedule();
            }
        }
    }

    pub fn lock<'a>(&'a self) -> SpinLockGuard<'a, T>
    {
        self._lock();
        SpinLockGuard
        {
            lock: &self.lock,
            data: unsafe { &mut *self.data.get() },
        }
    }
}

impl<'a, T: Send> Deref<T> for SpinLockGuard<'a, T>
{
    fn deref<'a>(&'a self) -> &'a T { &*self.data }
}

impl<'a, T: Send> DerefMut<T> for SpinLockGuard<'a, T>
{
    fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self.data }
}

#[unsafe_destructor]
impl<'a, T: Send> Drop for SpinLockGuard<'a, T>
{
    fn drop(&mut self)
    {
        self.lock.store(false, SeqCst);
    }
}
<commit_msg>Renamed SpinLock to Spinlock<commit_after>#![crate_type = "lib"]
#![feature(unsafe_destructor)]

use std::sync::atomics::{AtomicBool, SeqCst};
use std::ty::Unsafe;
use std::rt::local::Local;
use std::rt::task::Task;

pub struct Spinlock<T>
{
    lock: AtomicBool,
    data: Unsafe<T>,
}

pub struct SpinlockGuard<'a, T>
{
    lock: &'a AtomicBool,
    data: &'a mut T,
}

impl<T: Send> Spinlock<T>
{
    pub fn new(user_data: T) -> Spinlock<T>
    {
        Spinlock
        {
            lock: AtomicBool::new(false),
            data: Unsafe::new(user_data),
        }
    }

    fn _lock(&self)
    {
        while self.lock.swap(true, SeqCst) == true
        {
            if Local::exists(None::<Task>)
            {
                std::task::deschedule();
            }
        }
    }

    pub fn lock<'a>(&'a self) -> SpinlockGuard<'a, T>
    {
        self._lock();
        SpinlockGuard
        {
            lock: &self.lock,
            data: unsafe { &mut *self.data.get() },
        }
    }
}

impl<'a, T: Send> Deref<T> for SpinlockGuard<'a, T>
{
    fn deref<'a>(&'a self) -> &'a T { &*self.data }
}

impl<'a, T: Send> DerefMut<T> for SpinlockGuard<'a, T>
{
    fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self.data }
}

#[unsafe_destructor]
impl<'a, T: Send> Drop for SpinlockGuard<'a, T>
{
    fn drop(&mut self)
    {
        self.lock.store(false, SeqCst);
    }
}
<|endoftext|>


<commit_before>/* Copyright (C)  2016 nokaa <nokaa@cock.li>
 * This software is licensed under the terms of the
 * GNU Affero General Public License. You should have
 * received a copy of this license with this software.
 * The license may also be found at https://gnu.org/licenses/agpl.txt
 */

mod command;
mod cursor;
mod insert;

use rustty::{Terminal, Event, Color};
use editor;

pub struct Term<'a> {
    cursor: cursor::Cursor,
    editor: &'a mut editor::Editor<'a>,
    term: Terminal,
    quit: bool,
}

impl<'a> Term<'a> {
    pub fn new(editor: &'a mut editor::Editor<'a>) -> Term<'a> {
        Term {
            cursor: cursor::Cursor::new(Color::Red),
            editor: editor,
            term: Terminal::new().unwrap(),
            quit: false,
        }
    }

/// Launches the terminal
    pub fn run(&mut self) {
        self.term[self.cursor.current_pos()].set_bg(self.cursor.color);
        self.print_file();
        self.prompt();
        self.term.swap_buffers().unwrap();

        while !self.quit {
            let evt = self.term.get_event(100).unwrap();
            if let Some(Event::Key(ch)) = evt {
                if self.editor.command_mode() {
                    command::handle(self, ch);
                } else {
                    insert::handle(self, ch);
                }

                if self.cursor.pos.x >= self.term.cols() - 1 {
                    self.term[self.cursor.last_pos()].set_bg(Color::Default);
                    self.cursor.save_pos();
                    self.cursor.pos.x = 0;
                    self.cursor.pos.y += 1;
                }
                if self.cursor.pos.y >= self.term.rows() - 1 {
                    self.term[self.cursor.last_pos()].set_bg(Color::Default);
                    self.cursor.save_pos();
                    self.cursor.pos.x = 0;
                    self.cursor.pos.y = 0;
                }

                self.term[self.cursor.last_pos()].set_bg(Color::Default);
                self.term[self.cursor.current_pos()].set_bg(self.cursor.color);
                self.term.swap_buffers().unwrap();
            }
        }
    }

    /// Prints our prompt to the UI
    pub fn prompt(&mut self) {
        let w = self.term.cols();
        let h = self.term.rows();

        for i in 0..w {
            self.term[(i, h - 2)].set_bg(Color::Red);
        }

        for (i, c) in self.editor.filename().chars().enumerate() {
            self.term[(i, h - 2)].set_ch(c);
        }
    }

    /// Prints our editor's contents to the UI
    fn print_file(&mut self) {
        let mut i = 0;
        let mut j = 0;
        for line in &self.editor.contents {
            for b in line {
                self.term[(j, i)].set_ch(*b as char);
                j += 1;
            }
            i += 1;
            j = 0;
            if i == self.term.rows() - 2 {
                break;
            }
        }
    }

    pub fn quit(&mut self) {
        self.quit = true;
    }
}
<commit_msg>Add line field to keep track of UI location<commit_after>/* Copyright (C)  2016 nokaa <nokaa@cock.li>
 * This software is licensed under the terms of the
 * GNU Affero General Public License. You should have
 * received a copy of this license with this software.
 * The license may also be found at https://gnu.org/licenses/agpl.txt
 */

mod command;
mod cursor;
mod insert;

use rustty::{self, Event, Color};
use editor;

/// `Term` represents our client application. This allows
/// us to work with the filesystem and the UI.
pub struct Term<'a> {
    /// Represents the location of the cursor in our UI
    cursor: cursor::Cursor,
    /// Contains file information; allows us to work with
    /// the filesystem
    editor: &'a mut editor::Editor<'a>,
    /// This is the UI itself
    term: rustty::Terminal,
    /// Represents the running status
    quit: bool,
    /// Represents the topmost line in our UI
    line: usize,
}

impl<'a> Term<'a> {
    pub fn new(editor: &'a mut editor::Editor<'a>) -> Term<'a> {
        Term {
            cursor: cursor::Cursor::new(Color::Red),
            editor: editor,
            term: rustty::Terminal::new().unwrap(),
            quit: false,
            line: 0,
        }
    }

    /// Launches the terminal.
    pub fn run(&mut self) {
        self.term[self.cursor.current_pos()].set_bg(self.cursor.color);
        self.print_file();
        self.prompt();
        self.term.swap_buffers().unwrap();

        while !self.quit {
            let evt = self.term.get_event(100).unwrap();
            if let Some(Event::Key(ch)) = evt {
                if self.editor.command_mode() {
                    command::handle(self, ch);
                } else {
                    insert::handle(self, ch);
                }

                if self.cursor.pos.x >= self.term.cols() - 1 {
                    self.term[self.cursor.last_pos()].set_bg(Color::Default);
                    self.cursor.save_pos();
                    self.cursor.pos.x = 0;
                    self.cursor.pos.y += 1;
                }
                if self.cursor.pos.y >= self.term.rows() - 1 {
                    self.term[self.cursor.last_pos()].set_bg(Color::Default);
                    self.cursor.save_pos();
                    self.cursor.pos.x = 0;
                    self.cursor.pos.y = 0;
                }

                self.term[self.cursor.last_pos()].set_bg(Color::Default);
                self.term[self.cursor.current_pos()].set_bg(self.cursor.color);
                self.term.swap_buffers().unwrap();
            }
        }
    }

    /// Prints our prompt to the UI.
    pub fn prompt(&mut self) {
        let w = self.term.cols();
        let h = self.term.rows();

        for i in 0..w {
            self.term[(i, h - 2)].set_bg(Color::Red);
        }

        for (i, c) in self.editor.filename().chars().enumerate() {
            self.term[(i, h - 2)].set_ch(c);
        }
    }

    /// Prints our editor's contents to the UI.
    fn print_file(&mut self) {
        let mut i = 0;
        let mut j = 0;
        for line in &self.editor.contents {
            for b in line {
                self.term[(j, i)].set_ch(*b as char);
                j += 1;
            }
            i += 1;
            j = 0;
            if i == self.term.rows() - 2 {
                break;
            }
        }
    }

    /// Changes the value of the `quit` attribute to `true`.
    pub fn quit(&mut self) {
        self.quit = true;
    }

    pub fn current_line(&self) -> usize {
        self.line
    }
}
<|endoftext|>


<commit_before>
use sdl2;
use sdl2_image;
use sdl2_image::INIT_PNG;
use colors::Color;

pub struct Cell {
    pub glyph: char,
    pub fg: Color,
    pub bg: Color,
}

pub struct Terminal {
    pub grid: Vec<Cell>,
    pub columns: u32,
    pub rows: u32,
    pub sdl_context: sdl2::Sdl,
}

impl Terminal {
    pub fn new(columns: u32, rows: u32) -> Self {

        let sdl_context = sdl2::init().unwrap();
        let _image_context = sdl2_image::init(INIT_PNG).unwrap();

        let mut grid = vec![];

        let total_cells = columns * rows;
        for _ in 0..total_cells {
            grid.push(Cell {
                glyph: ' ',
                fg: Color {
                    r: 255,
                    g: 255,
                    b: 255,
                    a: 255,
                },
                bg: Color {
                    r: 0,
                    g: 0,
                    b: 0,
                    a: 255,
                },
            });
        }

        Terminal {
            grid: grid,
            columns: columns,
            rows: rows,
            sdl_context: sdl_context,
        }
    }

    pub fn set_cell(&mut self, x: i32, y: i32, cell: Cell) {
        let index = self.columns as i32 * y + x;
        if x >= 0 && y >= 0 && x < self.columns as i32 && y < self.rows as i32 {
            self.grid[index as usize] = cell;
        }
    }

    pub fn set(&mut self, x: i32, y: i32, c: char, fg: Color, bg: Color) {
        let index = self.columns as i32 * y + x;
        if x >= 0 && y >= 0 && x < self.columns as i32 && y < self.rows as i32 {
            self.grid[index as usize] = Cell {
                glyph: c,
                fg: fg,
                bg: bg,
            }
        }
    }

    pub fn print(&mut self, x: i32, y: i32, text: &str, fg: Color, bg: Color) {
        let mut string_chars = text.chars();
        for i in 0..text.len() {
            let c = string_chars.next().unwrap();
            self.set(x + i as i32, y, c, fg, bg);
        }
    }

    pub fn print_center(&mut self, y: i32, text: &str, fg: Color, bg: Color) {
        let center_x = self.columns / 2;
        let str_len_mid = text.len() / 2;
        let target_x = center_x - str_len_mid as u32;
        self.print(target_x as i32, y, text, fg, bg);
    }
}
<commit_msg>simplified the set method of terminal<commit_after>
use sdl2;
use sdl2_image;
use sdl2_image::INIT_PNG;
use colors::Color;

pub struct Cell {
    pub glyph: char,
    pub fg: Color,
    pub bg: Color,
}

pub struct Terminal {
    pub grid: Vec<Cell>,
    pub columns: u32,
    pub rows: u32,
    pub sdl_context: sdl2::Sdl,
}

impl Terminal {
    pub fn new(columns: u32, rows: u32) -> Self {

        let sdl_context = sdl2::init().unwrap();
        let _image_context = sdl2_image::init(INIT_PNG).unwrap();

        let mut grid = vec![];

        let total_cells = columns * rows;
        for _ in 0..total_cells {
            grid.push(Cell {
                glyph: ' ',
                fg: Color {
                    r: 255,
                    g: 255,
                    b: 255,
                    a: 255,
                },
                bg: Color {
                    r: 0,
                    g: 0,
                    b: 0,
                    a: 255,
                },
            });
        }

        Terminal {
            grid: grid,
            columns: columns,
            rows: rows,
            sdl_context: sdl_context,
        }
    }

    pub fn set_cell(&mut self, x: i32, y: i32, cell: Cell) {
        let index = self.columns as i32 * y + x;
        if x >= 0 && y >= 0 && x < self.columns as i32 && y < self.rows as i32 {
            self.grid[index as usize] = cell;
        }
    }

    pub fn set(&mut self, x: i32, y: i32, c: char, fg: Color, bg: Color) {
        let cell = Cell {
            glyph: c,
            fg: fg,
            bg: bg,
        };
        self.set_cell(x, y, cell);
    }

    pub fn print(&mut self, x: i32, y: i32, text: &str, fg: Color, bg: Color) {
        let mut string_chars = text.chars();
        for i in 0..text.len() {
            let c = string_chars.next().unwrap();
            self.set(x + i as i32, y, c, fg, bg);
        }
    }

    pub fn print_center(&mut self, y: i32, text: &str, fg: Color, bg: Color) {
        let center_x = self.columns / 2;
        let str_len_mid = text.len() / 2;
        let target_x = center_x - str_len_mid as u32;
        self.print(target_x as i32, y, text, fg, bg);
    }
}
<|endoftext|>


<commit_before>use super::command::{Command, Query};
use super::command::Command::Tokenize;
use std::collections::HashMap;
use types::tokenizer_type::TokenizerType;
use types::token_filters_type::TokenFiltersType;
use types::normalizer_type::NormalizerType;
use command_query::CommandQuery;
use queryable::Queryable;
use command_line::CommandLine;
use commandable::Commandable;
use extendable::Extendable;
use request_cancellable::RequestCancellable;
use std::fmt;
use std::str::FromStr;
use std::convert::AsRef;
use self::FlagType::{None, EnableTokenizedDelimiter, ExtFlagType};
use self::ModeType::{Add, Get, ExtModeType};
use util;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct TokenizeCommand {
    command: Command,
    tokenizer: TokenizerType,
    string: String,
    arguments: HashMap<String, String>,
}

#[derive (Debug)]
pub enum FlagTypeError {
    Empty,
}

#[derive (Clone, PartialEq, Eq, Debug)]
pub enum FlagType {
    None,
    EnableTokenizedDelimiter,
    /// For future extensibility.
    ExtFlagType(String),
}

impl AsRef<str> for FlagType {
    fn as_ref(&self) -> &str {
        match *self {
            None => "NONE",
            EnableTokenizedDelimiter => "ENABLE_TOKENIZED_DELIMITER",
            ExtFlagType(ref s) => s.as_ref(),
        }
    }
}

impl fmt::Display for FlagType {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(match *self {
            None => "NONE",
            EnableTokenizedDelimiter => "ENABLE_TOKENIZED_DELIMITER",
            ExtFlagType(ref s) => s.as_ref(),
        })
    }
}

impl FromStr for FlagType {
    type Err = FlagTypeError;
    fn from_str(s: &str) -> Result<FlagType, FlagTypeError> {
        if s == "" {
            Err(FlagTypeError::Empty)
        } else {
            Ok(match s {
                "None" | "NONE" => None,
                "EnableTokenDelimiter" | "ENABLE_TOKENIZED_DELIMITER" => EnableTokenizedDelimiter,
                _ => ExtFlagType(s.to_owned()),
            })
        }
    }
}

#[derive (Debug)]
pub enum ModeTypeError {
    Empty,
}

#[derive (Clone, PartialEq, Eq, Debug)]
pub enum ModeType {
    Add,
    Get,
    /// For future extensibility.
    ExtModeType(String),
}

impl AsRef<str> for ModeType {
    fn as_ref(&self) -> &str {
        match *self {
            Add => "ADD",
            Get => "GET",
            ExtModeType(ref s) => s.as_ref(),
        }
    }
}

impl fmt::Display for ModeType {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(match *self {
            Add => "ADD",
            Get => "GET",
            ExtModeType(ref s) => s.as_ref(),
        })
    }
}

impl FromStr for ModeType {
    type Err = ModeTypeError;
    fn from_str(s: &str) -> Result<ModeType, ModeTypeError> {
        if s == "" {
            Err(ModeTypeError::Empty)
        } else {
            Ok(match s {
                "Add" | "ADD" => Add,
                "Get" | "GET" => Get,
                _ => ExtModeType(s.to_owned()),
            })
        }
    }
}

impl Default for TokenizeCommand {
    fn default() -> TokenizeCommand {
        TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "".to_string(),
            arguments: HashMap::new(),
        }
    }
}

impl TokenizeCommand {
    pub fn new(tokenizer: TokenizerType, string: String) -> TokenizeCommand {
        let default: TokenizeCommand = Default::default();
        TokenizeCommand {
            command: default.command,
            tokenizer: tokenizer,
            string: string,
            arguments: default.arguments,
        }
    }

    pub fn normalizer(mut self, normalizer_type: NormalizerType) -> TokenizeCommand {
        let string = format!("{}", normalizer_type);
        self.arguments.insert("normalizer".to_string(), string.clone());
        self
    }

    pub fn token_filters(mut self, token_filters: TokenFiltersType) -> TokenizeCommand {

        let string = format!("{}", token_filters);
        self.arguments.insert("token_filters".to_string(), string.clone());
        self
    }

    pub fn flags(mut self, flags: Vec<FlagType>) -> TokenizeCommand {
        let string = util::split_flags_vec(flags);
        self.arguments.insert("flags".to_string(), string.clone());
        self
    }

    pub fn mode(mut self, mode: ModeType) -> TokenizeCommand {
        let string = format!("{}", mode);
        self.arguments.insert("mode".to_string(), string.clone());
        self
    }

    pub fn build(self) -> (Command, Query) {
        let mut query: Query = vec![("tokenizer".to_string(), format!("{}", self.tokenizer)),
                                    ("string".to_string(), self.string)];
        for (key, value) in self.arguments.iter() {
            query.push((key.to_owned(), value.to_owned()));
        }
        (Tokenize, query)
    }
}

impl Queryable for TokenizeCommand {
    fn to_query(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandQuery::new(command, query);
        command.encode()
    }
}

impl Commandable for TokenizeCommand {
    fn to_command(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandLine::new(command, query);
        command.encode()
    }
}

extendable!(TokenizeCommand);
request_cancellable!(TokenizeCommand);

#[cfg(test)]
mod test {
    use super::*;
    use command::Query;
    use command::Command::Tokenize;
    use std::collections::HashMap;
    use types::token_filters_type::TokenFiltersType;
    use types::tokenizer_type::TokenizerType;
    use types::normalizer_type::NormalizerType;
    use std::str::FromStr;
    use queryable::Queryable;
    use commandable::Commandable;
    use extendable::Extendable;

    #[test]
    fn test_flag_type_from_str() {
        assert_eq!(FlagType::None, FromStr::from_str("None").unwrap());
        assert_eq!(FlagType::ExtFlagType("added-type".to_owned()),
                   FromStr::from_str("added-type").unwrap());
        let x: Result<FlagType, _> = FromStr::from_str("");
        if let Err(FlagTypeError::Empty) = x {
        } else {
            panic!("An empty input type is invalid!")
        }
    }

    #[test]
    fn test_flag_type_fmt() {
        assert_eq!("NONE".to_owned(), format!("{}", FlagType::None));
        assert_eq!("ENABLE_TOKENIZED_DELIMITER".to_owned(),
                   format!("{}", FlagType::EnableTokenizedDelimiter));
        assert_eq!("added-type".to_owned(),
                   format!("{}", FlagType::ExtFlagType("added-type".to_owned())));
    }

    #[test]
    fn test_flag_type_as_str() {
        assert_eq!(FlagType::None.as_ref(), "NONE");
        assert_eq!(FlagType::EnableTokenizedDelimiter.as_ref(),
                   "ENABLE_TOKENIZED_DELIMITER");
        assert_eq!(FlagType::ExtFlagType("added-type".to_owned()).as_ref(),
                   "added-type");
    }

    #[test]
    fn test_mode_from_str() {
        assert_eq!(ModeType::Add, FromStr::from_str("Add").unwrap());
        assert_eq!(ModeType::ExtModeType("added-type".to_owned()),
                   FromStr::from_str("added-type").unwrap());
        let x: Result<ModeType, _> = FromStr::from_str("");
        if let Err(ModeTypeError::Empty) = x {
        } else {
            panic!("An empty input type is invalid!")
        }
    }

    #[test]
    fn test_mode_fmt() {
        assert_eq!("ADD".to_owned(), format!("{}", ModeType::Add));
        assert_eq!("GET".to_owned(), format!("{}", ModeType::Get));
        assert_eq!("added-type".to_owned(),
                   format!("{}", FlagType::ExtFlagType("added-type".to_owned())));
    }

    #[test]
    fn test_mode_as_str() {
        assert_eq!(ModeType::Add.as_ref(), "ADD");
        assert_eq!(ModeType::Get.as_ref(), "GET");
        assert_eq!(FlagType::ExtFlagType("added-type".to_owned()).as_ref(),
                   "added-type");
    }

    #[test]
    fn test_new() {
        let tokenize = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string());
        let expected = TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "element".to_string(),
            arguments: HashMap::new(),
        };
        assert_eq!(expected, tokenize);
    }

    #[test]
    fn test_normalizer() {
        let column_create = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string())
                                .normalizer(NormalizerType::Auto);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("normalizer".to_string(),
                   format!("{}", NormalizerType::Auto));
        let expected = TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "element".to_string(),
            arguments: arg.clone(),
        };
        assert_eq!(expected, column_create);
    }

    #[test]
    fn test_token_filters() {
        let token_filters = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string())
                                .token_filters(TokenFiltersType::StopWord);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("token_filters".to_string(),
                   format!("{}", TokenFiltersType::StopWord));
        let expected = TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "element".to_string(),
            arguments: arg.clone(),
        };
        assert_eq!(expected, token_filters);
    }

    #[test]
    fn test_flags() {
        let tokenize = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string())
                           .flags(vec![(FlagType::None), (FlagType::EnableTokenizedDelimiter)]);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("flags".to_string(),
                   "NONE|ENABLE_TOKENIZED_DELIMITER".to_string());
        let expected = TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "element".to_string(),
            arguments: arg.clone(),
        };
        assert_eq!(expected, tokenize);
    }

    #[test]
    fn test_mode() {
        let tokenize = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string())
                           .mode(ModeType::Add);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("mode".to_string(), format!("{}", ModeType::Add));
        let expected = TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "element".to_string(),
            arguments: arg.clone(),
        };
        assert_eq!(expected, tokenize);
    }

    #[test]
    fn test_build() {
        let actual = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string()).build();
        let expected_query: Query = vec![("tokenizer".to_string(),
                                          format!("{}", TokenizerType::Bigram)),
                                         ("string".to_string(), "element".to_string())];
        let expected = (Tokenize, expected_query);
        assert_eq!(expected, actual);
    }

    #[test]
    fn test_queryable() {
        let query = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string()).to_query();
        let url_encoded = "/d/tokenize?tokenizer=TokenBigram&string=element";
        assert_eq!(url_encoded.to_string(), query);
    }

    #[test]
    fn test_commandable() {
        let query = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string()).to_command();
        let url_encoded = "tokenize --tokenizer TokenBigram --string element";
        assert_eq!(url_encoded.to_string(), query);
    }

    #[test]
    fn test_extendable() {
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("user".to_string(), "defined".to_string());
        let expected = TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "element".to_string(),
            arguments: arg.clone(),
        };
        let query = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string());
        unsafe {
            let extended = query.set_arguments(arg.clone());
            assert_eq!(expected, extended);
        }
    }
}
<commit_msg>tokenize: Add escape for string argument<commit_after>use super::command::{Command, Query};
use super::command::Command::Tokenize;
use std::collections::HashMap;
use types::tokenizer_type::TokenizerType;
use types::token_filters_type::TokenFiltersType;
use types::normalizer_type::NormalizerType;
use command_query::CommandQuery;
use queryable::Queryable;
use command_line::CommandLine;
use commandable::Commandable;
use extendable::Extendable;
use request_cancellable::RequestCancellable;
use std::fmt;
use std::str::FromStr;
use std::convert::AsRef;
use self::FlagType::{None, EnableTokenizedDelimiter, ExtFlagType};
use self::ModeType::{Add, Get, ExtModeType};
use util;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct TokenizeCommand {
    command: Command,
    tokenizer: TokenizerType,
    string: String,
    arguments: HashMap<String, String>,
}

#[derive (Debug)]
pub enum FlagTypeError {
    Empty,
}

#[derive (Clone, PartialEq, Eq, Debug)]
pub enum FlagType {
    None,
    EnableTokenizedDelimiter,
    /// For future extensibility.
    ExtFlagType(String),
}

impl AsRef<str> for FlagType {
    fn as_ref(&self) -> &str {
        match *self {
            None => "NONE",
            EnableTokenizedDelimiter => "ENABLE_TOKENIZED_DELIMITER",
            ExtFlagType(ref s) => s.as_ref(),
        }
    }
}

impl fmt::Display for FlagType {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(match *self {
            None => "NONE",
            EnableTokenizedDelimiter => "ENABLE_TOKENIZED_DELIMITER",
            ExtFlagType(ref s) => s.as_ref(),
        })
    }
}

impl FromStr for FlagType {
    type Err = FlagTypeError;
    fn from_str(s: &str) -> Result<FlagType, FlagTypeError> {
        if s == "" {
            Err(FlagTypeError::Empty)
        } else {
            Ok(match s {
                "None" | "NONE" => None,
                "EnableTokenDelimiter" | "ENABLE_TOKENIZED_DELIMITER" => EnableTokenizedDelimiter,
                _ => ExtFlagType(s.to_owned()),
            })
        }
    }
}

#[derive (Debug)]
pub enum ModeTypeError {
    Empty,
}

#[derive (Clone, PartialEq, Eq, Debug)]
pub enum ModeType {
    Add,
    Get,
    /// For future extensibility.
    ExtModeType(String),
}

impl AsRef<str> for ModeType {
    fn as_ref(&self) -> &str {
        match *self {
            Add => "ADD",
            Get => "GET",
            ExtModeType(ref s) => s.as_ref(),
        }
    }
}

impl fmt::Display for ModeType {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(match *self {
            Add => "ADD",
            Get => "GET",
            ExtModeType(ref s) => s.as_ref(),
        })
    }
}

impl FromStr for ModeType {
    type Err = ModeTypeError;
    fn from_str(s: &str) -> Result<ModeType, ModeTypeError> {
        if s == "" {
            Err(ModeTypeError::Empty)
        } else {
            Ok(match s {
                "Add" | "ADD" => Add,
                "Get" | "GET" => Get,
                _ => ExtModeType(s.to_owned()),
            })
        }
    }
}

impl Default for TokenizeCommand {
    fn default() -> TokenizeCommand {
        TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "".to_string(),
            arguments: HashMap::new(),
        }
    }
}

impl TokenizeCommand {
    pub fn new(tokenizer: TokenizerType, string: String) -> TokenizeCommand {
        let default: TokenizeCommand = Default::default();
        TokenizeCommand {
            command: default.command,
            tokenizer: tokenizer,
            string: format!("\"{}\"", string),
            arguments: default.arguments,
        }
    }

    pub fn normalizer(mut self, normalizer_type: NormalizerType) -> TokenizeCommand {
        let string = format!("{}", normalizer_type);
        self.arguments.insert("normalizer".to_string(), string.clone());
        self
    }

    pub fn token_filters(mut self, token_filters: TokenFiltersType) -> TokenizeCommand {

        let string = format!("{}", token_filters);
        self.arguments.insert("token_filters".to_string(), string.clone());
        self
    }

    pub fn flags(mut self, flags: Vec<FlagType>) -> TokenizeCommand {
        let string = util::split_flags_vec(flags);
        self.arguments.insert("flags".to_string(), string.clone());
        self
    }

    pub fn mode(mut self, mode: ModeType) -> TokenizeCommand {
        let string = format!("{}", mode);
        self.arguments.insert("mode".to_string(), string.clone());
        self
    }

    pub fn build(self) -> (Command, Query) {
        let mut query: Query = vec![("tokenizer".to_string(), format!("{}", self.tokenizer)),
                                    ("string".to_string(), self.string)];
        for (key, value) in self.arguments.iter() {
            query.push((key.to_owned(), value.to_owned()));
        }
        (Tokenize, query)
    }
}

impl Queryable for TokenizeCommand {
    fn to_query(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandQuery::new(command, query);
        command.encode()
    }
}

impl Commandable for TokenizeCommand {
    fn to_command(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandLine::new(command, query);
        command.encode()
    }
}

extendable!(TokenizeCommand);
request_cancellable!(TokenizeCommand);

#[cfg(test)]
mod test {
    use super::*;
    use command::Query;
    use command::Command::Tokenize;
    use std::collections::HashMap;
    use types::token_filters_type::TokenFiltersType;
    use types::tokenizer_type::TokenizerType;
    use types::normalizer_type::NormalizerType;
    use std::str::FromStr;
    use queryable::Queryable;
    use commandable::Commandable;
    use extendable::Extendable;

    #[test]
    fn test_flag_type_from_str() {
        assert_eq!(FlagType::None, FromStr::from_str("None").unwrap());
        assert_eq!(FlagType::ExtFlagType("added-type".to_owned()),
                   FromStr::from_str("added-type").unwrap());
        let x: Result<FlagType, _> = FromStr::from_str("");
        if let Err(FlagTypeError::Empty) = x {
        } else {
            panic!("An empty input type is invalid!")
        }
    }

    #[test]
    fn test_flag_type_fmt() {
        assert_eq!("NONE".to_owned(), format!("{}", FlagType::None));
        assert_eq!("ENABLE_TOKENIZED_DELIMITER".to_owned(),
                   format!("{}", FlagType::EnableTokenizedDelimiter));
        assert_eq!("added-type".to_owned(),
                   format!("{}", FlagType::ExtFlagType("added-type".to_owned())));
    }

    #[test]
    fn test_flag_type_as_str() {
        assert_eq!(FlagType::None.as_ref(), "NONE");
        assert_eq!(FlagType::EnableTokenizedDelimiter.as_ref(),
                   "ENABLE_TOKENIZED_DELIMITER");
        assert_eq!(FlagType::ExtFlagType("added-type".to_owned()).as_ref(),
                   "added-type");
    }

    #[test]
    fn test_mode_from_str() {
        assert_eq!(ModeType::Add, FromStr::from_str("Add").unwrap());
        assert_eq!(ModeType::ExtModeType("added-type".to_owned()),
                   FromStr::from_str("added-type").unwrap());
        let x: Result<ModeType, _> = FromStr::from_str("");
        if let Err(ModeTypeError::Empty) = x {
        } else {
            panic!("An empty input type is invalid!")
        }
    }

    #[test]
    fn test_mode_fmt() {
        assert_eq!("ADD".to_owned(), format!("{}", ModeType::Add));
        assert_eq!("GET".to_owned(), format!("{}", ModeType::Get));
        assert_eq!("added-type".to_owned(),
                   format!("{}", FlagType::ExtFlagType("added-type".to_owned())));
    }

    #[test]
    fn test_mode_as_str() {
        assert_eq!(ModeType::Add.as_ref(), "ADD");
        assert_eq!(ModeType::Get.as_ref(), "GET");
        assert_eq!(FlagType::ExtFlagType("added-type".to_owned()).as_ref(),
                   "added-type");
    }

    #[test]
    fn test_new() {
        let tokenize = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string());
        let expected = TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "\"element\"".to_string(),
            arguments: HashMap::new(),
        };
        assert_eq!(expected, tokenize);
    }

    #[test]
    fn test_normalizer() {
        let column_create = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string())
                                .normalizer(NormalizerType::Auto);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("normalizer".to_string(),
                   format!("{}", NormalizerType::Auto));
        let expected = TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "\"element\"".to_string(),
            arguments: arg.clone(),
        };
        assert_eq!(expected, column_create);
    }

    #[test]
    fn test_token_filters() {
        let token_filters = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string())
                                .token_filters(TokenFiltersType::StopWord);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("token_filters".to_string(),
                   format!("{}", TokenFiltersType::StopWord));
        let expected = TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "\"element\"".to_string(),
            arguments: arg.clone(),
        };
        assert_eq!(expected, token_filters);
    }

    #[test]
    fn test_flags() {
        let tokenize = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string())
                           .flags(vec![(FlagType::None), (FlagType::EnableTokenizedDelimiter)]);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("flags".to_string(),
                   "NONE|ENABLE_TOKENIZED_DELIMITER".to_string());
        let expected = TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "\"element\"".to_string(),
            arguments: arg.clone(),
        };
        assert_eq!(expected, tokenize);
    }

    #[test]
    fn test_mode() {
        let tokenize = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string())
                           .mode(ModeType::Add);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("mode".to_string(), format!("{}", ModeType::Add));
        let expected = TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "\"element\"".to_string(),
            arguments: arg.clone(),
        };
        assert_eq!(expected, tokenize);
    }

    #[test]
    fn test_build() {
        let actual = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string()).build();
        let expected_query: Query = vec![("tokenizer".to_string(),
                                          format!("{}", TokenizerType::Bigram)),
                                         ("string".to_string(), "\"element\"".to_string())];
        let expected = (Tokenize, expected_query);
        assert_eq!(expected, actual);
    }

    #[test]
    fn test_queryable() {
        let query = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string()).to_query();
        let url_encoded = "/d/tokenize?tokenizer=TokenBigram&string=%22element%22";
        assert_eq!(url_encoded.to_string(), query);
    }

    #[test]
    fn test_commandable() {
        let query = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string()).to_command();
        let url_encoded = "tokenize --tokenizer TokenBigram --string \"element\"";
        assert_eq!(url_encoded.to_string(), query);
    }

    #[test]
    fn test_extendable() {
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("user".to_string(), "defined".to_string());
        let expected = TokenizeCommand {
            command: Tokenize,
            tokenizer: TokenizerType::Bigram,
            string: "\"element\"".to_string(),
            arguments: arg.clone(),
        };
        let query = TokenizeCommand::new(TokenizerType::Bigram, "element".to_string());
        unsafe {
            let extended = query.set_arguments(arg.clone());
            assert_eq!(expected, extended);
        }
    }
}
<|endoftext|>


<commit_before>//! HIR datatypes. See the [rustc dev guide] for more info.
//!
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html

#![feature(crate_visibility_modifier)]
#![feature(const_fn)] // For the unsizing cast on `&[]`
#![feature(const_panic)]
#![feature(in_band_lifetimes)]
#![feature(once_cell)]
#![feature(or_patterns)]
#![recursion_limit = "256"]

#[macro_use]
extern crate rustc_macros;

#[macro_use]
extern crate rustc_data_structures;

mod arena;
pub mod def;
pub mod definitions;
pub use rustc_span::def_id;
mod hir;
pub mod hir_id;
pub mod intravisit;
pub mod itemlikevisit;
pub mod lang_items;
pub mod pat_util;
mod stable_hash_impls;
mod target;
pub mod weak_lang_items;

pub use hir::*;
pub use hir_id::*;
pub use lang_items::{LangItem, LanguageItems};
pub use stable_hash_impls::HashStableContext;
pub use target::{MethodKind, Target};
<commit_msg>Enable `extended_key_value_attributes` in `rustc_hir`<commit_after>//! HIR datatypes. See the [rustc dev guide] for more info.
//!
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html

#![feature(crate_visibility_modifier)]
#![feature(const_fn)] // For the unsizing cast on `&[]`
#![feature(const_panic)]
#![feature(extended_key_value_attributes)]
#![feature(in_band_lifetimes)]
#![feature(once_cell)]
#![feature(or_patterns)]
#![recursion_limit = "256"]

#[macro_use]
extern crate rustc_macros;

#[macro_use]
extern crate rustc_data_structures;

mod arena;
pub mod def;
pub mod definitions;
pub use rustc_span::def_id;
mod hir;
pub mod hir_id;
pub mod intravisit;
pub mod itemlikevisit;
pub mod lang_items;
pub mod pat_util;
mod stable_hash_impls;
mod target;
pub mod weak_lang_items;

pub use hir::*;
pub use hir_id::*;
pub use lang_items::{LangItem, LanguageItems};
pub use stable_hash_impls::HashStableContext;
pub use target::{MethodKind, Target};
<|endoftext|>


<commit_before>//! Tests specific definitions
use std::iter::IntoIterator;
use std::slice::Iter;
use std::vec::IntoIter;

use super::{RawMode, RawReader, Renderer, Term};
use crate::config::{BellStyle, ColorMode, Config, OutputStreamType};
use crate::error::ReadlineError;
use crate::highlight::Highlighter;
use crate::keys::{KeyEvent, KeyCode as K, Modifiers as M};
use crate::layout::{Layout, Position};
use crate::line_buffer::LineBuffer;
use crate::Result;

pub type Mode = ();

impl RawMode for Mode {
    fn disable_raw_mode(&self) -> Result<()> {
        Ok(())
    }
}

impl<'a> RawReader for Iter<'a, KeyEvent> {
    fn next_key(&mut self, _: bool) -> Result<KeyEvent> {
        match self.next() {
            Some(key) => Ok(*key),
            None => Err(ReadlineError::Eof),
        }
    }

    #[cfg(unix)]
    fn next_char(&mut self) -> Result<char> {
        unimplemented!();
    }

    fn read_pasted_text(&mut self) -> Result<String> {
        unimplemented!()
    }
}

impl RawReader for IntoIter<KeyEvent> {
    fn next_key(&mut self, _: bool) -> Result<KeyEvent> {
        match self.next() {
            Some(key) => Ok(key),
            None => Err(ReadlineError::Eof),
        }
    }

    #[cfg(unix)]
    fn next_char(&mut self) -> Result<char> {
        match self.next() {
            Some((K::Char(c), M::NONE)) => Ok(c),
            None => Err(ReadlineError::Eof),
            _ => unimplemented!(),
        }
    }

    fn read_pasted_text(&mut self) -> Result<String> {
        unimplemented!()
    }
}

pub struct Sink {}

impl Sink {
    pub fn new() -> Sink {
        Sink {}
    }
}

impl Renderer for Sink {
    type Reader = IntoIter<KeyEvent>;

    fn move_cursor(&mut self, _: Position, _: Position) -> Result<()> {
        Ok(())
    }

    fn refresh_line(
        &mut self,
        _prompt: &str,
        _line: &LineBuffer,
        _hint: Option<&str>,
        _old_layout: &Layout,
        _new_layout: &Layout,
        _highlighter: Option<&dyn Highlighter>,
    ) -> Result<()> {
        Ok(())
    }

    fn calculate_position(&self, s: &str, orig: Position) -> Position {
        let mut pos = orig;
        pos.col += s.len();
        pos
    }

    fn write_and_flush(&self, _: &[u8]) -> Result<()> {
        Ok(())
    }

    fn beep(&mut self) -> Result<()> {
        Ok(())
    }

    fn clear_screen(&mut self) -> Result<()> {
        Ok(())
    }

    fn sigwinch(&self) -> bool {
        false
    }

    fn update_size(&mut self) {}

    fn get_columns(&self) -> usize {
        80
    }

    fn get_rows(&self) -> usize {
        24
    }

    fn colors_enabled(&self) -> bool {
        false
    }

    fn move_cursor_at_leftmost(&mut self, _: &mut IntoIter<KeyEvent>) -> Result<()> {
        Ok(())
    }
}

pub type Terminal = DummyTerminal;

#[derive(Clone, Debug)]
pub struct DummyTerminal {
    pub keys: Vec<KeyEvent>,
    pub cursor: usize, // cursor position before last command
    pub color_mode: ColorMode,
    pub bell_style: BellStyle,
}

impl Term for DummyTerminal {
    type Mode = Mode;
    type Reader = IntoIter<KeyEvent>;
    type Writer = Sink;

    fn new(
        color_mode: ColorMode,
        _stream: OutputStreamType,
        _tab_stop: usize,
        bell_style: BellStyle,
    ) -> DummyTerminal {
        DummyTerminal {
            keys: Vec::new(),
            cursor: 0,
            color_mode,
            bell_style,
        }
    }

    // Init checks:

    #[cfg(not(target_arch = "wasm32"))]
    fn is_unsupported(&self) -> bool {
        false
    }

    #[cfg(target_arch = "wasm32")]
    fn is_unsupported(&self) -> bool {
        true
    }

    fn is_stdin_tty(&self) -> bool {
        true
    }

    fn is_output_tty(&self) -> bool {
        false
    }

    // Interactive loop:

    fn enable_raw_mode(&mut self) -> Result<Mode> {
        Ok(())
    }

    fn create_reader(&self, _: &Config) -> Result<IntoIter<KeyEvent>> {
        Ok(self.keys.clone().into_iter())
    }

    fn create_writer(&self) -> Sink {
        Sink::new()
    }
}

#[cfg(unix)]
pub fn suspend() -> Result<()> {
    Ok(())
}
<commit_msg>Fix warning on windows<commit_after>//! Tests specific definitions
use std::iter::IntoIterator;
use std::slice::Iter;
use std::vec::IntoIter;

use super::{RawMode, RawReader, Renderer, Term};
use crate::config::{BellStyle, ColorMode, Config, OutputStreamType};
use crate::error::ReadlineError;
use crate::highlight::Highlighter;
use crate::keys::KeyEvent;
use crate::layout::{Layout, Position};
use crate::line_buffer::LineBuffer;
use crate::Result;

pub type Mode = ();

impl RawMode for Mode {
    fn disable_raw_mode(&self) -> Result<()> {
        Ok(())
    }
}

impl<'a> RawReader for Iter<'a, KeyEvent> {
    fn next_key(&mut self, _: bool) -> Result<KeyEvent> {
        match self.next() {
            Some(key) => Ok(*key),
            None => Err(ReadlineError::Eof),
        }
    }

    #[cfg(unix)]
    fn next_char(&mut self) -> Result<char> {
        unimplemented!();
    }

    fn read_pasted_text(&mut self) -> Result<String> {
        unimplemented!()
    }
}

impl RawReader for IntoIter<KeyEvent> {
    fn next_key(&mut self, _: bool) -> Result<KeyEvent> {
        match self.next() {
            Some(key) => Ok(key),
            None => Err(ReadlineError::Eof),
        }
    }

    #[cfg(unix)]
    fn next_char(&mut self) -> Result<char> {
        use crate::keys::{KeyCode as K, Modifiers as M};
        match self.next() {
            Some((K::Char(c), M::NONE)) => Ok(c),
            None => Err(ReadlineError::Eof),
            _ => unimplemented!(),
        }
    }

    fn read_pasted_text(&mut self) -> Result<String> {
        unimplemented!()
    }
}

pub struct Sink {}

impl Sink {
    pub fn new() -> Sink {
        Sink {}
    }
}

impl Renderer for Sink {
    type Reader = IntoIter<KeyEvent>;

    fn move_cursor(&mut self, _: Position, _: Position) -> Result<()> {
        Ok(())
    }

    fn refresh_line(
        &mut self,
        _prompt: &str,
        _line: &LineBuffer,
        _hint: Option<&str>,
        _old_layout: &Layout,
        _new_layout: &Layout,
        _highlighter: Option<&dyn Highlighter>,
    ) -> Result<()> {
        Ok(())
    }

    fn calculate_position(&self, s: &str, orig: Position) -> Position {
        let mut pos = orig;
        pos.col += s.len();
        pos
    }

    fn write_and_flush(&self, _: &[u8]) -> Result<()> {
        Ok(())
    }

    fn beep(&mut self) -> Result<()> {
        Ok(())
    }

    fn clear_screen(&mut self) -> Result<()> {
        Ok(())
    }

    fn sigwinch(&self) -> bool {
        false
    }

    fn update_size(&mut self) {}

    fn get_columns(&self) -> usize {
        80
    }

    fn get_rows(&self) -> usize {
        24
    }

    fn colors_enabled(&self) -> bool {
        false
    }

    fn move_cursor_at_leftmost(&mut self, _: &mut IntoIter<KeyEvent>) -> Result<()> {
        Ok(())
    }
}

pub type Terminal = DummyTerminal;

#[derive(Clone, Debug)]
pub struct DummyTerminal {
    pub keys: Vec<KeyEvent>,
    pub cursor: usize, // cursor position before last command
    pub color_mode: ColorMode,
    pub bell_style: BellStyle,
}

impl Term for DummyTerminal {
    type Mode = Mode;
    type Reader = IntoIter<KeyEvent>;
    type Writer = Sink;

    fn new(
        color_mode: ColorMode,
        _stream: OutputStreamType,
        _tab_stop: usize,
        bell_style: BellStyle,
    ) -> DummyTerminal {
        DummyTerminal {
            keys: Vec::new(),
            cursor: 0,
            color_mode,
            bell_style,
        }
    }

    // Init checks:

    #[cfg(not(target_arch = "wasm32"))]
    fn is_unsupported(&self) -> bool {
        false
    }

    #[cfg(target_arch = "wasm32")]
    fn is_unsupported(&self) -> bool {
        true
    }

    fn is_stdin_tty(&self) -> bool {
        true
    }

    fn is_output_tty(&self) -> bool {
        false
    }

    // Interactive loop:

    fn enable_raw_mode(&mut self) -> Result<Mode> {
        Ok(())
    }

    fn create_reader(&self, _: &Config) -> Result<IntoIter<KeyEvent>> {
        Ok(self.keys.clone().into_iter())
    }

    fn create_writer(&self) -> Sink {
        Sink::new()
    }
}

#[cfg(unix)]
pub fn suspend() -> Result<()> {
    Ok(())
}
<|endoftext|>