<commit_before>pub use std::ptr;

macro_rules! merge {
    ($default:expr => $($field:ident : $value:expr),*) => {
        {
            let mut x = $default;
            $( x.$field = $value; )*

            x
        }
    }
}

#[macro_export]
macro_rules! endpoint_descriptor {
    ($($key:ident : $value:expr),*) => {
        merge!(
            ::libusb::libusb_endpoint_descriptor {
                bLength:          7,
                bDescriptorType:  0x05,
                bEndpointAddress: 0x00,
                bmAttributes:     0x00,
                wMaxPacketSize:   16,
                bInterval:        1,
                bRefresh:         1,
                bSynchAddress:    0,
                extra:            $crate::test_helpers::ptr::null(),
                extra_length:     0
            } => $($key: $value),*
        )
    }
}

#[macro_export]
macro_rules! interface_descriptor {
    ($($key:ident : $value:expr),*) => {
        merge!(
            ::libusb::libusb_interface_descriptor {
                bLength:            9,
                bDescriptorType:    0x04,
                bInterfaceNumber:   0,
                bAlternateSetting:  0,
                bNumEndpoints:      0,
                bInterfaceClass:    0,
                bInterfaceSubClass: 0,
                bInterfaceProtocol: 0,
                iInterface:         0,
                endpoint:           $crate::test_helpers::ptr::null(),
                extra:              $crate::test_helpers::ptr::null(),
                extra_length:       0
            } => $($key: $value),*
        )
    };
    ($($endpoint:expr),+) => {
        {
            let endpoints = vec![$($endpoint),+];

            ::libusb::libusb_interface_descriptor {
                bLength:            9,
                bDescriptorType:    0x04,
                bInterfaceNumber:   0,
                bAlternateSetting:  0,
                bNumEndpoints:      endpoints.len() as u8,
                bInterfaceClass:    0,
                bInterfaceSubClass: 0,
                bInterfaceProtocol: 0,
                iInterface:         0,
                endpoint:           (&endpoints[..]).as_ptr(),
                extra:              $crate::test_helpers::ptr::null(),
                extra_length:       0
            }
        }
    }
}

#[macro_export]
macro_rules! interface {
    ($($descriptor:expr),*) => {
        {
            let descriptors = vec![$($descriptor),*];

            ::libusb::libusb_interface {
                altsetting:     descriptors.as_ptr(),
                num_altsetting: descriptors.len() as ::libc::c_int
            }
        }
    }
}

#[macro_export]
macro_rules! config_descriptor {
    ($($key:ident : $value:expr),*) => {
        merge!(
            ::libusb::libusb_config_descriptor {
                bLength:             9,
                bDescriptorType:     0x02,
                wTotalLength:        9,
                bNumInterfaces:      0,
                bConfigurationValue: 0,
                iConfiguration:      0,
                bmAttributes:        0x00,
                bMaxPower:           10,
                interface:           $crate::test_helpers::ptr::null(),
                extra:               $crate::test_helpers::ptr::null(),
                extra_length:        0
            } => $($key: $value),*
        )
    };
    ($($interface:expr),+) => {
        {
            let interfaces = vec![$($interface),+];

            ::libusb::libusb_config_descriptor {
                bLength:             9,
                bDescriptorType:     0x02,
                wTotalLength:        9,
                bNumInterfaces:      interfaces.len() as u8,
                bConfigurationValue: 0,
                iConfiguration:      0,
                bmAttributes:        0x00,
                bMaxPower:           10,
                interface:           (&interfaces[..]).as_ptr(),
                extra:               $crate::test_helpers::ptr::null(),
                extra_length:        0
            }
        }
    }
}

#[macro_export]
macro_rules! device_descriptor {
    ($($key:ident : $value:expr),*) => {
        merge!(
            ::libusb::libusb_device_descriptor {
                bLength:            18,
                bDescriptorType:    0x01,
                bcdUSB:             0x0110,
                bDeviceClass:       0,
                bDeviceSubClass:    0,
                bDeviceProtocol:    0,
                bMaxPacketSize0:    16,
                idVendor:           0x1234,
                idProduct:          0x5678,
                bcdDevice:          0x0123,
                iManufacturer:      0,
                iProduct:           0,
                iSerialNumber:      0,
                bNumConfigurations: 1
            } => $($key: $value),*
        )
    }
}
<commit_msg>Fix use-after-free in tests<commit_after>pub use std::ptr;

macro_rules! merge {
    ($default:expr => $($field:ident : $value:expr),*) => {
        {
            let mut x = $default;
            $( x.$field = $value; )*

            x
        }
    }
}

#[macro_export]
macro_rules! endpoint_descriptor {
    ($($key:ident : $value:expr),*) => {
        merge!(
            ::libusb::libusb_endpoint_descriptor {
                bLength:          7,
                bDescriptorType:  0x05,
                bEndpointAddress: 0x00,
                bmAttributes:     0x00,
                wMaxPacketSize:   16,
                bInterval:        1,
                bRefresh:         1,
                bSynchAddress:    0,
                extra:            $crate::test_helpers::ptr::null(),
                extra_length:     0
            } => $($key: $value),*
        )
    }
}

#[macro_export]
macro_rules! interface_descriptor {
    ($($key:ident : $value:expr),*) => {
        merge!(
            ::libusb::libusb_interface_descriptor {
                bLength:            9,
                bDescriptorType:    0x04,
                bInterfaceNumber:   0,
                bAlternateSetting:  0,
                bNumEndpoints:      0,
                bInterfaceClass:    0,
                bInterfaceSubClass: 0,
                bInterfaceProtocol: 0,
                iInterface:         0,
                endpoint:           $crate::test_helpers::ptr::null(),
                extra:              $crate::test_helpers::ptr::null(),
                extra_length:       0
            } => $($key: $value),*
        )
    };
    ($($endpoint:expr),+) => {
        {
            let endpoints = vec![$($endpoint),+];

            let r = ::libusb::libusb_interface_descriptor {
                bLength:            9,
                bDescriptorType:    0x04,
                bInterfaceNumber:   0,
                bAlternateSetting:  0,
                bNumEndpoints:      endpoints.len() as u8,
                bInterfaceClass:    0,
                bInterfaceSubClass: 0,
                bInterfaceProtocol: 0,
                iInterface:         0,
                endpoint:           (&endpoints[..]).as_ptr(),
                extra:              $crate::test_helpers::ptr::null(),
                extra_length:       0
            };

            // leak the Vec so the returned pointer remains valid
            ::std::mem::forget(endpoints);
            r
        }
    }
}

#[macro_export]
macro_rules! interface {
    ($($descriptor:expr),*) => {
        {
            let descriptors = vec![$($descriptor),*];

            let r = ::libusb::libusb_interface {
                altsetting:     descriptors.as_ptr(),
                num_altsetting: descriptors.len() as ::libc::c_int
            };

            // leak the Vec so the returned pointer remains valid
            ::std::mem::forget(descriptors);
            r
        }
    }
}

#[macro_export]
macro_rules! config_descriptor {
    ($($key:ident : $value:expr),*) => {
        merge!(
            ::libusb::libusb_config_descriptor {
                bLength:             9,
                bDescriptorType:     0x02,
                wTotalLength:        9,
                bNumInterfaces:      0,
                bConfigurationValue: 0,
                iConfiguration:      0,
                bmAttributes:        0x00,
                bMaxPower:           10,
                interface:           $crate::test_helpers::ptr::null(),
                extra:               $crate::test_helpers::ptr::null(),
                extra_length:        0
            } => $($key: $value),*
        )
    };
    ($($interface:expr),+) => {
        {
            let interfaces = vec![$($interface),+];

            let r = ::libusb::libusb_config_descriptor {
                bLength:             9,
                bDescriptorType:     0x02,
                wTotalLength:        9,
                bNumInterfaces:      interfaces.len() as u8,
                bConfigurationValue: 0,
                iConfiguration:      0,
                bmAttributes:        0x00,
                bMaxPower:           10,
                interface:           (&interfaces[..]).as_ptr(),
                extra:               $crate::test_helpers::ptr::null(),
                extra_length:        0
            };

            // leak the Vec so the returned pointer remains valid
            ::std::mem::forget(interfaces);
            r
        }
    }
}

#[macro_export]
macro_rules! device_descriptor {
    ($($key:ident : $value:expr),*) => {
        merge!(
            ::libusb::libusb_device_descriptor {
                bLength:            18,
                bDescriptorType:    0x01,
                bcdUSB:             0x0110,
                bDeviceClass:       0,
                bDeviceSubClass:    0,
                bDeviceProtocol:    0,
                bMaxPacketSize0:    16,
                idVendor:           0x1234,
                idProduct:          0x5678,
                bcdDevice:          0x0123,
                iManufacturer:      0,
                iProduct:           0,
                iSerialNumber:      0,
                bNumConfigurations: 1
            } => $($key: $value),*
        )
    }
}
<|endoftext|>


<commit_before>//! A simple parser for a tiny subset of HTML.
//!
//! Can parse basic opening and closing tags, and text nodes.
//!
//! Not yet supported:
//!
//! * Comments
//! * Doctypes and processing instructions
//! * Self-closing tags
//! * Non-well-formed markup
//! * Character entities

use dom;
use std::collections::hashmap::HashMap;

/// Parse an HTML document and return the root element.
pub fn parse(source: String) -> dom::Node {
    let mut nodes = Parser {
        pos: 0u,
        input: source,
    }.parse_nodes();

    // If the document contains a root `<html>` element, just return it. Otherwise, create one.
    let has_root = nodes.len() == 1 && match nodes[0].node_type {
        dom::Element(ref elem) if elem.tag_name.as_slice() == "html" => true,
        _ => false
    };
    if has_root {
        nodes.swap_remove(0).unwrap()
    } else {
        dom::elem("html".to_string(), HashMap::new(), nodes)
    }
}

struct Parser {
    pos: uint,
    input: String,
}

impl Parser {
    /// Parse a sequence of sibling nodes.
    fn parse_nodes(&mut self) -> Vec<dom::Node> {
        let mut nodes = vec!();
        loop {
            self.consume_whitespace();
            if self.eof() || self.starts_with("</") {
                break;
            }
            nodes.push(self.parse_node());
        }
        nodes
    }

    /// Parse a single node.
    fn parse_node(&mut self) -> dom::Node {
        match self.next_char() {
            '<' => self.parse_element(),
            _   => self.parse_text()
        }
    }

    /// Parse a single element, including its open tag, contents, and closing tag.
    fn parse_element(&mut self) -> dom::Node {
        // Opening tag.
        assert!(self.consume_char() == '<');
        let tag_name = self.parse_tag_name();
        let attrs = self.parse_attributes();
        assert!(self.consume_char() == '>');

        // Contents.
        let children = self.parse_nodes();

        // Closing tag.
        assert!(self.consume_char() == '<');
        assert!(self.consume_char() == '/');
        assert!(self.parse_tag_name() == tag_name);
        assert!(self.consume_char() == '>');

        dom::elem(tag_name, attrs, children)
    }

    /// Parse a tag or attribute name.
    fn parse_tag_name(&mut self) -> String {
        self.consume_while(|c| match c {
            'a'..'z' | 'A'..'Z' | '0'..'9' => true,
            _ => false
        })
    }

    /// Parse a list of name="value" pairs, separated by whitespace.
    fn parse_attributes(&mut self) -> dom::AttrMap {
        let mut attributes = HashMap::new();
        loop {
            self.consume_whitespace();
            match self.next_char() {
                '>' => break,
                _ => {
                    let (name, value) = self.parse_attr();
                    attributes.insert(name, value);
                }
            }
        }
        attributes
    }

    /// Parse a single name="value" pair.
    fn parse_attr(&mut self) -> (String, String) {
        let name = self.parse_tag_name();
        assert!(self.consume_char() == '=');
        let value = self.parse_attr_value();
        (name, value)
    }

    /// Parse a quoted value.
    fn parse_attr_value(&mut self) -> String {
        let open_quote = self.consume_char();
        assert!(open_quote == '"' || open_quote == '\'');
        let value = self.consume_while(|c| c != open_quote);
        assert!(self.consume_char() == open_quote);
        value
    }

    /// Parse a text node.
    fn parse_text(&mut self) -> dom::Node {
        dom::text(self.consume_while(|c| c != '<'))
    }

    /// Consume and discard zero or more whitespace characters.
    fn consume_whitespace(&mut self) {
        self.consume_while(|c| c.is_whitespace());
    }

    /// Consume characters until `test` returns false.
    fn consume_while(&mut self, test: |char| -> bool) -> String {
        let mut result = String::new();
        while !self.eof() && test(self.next_char()) {
            result.push_char(self.consume_char());
        }
        result
    }

    /// Return the current character, and advance self.pos to the next character.
    fn consume_char(&mut self) -> char {
        let range = self.input.as_slice().char_range_at(self.pos);
        self.pos = range.next;
        range.ch
    }

    /// Read the current character without consuming it.
    fn next_char(&self) -> char {
        self.input.as_slice().char_at(self.pos)
    }

    /// Does the current input start with the given string?
    fn starts_with(&self, s: &str) -> bool {
        self.input.as_slice().slice_from(self.pos).starts_with(s)
    }

    /// Return true if all input is consumed.
    fn eof(&self) -> bool {
        self.pos >= self.input.len()
    }
}
<commit_msg>Simplify root node creation<commit_after>//! A simple parser for a tiny subset of HTML.
//!
//! Can parse basic opening and closing tags, and text nodes.
//!
//! Not yet supported:
//!
//! * Comments
//! * Doctypes and processing instructions
//! * Self-closing tags
//! * Non-well-formed markup
//! * Character entities

use dom;
use std::collections::hashmap::HashMap;

/// Parse an HTML document and return the root element.
pub fn parse(source: String) -> dom::Node {
    let mut nodes = Parser { pos: 0u, input: source }.parse_nodes();

    // If the document contains a root element, just return it. Otherwise, create one.
    if nodes.len() == 1 {
        nodes.swap_remove(0).unwrap()
    } else {
        dom::elem("html".to_string(), HashMap::new(), nodes)
    }
}

struct Parser {
    pos: uint,
    input: String,
}

impl Parser {
    /// Parse a sequence of sibling nodes.
    fn parse_nodes(&mut self) -> Vec<dom::Node> {
        let mut nodes = vec!();
        loop {
            self.consume_whitespace();
            if self.eof() || self.starts_with("</") {
                break;
            }
            nodes.push(self.parse_node());
        }
        nodes
    }

    /// Parse a single node.
    fn parse_node(&mut self) -> dom::Node {
        match self.next_char() {
            '<' => self.parse_element(),
            _   => self.parse_text()
        }
    }

    /// Parse a single element, including its open tag, contents, and closing tag.
    fn parse_element(&mut self) -> dom::Node {
        // Opening tag.
        assert!(self.consume_char() == '<');
        let tag_name = self.parse_tag_name();
        let attrs = self.parse_attributes();
        assert!(self.consume_char() == '>');

        // Contents.
        let children = self.parse_nodes();

        // Closing tag.
        assert!(self.consume_char() == '<');
        assert!(self.consume_char() == '/');
        assert!(self.parse_tag_name() == tag_name);
        assert!(self.consume_char() == '>');

        dom::elem(tag_name, attrs, children)
    }

    /// Parse a tag or attribute name.
    fn parse_tag_name(&mut self) -> String {
        self.consume_while(|c| match c {
            'a'..'z' | 'A'..'Z' | '0'..'9' => true,
            _ => false
        })
    }

    /// Parse a list of name="value" pairs, separated by whitespace.
    fn parse_attributes(&mut self) -> dom::AttrMap {
        let mut attributes = HashMap::new();
        loop {
            self.consume_whitespace();
            match self.next_char() {
                '>' => break,
                _ => {
                    let (name, value) = self.parse_attr();
                    attributes.insert(name, value);
                }
            }
        }
        attributes
    }

    /// Parse a single name="value" pair.
    fn parse_attr(&mut self) -> (String, String) {
        let name = self.parse_tag_name();
        assert!(self.consume_char() == '=');
        let value = self.parse_attr_value();
        (name, value)
    }

    /// Parse a quoted value.
    fn parse_attr_value(&mut self) -> String {
        let open_quote = self.consume_char();
        assert!(open_quote == '"' || open_quote == '\'');
        let value = self.consume_while(|c| c != open_quote);
        assert!(self.consume_char() == open_quote);
        value
    }

    /// Parse a text node.
    fn parse_text(&mut self) -> dom::Node {
        dom::text(self.consume_while(|c| c != '<'))
    }

    /// Consume and discard zero or more whitespace characters.
    fn consume_whitespace(&mut self) {
        self.consume_while(|c| c.is_whitespace());
    }

    /// Consume characters until `test` returns false.
    fn consume_while(&mut self, test: |char| -> bool) -> String {
        let mut result = String::new();
        while !self.eof() && test(self.next_char()) {
            result.push_char(self.consume_char());
        }
        result
    }

    /// Return the current character, and advance self.pos to the next character.
    fn consume_char(&mut self) -> char {
        let range = self.input.as_slice().char_range_at(self.pos);
        self.pos = range.next;
        range.ch
    }

    /// Read the current character without consuming it.
    fn next_char(&self) -> char {
        self.input.as_slice().char_at(self.pos)
    }

    /// Does the current input start with the given string?
    fn starts_with(&self, s: &str) -> bool {
        self.input.as_slice().slice_from(self.pos).starts_with(s)
    }

    /// Return true if all input is consumed.
    fn eof(&self) -> bool {
        self.pos >= self.input.len()
    }
}
<|endoftext|>


<commit_before>//
//   Copyright 2016 Andrew Hunter
//
//   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.
//

use std::result::*;
use std::rc::*;

use rustc_serialize::*;

use super::treenode::*;
use super::basictree::*;
use super::values::*;

///
/// Encoder that will write to the specified tree node
///
struct TreeNodeEncoder {
    tag:    String,
    value:  TreeValue,
    child:  Option<TreeRef>
}

impl TreeNodeEncoder {
    fn new() -> TreeNodeEncoder {
        TreeNodeEncoder {
            tag:    "".to_string(),
            value:  TreeValue::Nothing,
            child:  None }
    }

    fn to_basic_tree_node_with_sibling(&self, new_sibling: Option<TreeRef>) -> BasicTree {
        let new_node = BasicTree::new(&*self.tag, self.value.to_owned(), self.child.to_owned(), new_sibling);

        new_node
    }
}

#[derive(Debug)]
pub enum TreeNodeCodingError {
    UnsupportedType
}

#[allow(unused_variables)]          // Unused function parameters are quite common due to the way this trait is designed
impl Encoder for TreeNodeEncoder {
    type Error = TreeNodeCodingError;

    fn emit_nil(&mut self) -> Result<(), Self::Error> {
        self.value = TreeValue::Nothing;
        Ok(())
    }

    fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v);
        Ok(())
    }

    fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v as i32);
        Ok(())
    }

    fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v as i32);
        Ok(())
    }

    fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error> {
        self.value = TreeValue::Bool(v);
        Ok(())
    }

    fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error> {
        self.value = TreeValue::Real(v);
        Ok(())
    }

    fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
        self.value = TreeValue::Real(v as f64);
        Ok(())
    }

    fn emit_str(&mut self, v: &str) -> Result<(), Self::Error> {
        self.value = TreeValue::String(v.to_string());
        Ok(())
    }

    fn emit_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        self.value = TreeValue::String(name.to_string());

        f(self)
    }

    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        // Encode the function into a new encoder
        let mut node_encoder = TreeNodeEncoder::new();
        let encoding_result = f(&mut node_encoder);

        node_encoder.tag = f_name.to_string();

        // Short-circuit on error
        if encoding_result.is_err() {
            return encoding_result;
        }

        // Replace the child node with the node generated for the new encoder
        let new_node = node_encoder.to_basic_tree_node_with_sibling(self.child.to_owned());

        // Save the node we just created and update the tree
        self.child = Some(Rc::new(new_node));

        Ok(())
    }

    fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_isize(&mut self, v: isize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_char(&mut self, v: char) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum<F>(&mut self, name: &str, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant_arg<F>(&mut self, a_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_none(&mut self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_some<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_val<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }
}

///
/// Converts an encodable object into a treenode
///
pub fn encode<T: Encodable>(source: &T) -> Result<Rc<TreeNode>, TreeNodeCodingError> {
    // The encoder doesn't directly create a TreeNode because of the way rust lifetimes work
    // (We'd need a <'a> lifetime on the encoder, and that lifetime would prevent recursion by generating
    // new encoders. This is really a limitation of Rust; we work around it by generating the description of
    // a tree node in the encoder and then the tree node itself outside of it)
    //
    // We don't expose the actual encoder publically for this reason, the API is too dumb by necessity.
    let mut encoder = TreeNodeEncoder::new();
    let result = source.encode(&mut encoder);

    result.map(|_| {
        let result: Rc<TreeNode> = Rc::new(encoder.to_basic_tree_node_with_sibling(None));
        result
    })
}

///
/// Marker trait that can be added to types to make them support encoding to a tree node via .to_tree_node()
///
pub trait EncodeToTreeNode {
    // Empty, this is a marker type
}

impl<T: Encodable + EncodeToTreeNode> ToTreeNode for T {
    ///
    /// Converts this value into a tree node
    ///
    fn to_tree_node(&self) -> Rc<TreeNode> {
        encode(self).unwrap()
    }
}

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

    #[derive(RustcEncodable, RustcDecodable)]
    struct Test {
        field1: i32,
        field2: String,
        field3: bool
    }

    // One day this ought to be possible via #[derive]
    impl EncodeToTreeNode for Test { }

    #[test]
    fn encode_struct() {
        let test = Test { field1: 32, field2: "Hi".to_string(), field3: true };
        let encoded = test.to_tree_node();

        assert!(match *encoded.get_child_at("field1").get_value() { TreeValue::Int(ref x) => *x == 32, _ => false });
        assert!(match *encoded.get_child_at("field2").get_value() { TreeValue::String(ref x) => *x == "Hi", _ => false });
        assert!(match *encoded.get_child_at("field3").get_value() { TreeValue::Bool(ref x) => *x == true, _ => false });
    }
}
<commit_msg>Add the EncodeToTreeNode trait to the basic value types<commit_after>//
//   Copyright 2016 Andrew Hunter
//
//   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.
//

use std::result::*;
use std::rc::*;

use rustc_serialize::*;

use super::treenode::*;
use super::basictree::*;
use super::values::*;

///
/// Encoder that will write to the specified tree node
///
struct TreeNodeEncoder {
    tag:    String,
    value:  TreeValue,
    child:  Option<TreeRef>
}

impl TreeNodeEncoder {
    fn new() -> TreeNodeEncoder {
        TreeNodeEncoder {
            tag:    "".to_string(),
            value:  TreeValue::Nothing,
            child:  None }
    }

    fn to_basic_tree_node_with_sibling(&self, new_sibling: Option<TreeRef>) -> BasicTree {
        let new_node = BasicTree::new(&*self.tag, self.value.to_owned(), self.child.to_owned(), new_sibling);

        new_node
    }
}

#[derive(Debug)]
pub enum TreeNodeCodingError {
    UnsupportedType
}

#[allow(unused_variables)]          // Unused function parameters are quite common due to the way this trait is designed
impl Encoder for TreeNodeEncoder {
    type Error = TreeNodeCodingError;

    fn emit_nil(&mut self) -> Result<(), Self::Error> {
        self.value = TreeValue::Nothing;
        Ok(())
    }

    fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v);
        Ok(())
    }

    fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v as i32);
        Ok(())
    }

    fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v as i32);
        Ok(())
    }

    fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error> {
        self.value = TreeValue::Bool(v);
        Ok(())
    }

    fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error> {
        self.value = TreeValue::Real(v);
        Ok(())
    }

    fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
        self.value = TreeValue::Real(v as f64);
        Ok(())
    }

    fn emit_str(&mut self, v: &str) -> Result<(), Self::Error> {
        self.value = TreeValue::String(v.to_string());
        Ok(())
    }

    fn emit_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        self.value = TreeValue::String(name.to_string());

        f(self)
    }

    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        // Encode the function into a new encoder
        let mut node_encoder = TreeNodeEncoder::new();
        let encoding_result = f(&mut node_encoder);

        node_encoder.tag = f_name.to_string();

        // Short-circuit on error
        if encoding_result.is_err() {
            return encoding_result;
        }

        // Replace the child node with the node generated for the new encoder
        let new_node = node_encoder.to_basic_tree_node_with_sibling(self.child.to_owned());

        // Save the node we just created and update the tree
        self.child = Some(Rc::new(new_node));

        Ok(())
    }

    fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_isize(&mut self, v: isize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_char(&mut self, v: char) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum<F>(&mut self, name: &str, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant_arg<F>(&mut self, a_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_none(&mut self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_some<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_val<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }
}

///
/// Converts an encodable object into a treenode
///
pub fn encode<T: Encodable>(source: &T) -> Result<Rc<TreeNode>, TreeNodeCodingError> {
    // The encoder doesn't directly create a TreeNode because of the way rust lifetimes work
    // (We'd need a <'a> lifetime on the encoder, and that lifetime would prevent recursion by generating
    // new encoders. This is really a limitation of Rust; we work around it by generating the description of
    // a tree node in the encoder and then the tree node itself outside of it)
    //
    // We don't expose the actual encoder publically for this reason, the API is too dumb by necessity.
    let mut encoder = TreeNodeEncoder::new();
    let result = source.encode(&mut encoder);

    result.map(|_| {
        let result: Rc<TreeNode> = Rc::new(encoder.to_basic_tree_node_with_sibling(None));
        result
    })
}

///
/// Marker trait that can be added to types to make them support encoding to a tree node via .to_tree_node()
///
pub trait EncodeToTreeNode {
    // Empty, this is a marker type
}

impl EncodeToTreeNode for String {}
impl EncodeToTreeNode for i32 {}
impl EncodeToTreeNode for f64 {}
impl EncodeToTreeNode for Vec<u8> {}

impl<T: Encodable + EncodeToTreeNode> ToTreeNode for T {
    ///
    /// Converts this value into a tree node
    ///
    fn to_tree_node(&self) -> Rc<TreeNode> {
        encode(self).unwrap()
    }
}

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

    #[derive(RustcEncodable, RustcDecodable)]
    struct Test {
        field1: i32,
        field2: String,
        field3: bool
    }

    // One day this ought to be possible via #[derive]
    impl EncodeToTreeNode for Test { }

    #[test]
    fn encode_struct() {
        let test = Test { field1: 32, field2: "Hi".to_string(), field3: true };
        let encoded = test.to_tree_node();

        assert!(match *encoded.get_child_at("field1").get_value() { TreeValue::Int(ref x) => *x == 32, _ => false });
        assert!(match *encoded.get_child_at("field2").get_value() { TreeValue::String(ref x) => *x == "Hi", _ => false });
        assert!(match *encoded.get_child_at("field3").get_value() { TreeValue::Bool(ref x) => *x == true, _ => false });
    }
}
<|endoftext|>


<commit_before>use super::Spawner;

/// A parallel iterator which works by splitting the underlying data
/// and sharing it between threads.
pub trait SplitIterator: Sized {
    /// The item this iterator produces.
    type Item;

    /// The splittable base data which this consists of.
    type Base: Split;

    /// A consumer which can act as an ad-hoc iterator adapter
    /// chain while being shared across threads.
    type Consumer: Consumer<Self::Base, Item=Self::Item>;

    /// Destructure this iterator into a splittable base and
    /// a shareable consumer of that base.
    fn destructure(self) -> (Self::Base, Self::Consumer);

    /// Zip this iterator with another, combining their items
    /// in a tuple.
    fn zip<B: SplitIterator>(self, other: B) -> Zip<Self, B> {
        Zip {
            a: self,
            b: other,
        }
    }

    /// Map the items of this iterator to another type using the supplied function.
    fn map<F: Sync, U>(self, map: F) -> Map<Self, F> where F: Fn(Self::Item) -> U {
        Map {
            parent: self,
            map: map,
        }
    }
}

/// Data which can be split in two at an index.
pub trait Split: Send + IntoIterator {
    /// Whether this should split, returning an index
    /// which would be best.
    fn should_split(&self) -> Option<usize>;

    /// Split the data at the specified index.
    /// Note that this may not always be the same as the index
    /// you return from should_split.
    fn split(self, usize) -> (Self, Self);
}

/// Things that can be turned into a `SplitIterator`.
pub trait IntoSplitIterator {
    /// The item the split iterator will produce.
    type Item;

    /// The iterator this will turn into.
    type SplitIter: SplitIterator<Item=Self::Item>;

    fn into_split_iter(self) -> Self::SplitIter;
}

impl<T: SplitIterator> IntoSplitIterator for T {
    type Item = <Self as SplitIterator>::Item;
    type SplitIter = Self;

    fn into_split_iter(self) -> Self::SplitIter {
        self
    }
}

impl<'a, T: 'a + Sync> IntoSplitIterator for &'a [T] {
    type Item = &'a T;
    type SplitIter = SliceSplit<'a, T>;

    fn into_split_iter(self) -> Self::SplitIter {
        SliceSplit(self)
    }
}

impl<'a, T: 'a + Sync + Send> IntoSplitIterator for &'a mut [T] {
    type Item = &'a mut T;
    type SplitIter = SliceSplitMut<'a, T>;

    fn into_split_iter(self) -> Self::SplitIter {
        SliceSplitMut(self)
    }
}

impl<'a, T: 'a + Sync> IntoSplitIterator for &'a Vec<T> {
    type Item = &'a T;
    type SplitIter = SliceSplit<'a, T>;

    fn into_split_iter(self) -> Self::SplitIter {
        SliceSplit(&self)
    }
}

impl<'a, T: 'a + Sync + Send> IntoSplitIterator for &'a mut Vec<T> {
    type Item = &'a mut T;
    type SplitIter = SliceSplitMut<'a, T>;

    fn into_split_iter(self) -> Self::SplitIter {
        SliceSplitMut(self)
    }
}

/// Used to mask data so that implementations don't conflict.
///
/// Specifically, this is used in the implementation of `SplitIterator`
/// for `Zip`, by hiding the base. This is because `SplitIterator` requires
/// that the base be `Split`. However, for `Split` types, there is a blanket
/// impl for `SplitIterator` for convenience, so if we didn't mask the type,
/// there would be conflicting implementations of `SplitIterator` for `Zip`.
/// This will be obsoleted when specialization becomes stable.
pub struct Hide<T>(T);

/// A split iterator over an immutable slice.
pub struct SliceSplit<'a, T: 'a>(&'a [T]);

/// A split iterator over a mutable slice.
pub struct SliceSplitMut<'a, T: 'a>(&'a mut [T]);

impl<'a, T: 'a> IntoIterator for SliceSplit<'a, T> {
    type Item = <&'a [T] as IntoIterator>::Item;
    type IntoIter = <&'a [T] as IntoIterator>::IntoIter;

    fn into_iter(self) -> Self::IntoIter { self.0.into_iter() }
}

impl<'a, T: 'a> IntoIterator for SliceSplitMut<'a, T> {
    type Item = <&'a mut [T] as IntoIterator>::Item;
    type IntoIter = <&'a mut [T] as IntoIterator>::IntoIter;

    fn into_iter(self) -> Self::IntoIter { self.0.into_iter() }
}

impl<'a, T: 'a + Sync> Split for SliceSplit<'a, T> {
    fn should_split(&self) -> Option<usize> {
        let len = self.0.len();
        if len > 4096 { Some(len / 2) }
        else { None }
    }

    fn split(self, idx: usize) -> (Self, Self) {
        let (a, b) = self.0.split_at(idx);
        (
            SliceSplit(a),
            SliceSplit(b),
        )
    }
}

impl<'a, T: 'a + Sync + Send> Split for SliceSplitMut<'a, T> {
    fn should_split(&self) -> Option<usize> {
        let len = self.0.len();
        if len > 4096 { Some(len / 2) }
        else { None }
    }

    fn split(self, idx: usize) -> (Self, Self) {
        let (a, b) = self.0.split_at_mut(idx);
        (
            SliceSplitMut(a),
            SliceSplitMut(b),
        )
    }
}

pub trait Callback<T>: Sized {
    fn call<I: Iterator<Item=T>>(self, I);
}

impl<F, T> Callback<T> for F where F: FnMut(T) {
    fn call<I: Iterator<Item=T>>(mut self, iter: I) {
        for i in iter {
            (self)(i)
        }
    }
}

pub trait Consumer<In: IntoIterator>: Sync {
    type Item;

    /// Consume the iterator, typically by passing it on to the
    /// parent consumer along with a callback which will receive
    /// a producer of items to transform.
    fn consume<C: Callback<Self::Item>>(&self, i: In, cb: C);
}

impl<In: IntoIterator> Consumer<In> for () {
    type Item = In::Item;

    fn consume<C: Callback<Self::Item>>(&self, i: In, cb: C) {
        cb.call(i.into_iter())
    }
}

impl<T: Split> SplitIterator for T {
    type Item = T::Item;
    type Base = Self;
    type Consumer = ();

    fn destructure(self) -> (Self, ()) {
        (self, ())
    }
}

/// Map iterator adapter.
///
/// This transforms each element into a new object.
pub struct Map<T, F> {
    parent: T,
    map: F,
}

struct MapCallback<C, F> {
    cb: C,
    map: F,
}

impl<Item, C: Callback<U>, F, U> Callback<Item> for MapCallback<C, F>
where F: Fn(Item) -> U {
    fn call<I: Iterator<Item=Item>>(self, iter: I) {
        self.cb.call(iter.map(self.map));
    }
}

impl<In: IntoIterator, T, F: Sync, U> Consumer<In> for Map<T, F>
where T: Consumer<In>, F: Fn(T::Item) -> U {
    type Item = U;

    fn consume<C: Callback<U>>(&self, i: In, cb: C) {
        let callback = MapCallback {
            cb: cb,
            map: &self.map,
        };

        self.parent.consume(i, callback);
    }
}

impl<T: SplitIterator, F: Sync, U> SplitIterator for Map<T, F>
where F: Fn(T::Item) -> U {
    type Item = U;
    type Base = T::Base;
    type Consumer = Map<T::Consumer, F>;

    fn destructure(self) -> (Self::Base, Self::Consumer) {
        let (b, c) = self.parent.destructure();

        (b, Map { parent: c, map: self.map })
    }
}

/// Zip iterator adapter.
///
/// This combines two other iterators into one.
pub struct Zip<A, B> {
    a: A,
    b: B,
}

// Okay, the callback situation gets a little hairy with Zip...
//
// The idea is that a Zip which is a consumer is a Zip combining two
// other consumers. The input is a Zip combining two IntoIterators and
// a callback which wants a zipped iterator of the two consumers' item types.
// The problem is that the callback design only allows for getting an iterator
// from one consumer at a time. So we `consume` the first consumer, passing a callback
// which stores the other consumer along with the iterator that the second consumer
// will eventually consume. On top of that, this callback will store the original
// callback, which is expecting a zipped iterator.
//
// When this callback is called, it will receive an iterator of the first item type along
// with self by-value. Now, remember that self is storing the second consumer,
// the second consumer's argument, and the final callback. So the next step is to
// create one more callback which store the iterator we just received along with the
// final callback. We have the second consumer consume its iterator, and pass this new
// callback to it. When that second callback is called, it will receive an iterator of
// the second item as an argument. At that point, we have an iterator of each item type and the
// final callback all in one place. So we just zip them together, shoot them into the final
// callback, and we're done!
//
// ...there is probably a better way.
struct ZipCallbackA<'a, ConsB: 'a, InB, C> {
    consumer_b: &'a ConsB,
    in_b: InB,
    cb: C
}

struct ZipCallbackB<IterA, C> {
    iter: IterA,
    cb: C,
}

impl<'a, ItemA, InB, ConsB: 'a, C> Callback<ItemA> for ZipCallbackA<'a, ConsB, InB, C>
where ConsB: Consumer<InB>, InB: IntoIterator,
      C: Callback<(ItemA, ConsB::Item)> {
    fn call<I: Iterator<Item=ItemA>>(self, iter: I) {
        // consume B's consumer with a new callback, which stores
        // the iterator we just received.
        let b_cb = ZipCallbackB {
            iter: iter,
            cb: self.cb,
        };

        self.consumer_b.consume(self.in_b, b_cb);
    }
}

impl<ItemA, IterA, C, ItemB> Callback<ItemB> for ZipCallbackB<IterA, C>
where IterA: Iterator<Item=ItemA>, C: Callback<(ItemA, ItemB)> {
    fn call<IterB: Iterator<Item=ItemB>>(self, iter_b: IterB) {
        // we are receiving an iterator for ItemB, and we are storing
        // an iterator for ItemB along with a callback expecting an
        // iterator of (ItemA, ItemB). Let's give it what it wants.
        self.cb.call(self.iter.zip(iter_b));
    }
}

impl<InA, A, InB, B> Consumer<Hide<Zip<InA, InB>>> for Zip<A, B>
where A: Consumer<InA>, B: Consumer<InB>,
      InA: IntoIterator, InB: IntoIterator {
    type Item = (A::Item, B::Item);

    fn consume<C: Callback<Self::Item>>(&self, i: Hide<Zip<InA, InB>>, cb: C) {
        let a_cb = ZipCallbackA {
            consumer_b: &self.b,
            in_b: i.0.b,
            cb: cb,
        };

        self.a.consume(i.0.a, a_cb);
    }
}

impl<A: SplitIterator, B: SplitIterator> SplitIterator for Zip<A, B> {
    type Item = (A::Item, B::Item);
    type Base = Hide<Zip<A::Base, B::Base>>;
    type Consumer = Zip<A::Consumer, B::Consumer>;

    fn destructure(self) -> (Self::Base, Self::Consumer) {
        let (a_b, a_c) = self.a.destructure();
        let (b_b, b_c) = self.b.destructure();

        (
            Hide(Zip { a: a_b, b: b_b }),
            Zip { a: a_c, b: b_c },
        )
    }
}

impl<A: IntoIterator, B: IntoIterator> IntoIterator for Hide<Zip<A, B>> {
    type Item = (A::Item, B::Item);
    type IntoIter = ::std::iter::Zip<A::IntoIter, B::IntoIter>;

    fn into_iter(self) -> Self::IntoIter {
        let z = self.0;
        z.a.into_iter().zip(z.b.into_iter())
    }
}

impl<A: Split, B: Split> Split for Hide<Zip<A, B>> {
    fn should_split(&self) -> Option<usize> {
        let z = &self.0;
        match (z.a.should_split(), z.a.should_split()) {
            (Some(a), Some(b)) => {
                Some(if a > b { b } else { a })
            }
            _ => None
        }
    }

    fn split(self, idx: usize) -> (Self, Self) {
        let z = self.0;
        let (a1, a2) = z.a.split(idx);
        let (b1, b2) = z.b.split(idx);

        (
            Hide(Zip { a: a1, b: b1 }),
            Hide(Zip { a: a2, b: b2 }),
        )
    }
}

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

    #[test]
    fn test1() {
        let v1 = vec![1, 2, 3];
        let v2 = vec![4, 5, 6];

        let s1 = SliceSplit(&v1);
        let s2 = SliceSplit(&v2);

        let diff = 1;
        let i = s1.map(|x| x + diff).zip(s2).map(|(a, b)| a + b);

        let (base, consumer) = i.destructure();
        consumer.consume(base, |x| println!("{:?}", x));
    }
}<commit_msg>Add for_each method on SplitIterator<commit_after>use super::Spawner;

/// A parallel iterator which works by splitting the underlying data
/// and sharing it between threads.
///
/// Functions which consume the iterator will take a `&Spawner` as an argument,
/// so that they can distribute their work in parallel.
pub trait SplitIterator: Sized {
    /// The item this iterator produces.
    type Item;

    /// The splittable base data which this consists of.
    type Base: Split;

    /// A consumer which can act as an ad-hoc iterator adapter
    /// chain while being shared across threads.
    type Consumer: Consumer<Self::Base, Item=Self::Item>;

    /// Destructure this iterator into a splittable base and
    /// a shareable consumer of that base.
    fn destructure(self) -> (Self::Base, Self::Consumer);

    /// Zip this iterator with another, combining their items
    /// in a tuple.
    fn zip<B: SplitIterator>(self, other: B) -> Zip<Self, B> {
        Zip {
            a: self,
            b: other,
        }
    }

    /// Map the items of this iterator to another type using the supplied function.
    fn map<F: Sync, U>(self, map: F) -> Map<Self, F> where F: Fn(Self::Item) -> U {
        Map {
            parent: self,
            map: map,
        }
    }

    /// Consume this iterator, performing an action for each item.
    fn for_each<F: Sync>(self, spawner: &Spawner, f: F) where F: Fn(Self::Item) {
        let (base, consumer) = self.destructure();

        let f = &f;
        consume_helper::<Self, _>((base, &consumer), spawner, &(|base, cons| {
            cons.consume(base, f);
        }))
    }
}

fn consume_helper<T: SplitIterator, F: Sync>(iter: (T::Base, &T::Consumer), spawner: &Spawner, f: &F)
where F: Fn(T::Base, &T::Consumer) {
    let (base, consumer) = iter;
    if let Some(idx) = base.should_split() {
        let (b1, b2) = base.split(idx);
        spawner.join(
            |inner| consume_helper::<T, F>((b1, consumer), inner, f),
            |inner| consume_helper::<T, F>((b2, consumer), inner, f),
        );
    } else {
        f(base, consumer);
    }
}

/// Data which can be split in two at an index.
pub trait Split: Send + IntoIterator {
    /// Whether this should split, returning an index
    /// which would be best.
    fn should_split(&self) -> Option<usize>;

    /// Split the data at the specified index.
    /// Note that this may not always be the same as the index
    /// you return from should_split.
    fn split(self, usize) -> (Self, Self);
}

/// Things that can be turned into a `SplitIterator`.
pub trait IntoSplitIterator {
    /// The item the split iterator will produce.
    type Item;

    /// The iterator this will turn into.
    type SplitIter: SplitIterator<Item=Self::Item>;

    fn into_split_iter(self) -> Self::SplitIter;
}

impl<T: SplitIterator> IntoSplitIterator for T {
    type Item = <Self as SplitIterator>::Item;
    type SplitIter = Self;

    fn into_split_iter(self) -> Self::SplitIter {
        self
    }
}

impl<'a, T: 'a + Sync> IntoSplitIterator for &'a [T] {
    type Item = &'a T;
    type SplitIter = SliceSplit<'a, T>;

    fn into_split_iter(self) -> Self::SplitIter {
        SliceSplit(self)
    }
}

impl<'a, T: 'a + Sync + Send> IntoSplitIterator for &'a mut [T] {
    type Item = &'a mut T;
    type SplitIter = SliceSplitMut<'a, T>;

    fn into_split_iter(self) -> Self::SplitIter {
        SliceSplitMut(self)
    }
}

impl<'a, T: 'a + Sync> IntoSplitIterator for &'a Vec<T> {
    type Item = &'a T;
    type SplitIter = SliceSplit<'a, T>;

    fn into_split_iter(self) -> Self::SplitIter {
        SliceSplit(&self)
    }
}

impl<'a, T: 'a + Sync + Send> IntoSplitIterator for &'a mut Vec<T> {
    type Item = &'a mut T;
    type SplitIter = SliceSplitMut<'a, T>;

    fn into_split_iter(self) -> Self::SplitIter {
        SliceSplitMut(self)
    }
}

/// Used to mask data so that implementations don't conflict.
///
/// Specifically, this is used in the implementation of `SplitIterator`
/// for `Zip`, by hiding the base. This is because `SplitIterator` requires
/// that the base be `Split`. However, for `Split` types, there is a blanket
/// impl for `SplitIterator` for convenience, so if we didn't mask the type,
/// there would be conflicting implementations of `SplitIterator` for `Zip`.
/// This will be obsoleted when specialization becomes stable.
pub struct Hide<T>(T);

/// A split iterator over an immutable slice.
pub struct SliceSplit<'a, T: 'a>(&'a [T]);

/// A split iterator over a mutable slice.
pub struct SliceSplitMut<'a, T: 'a>(&'a mut [T]);

impl<'a, T: 'a> IntoIterator for SliceSplit<'a, T> {
    type Item = <&'a [T] as IntoIterator>::Item;
    type IntoIter = <&'a [T] as IntoIterator>::IntoIter;

    fn into_iter(self) -> Self::IntoIter { self.0.into_iter() }
}

impl<'a, T: 'a> IntoIterator for SliceSplitMut<'a, T> {
    type Item = <&'a mut [T] as IntoIterator>::Item;
    type IntoIter = <&'a mut [T] as IntoIterator>::IntoIter;

    fn into_iter(self) -> Self::IntoIter { self.0.into_iter() }
}

impl<'a, T: 'a + Sync> Split for SliceSplit<'a, T> {
    fn should_split(&self) -> Option<usize> {
        let len = self.0.len();
        if len > 4096 { Some(len / 2) }
        else { None }
    }

    fn split(self, idx: usize) -> (Self, Self) {
        let (a, b) = self.0.split_at(idx);
        (
            SliceSplit(a),
            SliceSplit(b),
        )
    }
}

impl<'a, T: 'a + Sync + Send> Split for SliceSplitMut<'a, T> {
    fn should_split(&self) -> Option<usize> {
        let len = self.0.len();
        if len > 4096 { Some(len / 2) }
        else { None }
    }

    fn split(self, idx: usize) -> (Self, Self) {
        let (a, b) = self.0.split_at_mut(idx);
        (
            SliceSplitMut(a),
            SliceSplitMut(b),
        )
    }
}

pub trait Callback<T>: Sized {
    fn call<I: Iterator<Item=T>>(self, I);
}

impl<F, T> Callback<T> for F where F: FnMut(T) {
    fn call<I: Iterator<Item=T>>(mut self, iter: I) {
        for i in iter {
            (self)(i)
        }
    }
}

pub trait Consumer<In: IntoIterator>: Sync {
    type Item;

    /// Consume the iterator, typically by passing it on to the
    /// parent consumer along with a callback which will receive
    /// a producer of items to transform.
    fn consume<C: Callback<Self::Item>>(&self, i: In, cb: C);
}

impl<In: IntoIterator> Consumer<In> for () {
    type Item = In::Item;

    fn consume<C: Callback<Self::Item>>(&self, i: In, cb: C) {
        cb.call(i.into_iter())
    }
}

impl<T: Split> SplitIterator for T {
    type Item = T::Item;
    type Base = Self;
    type Consumer = ();

    fn destructure(self) -> (Self, ()) {
        (self, ())
    }
}

/// Map iterator adapter.
///
/// This transforms each element into a new object.
pub struct Map<T, F> {
    parent: T,
    map: F,
}

struct MapCallback<C, F> {
    cb: C,
    map: F,
}

impl<Item, C: Callback<U>, F, U> Callback<Item> for MapCallback<C, F>
where F: Fn(Item) -> U {
    fn call<I: Iterator<Item=Item>>(self, iter: I) {
        self.cb.call(iter.map(self.map));
    }
}

impl<In: IntoIterator, T, F: Sync, U> Consumer<In> for Map<T, F>
where T: Consumer<In>, F: Fn(T::Item) -> U {
    type Item = U;

    fn consume<C: Callback<U>>(&self, i: In, cb: C) {
        let callback = MapCallback {
            cb: cb,
            map: &self.map,
        };

        self.parent.consume(i, callback);
    }
}

impl<T: SplitIterator, F: Sync, U> SplitIterator for Map<T, F>
where F: Fn(T::Item) -> U {
    type Item = U;
    type Base = T::Base;
    type Consumer = Map<T::Consumer, F>;

    fn destructure(self) -> (Self::Base, Self::Consumer) {
        let (b, c) = self.parent.destructure();

        (b, Map { parent: c, map: self.map })
    }
}

/// Zip iterator adapter.
///
/// This combines two other iterators into one.
pub struct Zip<A, B> {
    a: A,
    b: B,
}

// Okay, the callback situation gets a little hairy with Zip...
//
// The idea is that a Zip which is a consumer is a Zip combining two
// other consumers. The input is a Zip combining two IntoIterators and
// a callback which wants a zipped iterator of the two consumers' item types.
// The problem is that the callback design only allows for getting an iterator
// from one consumer at a time. So we `consume` the first consumer, passing a callback
// which stores the other consumer along with the iterator that the second consumer
// will eventually consume. On top of that, this callback will store the original
// callback, which is expecting a zipped iterator.
//
// When this callback is called, it will receive an iterator of the first item type along
// with self by-value. Now, remember that self is storing the second consumer,
// the second consumer's argument, and the final callback. So the next step is to
// create one more callback which store the iterator we just received along with the
// final callback. We have the second consumer consume its iterator, and pass this new
// callback to it. When that second callback is called, it will receive an iterator of
// the second item as an argument. At that point, we have an iterator of each item type and the
// final callback all in one place. So we just zip them together, shoot them into the final
// callback, and we're done!
//
// ...there is probably a better way.
struct ZipCallbackA<'a, ConsB: 'a, InB, C> {
    consumer_b: &'a ConsB,
    in_b: InB,
    cb: C
}

struct ZipCallbackB<IterA, C> {
    iter: IterA,
    cb: C,
}

impl<'a, ItemA, InB, ConsB: 'a, C> Callback<ItemA> for ZipCallbackA<'a, ConsB, InB, C>
where ConsB: Consumer<InB>, InB: IntoIterator,
      C: Callback<(ItemA, ConsB::Item)> {
    fn call<I: Iterator<Item=ItemA>>(self, iter: I) {
        // consume B's consumer with a new callback, which stores
        // the iterator we just received.
        let b_cb = ZipCallbackB {
            iter: iter,
            cb: self.cb,
        };

        self.consumer_b.consume(self.in_b, b_cb);
    }
}

impl<ItemA, IterA, C, ItemB> Callback<ItemB> for ZipCallbackB<IterA, C>
where IterA: Iterator<Item=ItemA>, C: Callback<(ItemA, ItemB)> {
    fn call<IterB: Iterator<Item=ItemB>>(self, iter_b: IterB) {
        // we are receiving an iterator for ItemB, and we are storing
        // an iterator for ItemB along with a callback expecting an
        // iterator of (ItemA, ItemB). Let's give it what it wants.
        self.cb.call(self.iter.zip(iter_b));
    }
}

impl<InA, A, InB, B> Consumer<Hide<Zip<InA, InB>>> for Zip<A, B>
where A: Consumer<InA>, B: Consumer<InB>,
      InA: IntoIterator, InB: IntoIterator {
    type Item = (A::Item, B::Item);

    fn consume<C: Callback<Self::Item>>(&self, i: Hide<Zip<InA, InB>>, cb: C) {
        let a_cb = ZipCallbackA {
            consumer_b: &self.b,
            in_b: i.0.b,
            cb: cb,
        };

        self.a.consume(i.0.a, a_cb);
    }
}

impl<A: SplitIterator, B: SplitIterator> SplitIterator for Zip<A, B> {
    type Item = (A::Item, B::Item);
    type Base = Hide<Zip<A::Base, B::Base>>;
    type Consumer = Zip<A::Consumer, B::Consumer>;

    fn destructure(self) -> (Self::Base, Self::Consumer) {
        let (a_b, a_c) = self.a.destructure();
        let (b_b, b_c) = self.b.destructure();

        (
            Hide(Zip { a: a_b, b: b_b }),
            Zip { a: a_c, b: b_c },
        )
    }
}

impl<A: IntoIterator, B: IntoIterator> IntoIterator for Hide<Zip<A, B>> {
    type Item = (A::Item, B::Item);
    type IntoIter = ::std::iter::Zip<A::IntoIter, B::IntoIter>;

    fn into_iter(self) -> Self::IntoIter {
        let z = self.0;
        z.a.into_iter().zip(z.b.into_iter())
    }
}

impl<A: Split, B: Split> Split for Hide<Zip<A, B>> {
    fn should_split(&self) -> Option<usize> {
        let z = &self.0;
        match (z.a.should_split(), z.a.should_split()) {
            (Some(a), Some(b)) => {
                Some(if a > b { b } else { a })
            }
            _ => None
        }
    }

    fn split(self, idx: usize) -> (Self, Self) {
        let z = self.0;
        let (a1, a2) = z.a.split(idx);
        let (b1, b2) = z.b.split(idx);

        (
            Hide(Zip { a: a1, b: b1 }),
            Hide(Zip { a: a2, b: b2 }),
        )
    }
}

#[cfg(test)]
mod tests {
    use ::{make_pool, Pool, IntoSplitIterator, SplitIterator};

    fn pool_harness<F: FnMut(&mut Pool)>(mut f: F) {
        for i in 0..32 {
            let mut pool = make_pool(i).unwrap();
            f(&mut pool);
        }
    }

    #[test]
    fn doubling() {
        let v: Vec<_> = (0..5000).collect();

        pool_harness(|pool| {
            let mut v1 = v.clone();
            (&mut v1).into_split_iter().for_each(&pool.spawner(), |x| *x *= 2);

            assert_eq!(v1, (0..5000).map(|x| x * 2).collect::<Vec<_>>());
        });
    }
}<|endoftext|>


<commit_before>use std::default::Default;
use ::internal::prelude::*;

macro_rules! colour {
    ($struct_:ident; $($name:ident, $val:expr;)*) => {
        impl $struct_ {
            $(
                pub fn $name() -> Colour {
                    Colour::new($val)
                }
            )*
        }
    }
}

/// A utility struct to help with working with the basic representation of a
/// colour. This is particularly useful when working with a [`Role`]'s colour,
/// as the API works with an integer value instead of an RGB value.
///
/// Instances can be created by using the struct's associated functions. These
/// produce presets equivilant to those found in the official client's colour
/// picker.
///
/// # Examples
///
/// Passing in a role's colour, and then retrieving its green component
/// via [`get_g`]:
///
/// ```rust,ignore
/// use serenity::utils::Colour;
///
/// // assuming a `role` has already been bound
///
/// let colour = Colour::new(role.colour);
/// let green = colour.get_g();
///
/// println!("The green component is: {}", green);
/// ```
///
/// Creating an instance with the [`dark_teal`] presets:
///
/// ```rust,ignore
/// use serenity::utils::Colour;
///
/// let colour = Colour::dark_teal();
///
/// assert_eq!(colour.get_tuple(), (17, 128, 106));
/// ```
///
/// [`Role`]: ../model/struct.Role.html
/// [`dark_teal`]: #method.dark_teal
/// [`get_g`]: #method.get_g
#[derive(Clone, Copy, Debug)]
pub struct Colour {
    /// The raw inner integer value of this Colour. This is worked with to
    /// generate values such as the red component value.
    pub value: u32,
}

impl Colour {
    /// Generates a new Colour with the given integer value set.
    pub fn new(value: u32) -> Colour {
        Colour {
            value: value,
        }
    }

    #[doc(hidden)]
    pub fn decode(value: Value) -> Result<Colour> {
        match value {
            Value::U64(v) => Ok(Colour::new(v as u32)),
            Value::I64(v) => Ok(Colour::new(v as u32)),
            other => Err(Error::Decode("Expected valid colour", other)),
        }
    }

    /// Returns the red RGB component of this Colour.
    pub fn get_r(&self) -> u8 {
        ((self.value >> 16) & 255) as u8
    }

    /// Returns the green RGB component of this Colour.
    pub fn get_g(&self) -> u8 {
        ((self.value >> 8) & 255) as u8
    }

    /// Returns the blue RGB component of this Colour.
    pub fn get_b(&self) -> u8 {
        (self.value & 255) as u8
    }

    /// Returns a tuple of the red, green, and blue components of this Colour.
    pub fn get_tuple(&self) -> (u8, u8, u8) {
        (self.get_r(), self.get_g(), self.get_b())
    }
}

impl From<u32> for Colour {
    fn from(value: u32) -> Colour {
        Colour::new(value)
    }
}

impl From<u64> for Colour {
    fn from(value: u64) -> Colour {
        Colour::new(value as u32)
    }
}

colour! {
    Colour;
    blue, 0x3498db;
    dark_blue, 0x206694;
    dark_green, 0x1f8b4c;
    dark_gold, 0xc27c0e;
    dark_grey, 0x607d8b;
    dark_magenta, 0xad1457;
    dark_orange, 0xa84300;
    dark_purple, 0x71368a;
    dark_red, 0x992d22;
    dark_teal, 0x11806a;
    darker_grey, 0x546e7a;
    gold, 0xf1c40f;
    light_grey, 0x979c9f;
    lighter_grey, 0x95a5a6;
    magenta, 0xe91e63;
    orange, 0xe67e22;
    purple, 0x9b59b6;
    red, 0xe74c3c;
    teal, 0x1abc9c;
}

impl Default for Colour {
    fn default() -> Colour {
        Colour {
            value: 0,
        }
    }
}
<commit_msg>Add Colour::from_rgb<commit_after>use std::default::Default;
use ::internal::prelude::*;

macro_rules! colour {
    ($struct_:ident; $($name:ident, $val:expr;)*) => {
        impl $struct_ {
            $(
                pub fn $name() -> Colour {
                    Colour::new($val)
                }
            )*
        }
    }
}

/// A utility struct to help with working with the basic representation of a
/// colour. This is particularly useful when working with a [`Role`]'s colour,
/// as the API works with an integer value instead of an RGB value.
///
/// Instances can be created by using the struct's associated functions. These
/// produce presets equivilant to those found in the official client's colour
/// picker.
///
/// # Examples
///
/// Passing in a role's colour, and then retrieving its green component
/// via [`get_g`]:
///
/// ```rust,ignore
/// use serenity::utils::Colour;
///
/// // assuming a `role` has already been bound
///
/// let colour = Colour::new(role.colour);
/// let green = colour.get_g();
///
/// println!("The green component is: {}", green);
/// ```
///
/// Creating an instance with the [`dark_teal`] presets:
///
/// ```rust,ignore
/// use serenity::utils::Colour;
///
/// let colour = Colour::dark_teal();
///
/// assert_eq!(colour.get_tuple(), (17, 128, 106));
/// ```
///
/// [`Role`]: ../model/struct.Role.html
/// [`dark_teal`]: #method.dark_teal
/// [`get_g`]: #method.get_g
#[derive(Clone, Copy, Debug)]
pub struct Colour {
    /// The raw inner integer value of this Colour. This is worked with to
    /// generate values such as the red component value.
    pub value: u32,
}

impl Colour {
    /// Generates a new Colour with the given integer value set.
    pub fn new(value: u32) -> Colour {
        Colour {
            value: value,
        }
    }

    /// Generates a new Colour from an RGB value, creating an inner u32
    /// representation.
    ///
    /// # Examples
    ///
    /// Creating a `Colour` via its RGB values will set its inner u32 correctly:
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert!(Colour::from_rgb(255, 0, 0).value == 0xFF0000);
    /// assert!(Colour::from_rgb(217, 23, 211).value == 0xD917D3);
    /// ```
    ///
    /// And you can then retrieve those same RGB values via its methods:
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// let colour = Colour::from_rgb(217, 45, 215);
    ///
    /// assert_eq!(colour.get_r(), 217);
    /// assert_eq!(colour.get_g(), 45);
    /// assert_eq!(colour.get_b(), 215);
    /// assert_eq!(colour.get_tuple(), (217, 45, 215));
    /// ```
    pub fn from_rgb(r: u8, g: u8, b: u8) -> Colour {
        let mut uint = r as u32;
        uint = (uint << 8) | (g as u32);
        uint = (uint << 8) | (b as u32);

        Colour::new(uint)
    }

    #[doc(hidden)]
    pub fn decode(value: Value) -> Result<Colour> {
        match value {
            Value::U64(v) => Ok(Colour::new(v as u32)),
            Value::I64(v) => Ok(Colour::new(v as u32)),
            other => Err(Error::Decode("Expected valid colour", other)),
        }
    }

    /// Returns the red RGB component of this Colour.
    pub fn get_r(&self) -> u8 {
        ((self.value >> 16) & 255) as u8
    }

    /// Returns the green RGB component of this Colour.
    pub fn get_g(&self) -> u8 {
        ((self.value >> 8) & 255) as u8
    }

    /// Returns the blue RGB component of this Colour.
    pub fn get_b(&self) -> u8 {
        (self.value & 255) as u8
    }

    /// Returns a tuple of the red, green, and blue components of this Colour.
    pub fn get_tuple(&self) -> (u8, u8, u8) {
        (self.get_r(), self.get_g(), self.get_b())
    }
}

impl From<u32> for Colour {
    fn from(value: u32) -> Colour {
        Colour::new(value)
    }
}

impl From<u64> for Colour {
    fn from(value: u64) -> Colour {
        Colour::new(value as u32)
    }
}

colour! {
    Colour;
    blue, 0x3498db;
    dark_blue, 0x206694;
    dark_green, 0x1f8b4c;
    dark_gold, 0xc27c0e;
    dark_grey, 0x607d8b;
    dark_magenta, 0xad1457;
    dark_orange, 0xa84300;
    dark_purple, 0x71368a;
    dark_red, 0x992d22;
    dark_teal, 0x11806a;
    darker_grey, 0x546e7a;
    gold, 0xf1c40f;
    light_grey, 0x979c9f;
    lighter_grey, 0x95a5a6;
    magenta, 0xe91e63;
    orange, 0xe67e22;
    purple, 0x9b59b6;
    red, 0xe74c3c;
    teal, 0x1abc9c;
}

impl Default for Colour {
    fn default() -> Colour {
        Colour {
            value: 0,
        }
    }
}
<|endoftext|>


<commit_before>use crate::value::de::{MapDeserializer, MapRefDeserializer, SeqDeserializer, SeqRefDeserializer};
use crate::value::Value;
use crate::Error;
use serde::de::value::{BorrowedStrDeserializer, StrDeserializer};
use serde::de::{
    Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error as _, VariantAccess, Visitor,
};
use serde::ser::{Serialize, SerializeMap, Serializer};
use std::cmp::Ordering;
use std::fmt::{self, Debug};
use std::hash::{Hash, Hasher};

/// FIXME
#[derive(Clone)]
pub struct Tag {
    pub(crate) string: String,
}

/// FIXME
#[derive(Clone, PartialEq, PartialOrd, Hash, Debug)]
pub struct TaggedValue {
    /// FIXME
    pub tag: Tag,
    /// FIXME
    pub value: Value,
}

impl Tag {
    /// FIXME
    pub fn new(string: impl Into<String>) -> Self {
        Tag {
            string: string.into(),
        }
    }
}

impl Value {
    pub(crate) fn untag(self) -> Self {
        let mut cur = self;
        while let Value::Tagged(tagged) = cur {
            cur = tagged.value;
        }
        cur
    }

    pub(crate) fn untag_ref(&self) -> &Self {
        let mut cur = self;
        while let Value::Tagged(tagged) = cur {
            cur = &tagged.value;
        }
        cur
    }

    pub(crate) fn untag_mut(&mut self) -> &mut Self {
        let mut cur = self;
        while let Value::Tagged(tagged) = cur {
            cur = &mut tagged.value;
        }
        cur
    }
}

pub(crate) fn nobang(maybe_banged: &str) -> &str {
    maybe_banged.strip_prefix('!').unwrap_or(maybe_banged)
}

impl Eq for Tag {}

impl PartialEq for Tag {
    fn eq(&self, other: &Tag) -> bool {
        PartialEq::eq(nobang(&self.string), nobang(&other.string))
    }
}

impl<T> PartialEq<T> for Tag
where
    T: ?Sized + AsRef<str>,
{
    fn eq(&self, other: &T) -> bool {
        PartialEq::eq(nobang(&self.string), nobang(other.as_ref()))
    }
}

impl Ord for Tag {
    fn cmp(&self, other: &Self) -> Ordering {
        Ord::cmp(nobang(&self.string), nobang(&other.string))
    }
}

impl PartialOrd for Tag {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        PartialOrd::partial_cmp(nobang(&self.string), nobang(&other.string))
    }
}

impl Hash for Tag {
    fn hash<H: Hasher>(&self, hasher: &mut H) {
        nobang(&self.string).hash(hasher);
    }
}

impl Debug for Tag {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "!{}", nobang(&self.string))
    }
}

impl Serialize for TaggedValue {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut map = serializer.serialize_map(Some(1))?;
        map.serialize_entry(&format_args!("!{}", nobang(&self.tag.string)), &self.value)?;
        map.end()
    }
}

impl<'de> EnumAccess<'de> for TaggedValue {
    type Error = Error;
    type Variant = Value;

    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
    where
        V: DeserializeSeed<'de>,
    {
        let tag = StrDeserializer::<Error>::new(nobang(&self.tag.string));
        let value = seed.deserialize(tag)?;
        Ok((value, self.value))
    }
}

impl<'de> VariantAccess<'de> for Value {
    type Error = Error;

    fn unit_variant(self) -> Result<(), Error> {
        Deserialize::deserialize(self)
    }

    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
    where
        T: DeserializeSeed<'de>,
    {
        seed.deserialize(self)
    }

    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Sequence(v) = self {
            Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"tuple variant"))
        }
    }

    fn struct_variant<V>(
        self,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Mapping(v) = self {
            Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"struct variant"))
        }
    }
}

impl<'de> EnumAccess<'de> for &'de TaggedValue {
    type Error = Error;
    type Variant = &'de Value;

    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
    where
        V: DeserializeSeed<'de>,
    {
        let tag = BorrowedStrDeserializer::<Error>::new(nobang(&self.tag.string));
        let value = seed.deserialize(tag)?;
        Ok((value, &self.value))
    }
}

impl<'de> VariantAccess<'de> for &'de Value {
    type Error = Error;

    fn unit_variant(self) -> Result<(), Error> {
        Deserialize::deserialize(self)
    }

    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
    where
        T: DeserializeSeed<'de>,
    {
        seed.deserialize(self)
    }

    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Sequence(v) = self {
            Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"tuple variant"))
        }
    }

    fn struct_variant<V>(
        self,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Mapping(v) = self {
            Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"struct variant"))
        }
    }
}
<commit_msg>Implement Deserialize for TaggedValue<commit_after>use crate::value::de::{MapDeserializer, MapRefDeserializer, SeqDeserializer, SeqRefDeserializer};
use crate::value::Value;
use crate::Error;
use serde::de::value::{BorrowedStrDeserializer, StrDeserializer};
use serde::de::{
    Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error as _, VariantAccess, Visitor,
};
use serde::ser::{Serialize, SerializeMap, Serializer};
use std::cmp::Ordering;
use std::fmt::{self, Debug};
use std::hash::{Hash, Hasher};

/// FIXME
#[derive(Clone)]
pub struct Tag {
    pub(crate) string: String,
}

/// FIXME
#[derive(Clone, PartialEq, PartialOrd, Hash, Debug)]
pub struct TaggedValue {
    /// FIXME
    pub tag: Tag,
    /// FIXME
    pub value: Value,
}

impl Tag {
    /// FIXME
    pub fn new(string: impl Into<String>) -> Self {
        Tag {
            string: string.into(),
        }
    }
}

impl Value {
    pub(crate) fn untag(self) -> Self {
        let mut cur = self;
        while let Value::Tagged(tagged) = cur {
            cur = tagged.value;
        }
        cur
    }

    pub(crate) fn untag_ref(&self) -> &Self {
        let mut cur = self;
        while let Value::Tagged(tagged) = cur {
            cur = &tagged.value;
        }
        cur
    }

    pub(crate) fn untag_mut(&mut self) -> &mut Self {
        let mut cur = self;
        while let Value::Tagged(tagged) = cur {
            cur = &mut tagged.value;
        }
        cur
    }
}

pub(crate) fn nobang(maybe_banged: &str) -> &str {
    maybe_banged.strip_prefix('!').unwrap_or(maybe_banged)
}

impl Eq for Tag {}

impl PartialEq for Tag {
    fn eq(&self, other: &Tag) -> bool {
        PartialEq::eq(nobang(&self.string), nobang(&other.string))
    }
}

impl<T> PartialEq<T> for Tag
where
    T: ?Sized + AsRef<str>,
{
    fn eq(&self, other: &T) -> bool {
        PartialEq::eq(nobang(&self.string), nobang(other.as_ref()))
    }
}

impl Ord for Tag {
    fn cmp(&self, other: &Self) -> Ordering {
        Ord::cmp(nobang(&self.string), nobang(&other.string))
    }
}

impl PartialOrd for Tag {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        PartialOrd::partial_cmp(nobang(&self.string), nobang(&other.string))
    }
}

impl Hash for Tag {
    fn hash<H: Hasher>(&self, hasher: &mut H) {
        nobang(&self.string).hash(hasher);
    }
}

impl Debug for Tag {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "!{}", nobang(&self.string))
    }
}

impl Serialize for TaggedValue {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut map = serializer.serialize_map(Some(1))?;
        map.serialize_entry(&format_args!("!{}", nobang(&self.tag.string)), &self.value)?;
        map.end()
    }
}

impl<'de> Deserialize<'de> for TaggedValue {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct TaggedValueVisitor;

        impl<'de> Visitor<'de> for TaggedValueVisitor {
            type Value = TaggedValue;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("a YAML value with a !Tag")
            }

            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
            where
                A: EnumAccess<'de>,
            {
                let (tag, contents) = data.variant::<String>()?;
                let tag = Tag::new(tag);
                let value = contents.newtype_variant()?;
                Ok(TaggedValue { tag, value })
            }
        }

        deserializer.deserialize_any(TaggedValueVisitor)
    }
}

impl<'de> EnumAccess<'de> for TaggedValue {
    type Error = Error;
    type Variant = Value;

    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
    where
        V: DeserializeSeed<'de>,
    {
        let tag = StrDeserializer::<Error>::new(nobang(&self.tag.string));
        let value = seed.deserialize(tag)?;
        Ok((value, self.value))
    }
}

impl<'de> VariantAccess<'de> for Value {
    type Error = Error;

    fn unit_variant(self) -> Result<(), Error> {
        Deserialize::deserialize(self)
    }

    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
    where
        T: DeserializeSeed<'de>,
    {
        seed.deserialize(self)
    }

    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Sequence(v) = self {
            Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"tuple variant"))
        }
    }

    fn struct_variant<V>(
        self,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Mapping(v) = self {
            Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"struct variant"))
        }
    }
}

impl<'de> EnumAccess<'de> for &'de TaggedValue {
    type Error = Error;
    type Variant = &'de Value;

    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
    where
        V: DeserializeSeed<'de>,
    {
        let tag = BorrowedStrDeserializer::<Error>::new(nobang(&self.tag.string));
        let value = seed.deserialize(tag)?;
        Ok((value, &self.value))
    }
}

impl<'de> VariantAccess<'de> for &'de Value {
    type Error = Error;

    fn unit_variant(self) -> Result<(), Error> {
        Deserialize::deserialize(self)
    }

    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
    where
        T: DeserializeSeed<'de>,
    {
        seed.deserialize(self)
    }

    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Sequence(v) = self {
            Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"tuple variant"))
        }
    }

    fn struct_variant<V>(
        self,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Mapping(v) = self {
            Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"struct variant"))
        }
    }
}
<|endoftext|>