<commit_before>// Copyright 2016 Serde YAML 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. This file may not be copied, modified, or distributed
// except according to those terms.

//! YAML Serialization
//!
//! This module provides YAML serialization with the type `Serializer`.

use std::fmt;
use std::io;

use yaml_rust::{Yaml, YamlEmitter};
use yaml_rust::yaml;

use serde::ser;

use super::error::{Error, Result};

/// A structure for serializing a Rust value into a YAML value.
pub struct Serializer {
    /// The YAML value to hold the result.
    doc: Yaml,
}

impl Serializer {
    pub fn new() -> Self {
        Serializer {
            doc: Yaml::Null,
        }
    }
    pub fn take(self) -> Yaml {
        self.doc
    }
}

impl ser::Serializer for Serializer {
    type Error = Error;
    type SeqState = ();
    type TupleState = ();
    type TupleStructState = ();
    type TupleVariantState = &'static str;
    type MapState = ();
    type StructState = ();
    type StructVariantState = &'static str;

    fn serialize_bool(&mut self, v: bool) -> Result<()> {
        self.doc = Yaml::Boolean(v);
        Ok(())
    }

    fn serialize_isize(&mut self, v: isize) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_usize(&mut self, v: usize) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_i8(&mut self, v: i8) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_u8(&mut self, v: u8) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_i16(&mut self, v: i16) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_u16(&mut self, v: u16) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_i32(&mut self, v: i32) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_u32(&mut self, v: u32) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_i64(&mut self, v: i64) -> Result<()> {
        self.doc = Yaml::Integer(v);
        Ok(())
    }

    fn serialize_u64(&mut self, v: u64) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_f64(&mut self, v: f64) -> Result<()> {
        self.doc = Yaml::Real(v.to_string());
        Ok(())
    }

    fn serialize_f32(&mut self, v: f32) -> Result<()> {
        self.doc = Yaml::Real(v.to_string());
        Ok(())
    }

    fn serialize_char(&mut self, value: char) -> Result<()> {
        self.doc = Yaml::String(value.to_string());
        Ok(())
    }

    fn serialize_str(&mut self, value: &str) -> Result<()> {
        self.doc = Yaml::String(String::from(value));
        Ok(())
    }

    fn serialize_unit(&mut self) -> Result<()> {
        self.doc = Yaml::Null;
        Ok(())
    }

    fn serialize_unit_struct(&mut self, _name: &'static str) -> Result<()> {
        self.doc = Yaml::Null;
        Ok(())
    }

    fn serialize_none(&mut self) -> Result<()> {
        self.serialize_unit()
    }

    fn serialize_some<V>(&mut self, value: V) -> Result<()>
        where V: ser::Serialize,
    {
        value.serialize(self)
    }

    fn serialize_seq_fixed_size(&mut self, len: usize) -> Result<()> {
        self.serialize_seq(Some(len))
    }

    fn serialize_seq(&mut self, len: Option<usize>) -> Result<()> {
        let vec = match len {
            None => yaml::Array::new(),
            Some(len) => yaml::Array::with_capacity(len),
        };
        self.doc = Yaml::Array(vec);
        Ok(())
    }

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

    fn serialize_seq_elt<T>(&mut self, _: &mut(), elem: T) -> Result<()>
        where T: ser::Serialize,
    {
        if let Yaml::Array(ref mut vec) = self.doc {
            vec.push(try!(to_yaml(elem)));
        } else {
            panic!("bad call to serialize_seq_elt");
        }
        Ok(())
    }

    fn serialize_tuple(&mut self, len: usize) -> Result<()> {
        self.serialize_seq(Some(len))
    }

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

    fn serialize_tuple_elt<T>(&mut self, state: &mut(), elem: T) -> Result<()>
        where T: ser::Serialize,
    {
        self.serialize_seq_elt(state, elem)
    }

    fn serialize_map(&mut self, _len: Option<usize>) -> Result<()>
    {
        self.doc = Yaml::Hash(yaml::Hash::new());
        Ok(())
    }

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

    fn serialize_map_elt<K, V>(&mut self, _: &mut (), key: K, value: V) -> Result<()>
        where K: ser::Serialize,
              V: ser::Serialize,
    {
        if let Yaml::Hash(ref mut map) = self.doc {
            map.insert(try!(to_yaml(key)), try!(to_yaml(value)));
        } else {
            panic!("bad call to serialize_map_elt");
        }
        Ok(())
    }

    fn serialize_struct(&mut self, _name: &'static str, len: usize) -> Result<()>
    {
        self.serialize_map(Some(len))
    }

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

    fn serialize_struct_elt<V>(&mut self, state: &mut (), key: &'static str, value: V) -> Result<()>
        where V: ser::Serialize,
    {
        self.serialize_map_elt(state, key, value)
    }

    fn serialize_tuple_struct(&mut self, _name: &'static str, len: usize) -> Result<()>
    {
        self.serialize_tuple(len)
    }

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

    fn serialize_tuple_struct_elt<V>(&mut self, state: &mut (), value: V) -> Result<()>
        where V: ser::Serialize,
    {
        self.serialize_tuple_elt(state, value)
    }

    fn serialize_unit_variant(
        &mut self,
        _name: &str,
        _variant_index: usize,
        variant: &str
    ) -> Result<()> {
        self.doc = Yaml::String(String::from(variant));
        Ok(())
    }

    /// Override `serialize_newtype_struct` to serialize newtypes without an object wrapper.
    fn serialize_newtype_struct<T>(
        &mut self,
        _name: &'static str,
        value: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        value.serialize(self)
    }

    fn serialize_newtype_variant<T>(
        &mut self,
        _name: &str,
        _variant_index: usize,
        variant: &str,
        value: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        self.doc = singleton_hash(try!(to_yaml(variant)),
                                   try!(to_yaml(value)));
        Ok(())
    }

    fn serialize_tuple_variant(
        &mut self,
        _enum: &'static str,
        _idx: usize,
        variant: &'static str,
        len: usize,
    ) -> Result<&'static str> {
        try!(self.serialize_tuple(len));
        Ok(variant)
    }

    fn serialize_tuple_variant_elt<V: ser::Serialize>(&mut self, _: &mut &'static str, v: V) -> Result<()> {
        self.serialize_tuple_elt(&mut (), v)
    }

    fn serialize_tuple_variant_end(
        &mut self,
        variant: &'static str,
    ) -> Result<()> {
        self.doc = singleton_hash(try!(to_yaml(variant)), ::std::mem::replace(&mut self.doc, Yaml::Null));
        Ok(())
    }

    fn serialize_struct_variant(
        &mut self,
        _enum: &'static str,
        _idx: usize,
        variant: &'static str,
        len: usize,
    ) -> Result<&'static str> {
        try!(self.serialize_struct(variant, len));
        Ok(variant)
    }

    fn serialize_struct_variant_elt<V: ser::Serialize>(&mut self, _: &mut &'static str, field: &'static str, v: V) -> Result<()> {
        self.serialize_struct_elt(&mut (), field, v)
    }

    fn serialize_struct_variant_end(
        &mut self,
        variant: &'static str,
    ) -> Result<()> {
        self.doc = singleton_hash(try!(to_yaml(variant)), ::std::mem::replace(&mut self.doc, Yaml::Null));
        Ok(())
    }

    fn serialize_bytes(&mut self, value: &[u8]) -> Result<()> {
        let mut state = try!(self.serialize_seq(Some(value.len())));
        for c in value {
            try!(self.serialize_seq_elt(&mut state, c));
        }
        self.serialize_seq_end(state)
    }
}

pub fn to_writer<W, T>(writer: &mut W, value: &T) -> Result<()>
    where W: io::Write,
          T: ser::Serialize,
{
    let doc = try!(to_yaml(value));
    let mut writer_adapter = FmtToIoWriter {
        writer: writer,
    };
    try!(YamlEmitter::new(&mut writer_adapter).dump(&doc));
    Ok(())
}

pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
    where T: ser::Serialize,
{
    let mut vec = Vec::with_capacity(128);
    try!(to_writer(&mut vec, value));
    Ok(vec)
}

pub fn to_string<T>(value: &T) -> Result<String>
    where T: ser::Serialize,
{
    Ok(try!(String::from_utf8(try!(to_vec(value)))))
}

/// The yaml-rust library uses `fmt.Write` intead of `io.Write` so this is a
/// simple adapter.
struct FmtToIoWriter<'a, W>
    where W: io::Write + 'a,
{
    writer: &'a mut W,
}

impl<'a, W> fmt::Write for FmtToIoWriter<'a, W>
    where W: io::Write + 'a,
{
    fn write_str(&mut self, s: &str) -> fmt::Result {
        if self.writer.write(s.as_bytes()).is_err() {
            return Err(fmt::Error);
        }
        if self.writer.flush().is_err() {
            return Err(fmt::Error);
        }
        Ok(())
    }
}

fn to_yaml<T>(elem: T) -> Result<Yaml>
    where T: ser::Serialize,
{
    let mut ser = Serializer::new();
    try!(elem.serialize(&mut ser));
    Ok(ser.take())
}

fn singleton_hash(k: Yaml, v: Yaml) -> Yaml {
    let mut hash = yaml::Hash::new();
    hash.insert(k, v);
    Yaml::Hash(hash)
}
<commit_msg>Sort Serializer methods in the trait's order<commit_after>// Copyright 2016 Serde YAML 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. This file may not be copied, modified, or distributed
// except according to those terms.

//! YAML Serialization
//!
//! This module provides YAML serialization with the type `Serializer`.

use std::fmt;
use std::io;

use yaml_rust::{Yaml, YamlEmitter};
use yaml_rust::yaml;

use serde::ser;

use super::error::{Error, Result};

/// A structure for serializing a Rust value into a YAML value.
pub struct Serializer {
    /// The YAML value to hold the result.
    doc: Yaml,
}

impl Serializer {
    pub fn new() -> Self {
        Serializer {
            doc: Yaml::Null,
        }
    }

    pub fn take(self) -> Yaml {
        self.doc
    }
}

impl ser::Serializer for Serializer {
    type Error = Error;
    type SeqState = ();
    type TupleState = ();
    type TupleStructState = ();
    type TupleVariantState = &'static str;
    type MapState = ();
    type StructState = ();
    type StructVariantState = &'static str;

    fn serialize_bool(&mut self, v: bool) -> Result<()> {
        self.doc = Yaml::Boolean(v);
        Ok(())
    }

    fn serialize_isize(&mut self, v: isize) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i8(&mut self, v: i8) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i16(&mut self, v: i16) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i32(&mut self, v: i32) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i64(&mut self, v: i64) -> Result<()> {
        self.doc = Yaml::Integer(v);
        Ok(())
    }

    fn serialize_usize(&mut self, v: usize) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u8(&mut self, v: u8) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u16(&mut self, v: u16) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u32(&mut self, v: u32) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u64(&mut self, v: u64) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_f32(&mut self, v: f32) -> Result<()> {
        self.doc = Yaml::Real(v.to_string());
        Ok(())
    }

    fn serialize_f64(&mut self, v: f64) -> Result<()> {
        self.doc = Yaml::Real(v.to_string());
        Ok(())
    }

    fn serialize_char(&mut self, value: char) -> Result<()> {
        self.doc = Yaml::String(value.to_string());
        Ok(())
    }

    fn serialize_str(&mut self, value: &str) -> Result<()> {
        self.doc = Yaml::String(String::from(value));
        Ok(())
    }

    fn serialize_bytes(&mut self, value: &[u8]) -> Result<()> {
        let mut state = try!(self.serialize_seq(Some(value.len())));
        for c in value {
            try!(self.serialize_seq_elt(&mut state, c));
        }
        self.serialize_seq_end(state)
    }

    fn serialize_unit(&mut self) -> Result<()> {
        self.doc = Yaml::Null;
        Ok(())
    }

    fn serialize_unit_struct(&mut self, _name: &'static str) -> Result<()> {
        self.doc = Yaml::Null;
        Ok(())
    }

    fn serialize_unit_variant(
        &mut self,
        _name: &str,
        _variant_index: usize,
        variant: &str
    ) -> Result<()> {
        self.doc = Yaml::String(String::from(variant));
        Ok(())
    }

    fn serialize_newtype_struct<T>(
        &mut self,
        _name: &'static str,
        value: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        value.serialize(self)
    }

    fn serialize_newtype_variant<T>(
        &mut self,
        _name: &str,
        _variant_index: usize,
        variant: &str,
        value: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        self.doc = singleton_hash(try!(to_yaml(variant)),
                                  try!(to_yaml(value)));
        Ok(())
    }

    fn serialize_none(&mut self) -> Result<()> {
        self.serialize_unit()
    }

    fn serialize_some<V>(&mut self, value: V) -> Result<()>
        where V: ser::Serialize,
    {
        value.serialize(self)
    }

    fn serialize_seq(&mut self, len: Option<usize>) -> Result<()> {
        let vec = match len {
            None => yaml::Array::new(),
            Some(len) => yaml::Array::with_capacity(len),
        };
        self.doc = Yaml::Array(vec);
        Ok(())
    }

    fn serialize_seq_elt<T>(&mut self, _state: &mut(), elem: T) -> Result<()>
        where T: ser::Serialize,
    {
        if let Yaml::Array(ref mut vec) = self.doc {
            vec.push(try!(to_yaml(elem)));
        } else {
            panic!("bad call to serialize_seq_elt");
        }
        Ok(())
    }

    fn serialize_seq_end(&mut self, _state: ()) -> Result<()> {
        Ok(())
    }

    fn serialize_seq_fixed_size(&mut self, len: usize) -> Result<()> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple(&mut self, len: usize) -> Result<()> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple_elt<T>(&mut self, state: &mut(), elem: T) -> Result<()>
        where T: ser::Serialize,
    {
        self.serialize_seq_elt(state, elem)
    }

    fn serialize_tuple_end(&mut self, _state: ()) -> Result<()> {
        Ok(())
    }

    fn serialize_tuple_struct(&mut self, _name: &'static str, len: usize) -> Result<()>
    {
        self.serialize_tuple(len)
    }

    fn serialize_tuple_struct_elt<V>(&mut self, state: &mut (), value: V) -> Result<()>
        where V: ser::Serialize,
    {
        self.serialize_tuple_elt(state, value)
    }

    fn serialize_tuple_struct_end(&mut self, _state: ()) -> Result<()> {
        Ok(())
    }

    fn serialize_tuple_variant(
        &mut self,
        _enum: &'static str,
        _idx: usize,
        variant: &'static str,
        len: usize,
    ) -> Result<&'static str> {
        try!(self.serialize_tuple(len));
        Ok(variant)
    }

    fn serialize_tuple_variant_elt<V: ser::Serialize>(&mut self, _state: &mut &'static str, v: V) -> Result<()> {
        self.serialize_tuple_elt(&mut (), v)
    }

    fn serialize_tuple_variant_end(
        &mut self,
        variant: &'static str,
    ) -> Result<()> {
        self.doc = singleton_hash(try!(to_yaml(variant)), ::std::mem::replace(&mut self.doc, Yaml::Null));
        Ok(())
    }

    fn serialize_map(&mut self, _len: Option<usize>) -> Result<()>
    {
        self.doc = Yaml::Hash(yaml::Hash::new());
        Ok(())
    }

    fn serialize_map_elt<K, V>(&mut self, _state: &mut (), key: K, value: V) -> Result<()>
        where K: ser::Serialize,
              V: ser::Serialize,
    {
        if let Yaml::Hash(ref mut map) = self.doc {
            map.insert(try!(to_yaml(key)), try!(to_yaml(value)));
        } else {
            panic!("bad call to serialize_map_elt");
        }
        Ok(())
    }

    fn serialize_map_end(&mut self, _state: ()) -> Result<()> {
        Ok(())
    }

    fn serialize_struct(&mut self, _name: &'static str, len: usize) -> Result<()>
    {
        self.serialize_map(Some(len))
    }

    fn serialize_struct_elt<V>(&mut self, state: &mut (), key: &'static str, value: V) -> Result<()>
        where V: ser::Serialize,
    {
        self.serialize_map_elt(state, key, value)
    }

    fn serialize_struct_end(&mut self, _state: ()) -> Result<()> {
        Ok(())
    }

    fn serialize_struct_variant(
        &mut self,
        _enum: &'static str,
        _idx: usize,
        variant: &'static str,
        len: usize,
    ) -> Result<&'static str> {
        try!(self.serialize_struct(variant, len));
        Ok(variant)
    }

    fn serialize_struct_variant_elt<V: ser::Serialize>(&mut self, _state: &mut &'static str, field: &'static str, v: V) -> Result<()> {
        self.serialize_struct_elt(&mut (), field, v)
    }

    fn serialize_struct_variant_end(
        &mut self,
        variant: &'static str,
    ) -> Result<()> {
        self.doc = singleton_hash(try!(to_yaml(variant)), ::std::mem::replace(&mut self.doc, Yaml::Null));
        Ok(())
    }
}

pub fn to_writer<W, T>(writer: &mut W, value: &T) -> Result<()>
    where W: io::Write,
          T: ser::Serialize,
{
    let doc = try!(to_yaml(value));
    let mut writer_adapter = FmtToIoWriter {
        writer: writer,
    };
    try!(YamlEmitter::new(&mut writer_adapter).dump(&doc));
    Ok(())
}

pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
    where T: ser::Serialize,
{
    let mut vec = Vec::with_capacity(128);
    try!(to_writer(&mut vec, value));
    Ok(vec)
}

pub fn to_string<T>(value: &T) -> Result<String>
    where T: ser::Serialize,
{
    Ok(try!(String::from_utf8(try!(to_vec(value)))))
}

/// The yaml-rust library uses `fmt.Write` intead of `io.Write` so this is a
/// simple adapter.
struct FmtToIoWriter<'a, W>
    where W: io::Write + 'a,
{
    writer: &'a mut W,
}

impl<'a, W> fmt::Write for FmtToIoWriter<'a, W>
    where W: io::Write + 'a,
{
    fn write_str(&mut self, s: &str) -> fmt::Result {
        if self.writer.write(s.as_bytes()).is_err() {
            return Err(fmt::Error);
        }
        if self.writer.flush().is_err() {
            return Err(fmt::Error);
        }
        Ok(())
    }
}

fn to_yaml<T>(elem: T) -> Result<Yaml>
    where T: ser::Serialize,
{
    let mut ser = Serializer::new();
    try!(elem.serialize(&mut ser));
    Ok(ser.take())
}

fn singleton_hash(k: Yaml, v: Yaml) -> Yaml {
    let mut hash = yaml::Hash::new();
    hash.insert(k, v);
    Yaml::Hash(hash)
}
<|endoftext|>


<commit_before>use std::ptr;
use std::mem;
use std::cmp::{max, Ordering};
use std::fmt::{Debug, Formatter};
use delete_range::{DeleteRange, DeleteRangeCache, TraversalDriver, TraversalDecision};

pub trait Item: Sized+Clone {
    type Key: Ord;

    fn ord(&self) -> Self::Key;
}

impl Item for usize {
    type Key = usize;

    fn ord(&self) -> Self::Key {
        *self
    }
}

#[derive(Debug, Clone)]
pub struct Node<T: Item> {
    pub item: Option<T>,
}

/// A fast way to refill the tree from a master copy; adds the requirement for T to implement Copy.
pub trait TeardownTreeRefill<T: Copy+Item> {
    fn refill(&mut self, master: &TeardownTree<T>);
}

impl<T: Copy+Item> TeardownTreeRefill<T> for TeardownTree<T> {
    fn refill(&mut self, master: &TeardownTree<T>) {
        let len = self.data.len();
        debug_assert!(len == master.data.len());
        self.data.truncate(0);
        unsafe {
            ptr::copy_nonoverlapping(master.data.as_ptr(), self.data.as_mut_ptr(), len);
            self.data.set_len(len);
        }
        self.size = master.size;
    }
}

pub struct DriverFromTo {
    from: usize,
    to: usize
}

impl DriverFromTo {
    pub fn new(from: usize, to: usize) -> DriverFromTo {
        DriverFromTo { from:from, to:to }
    }
}

impl TraversalDriver<usize> for DriverFromTo {
    #[inline(always)]
    fn decide(&self, x: &usize) -> TraversalDecision {
        let left = self.from <= *x;
        let right = *x <= self.to;

        TraversalDecision { left: left, right: right }
    }
}

#[derive(Clone)]
pub struct TeardownTree<T: Item> {
    data: Vec<Node<T>>,
    size: usize,

    pub delete_range_cache: Option<DeleteRangeCache<T>>,
}

impl<T: Item> TeardownTree<T> {
    pub fn new(sorted: Vec<T>) -> TeardownTree<T> {
        let size = sorted.len();

        let capacity = size;

        let mut data = Vec::with_capacity(capacity);
        for _ in 0..capacity {
            data.push(Node{item: None});
        }

        let mut sorted: Vec<Option<T>> = sorted.into_iter().map(|x| Some(x)).collect();
        let height = Self::build(&mut sorted, 0, &mut data);
        debug_assert!({ // we assert that the tree is nearly complete
            data.iter().take(sorted.len()).filter(|x| x.item.is_none()).count() == 0
        });
        let cache = DeleteRangeCache::new(height);
        TeardownTree { data: data, size: size, delete_range_cache: Some(cache) }
    }

    pub fn with_nodes(nodes: Vec<Node<T>>) -> TeardownTree<T> {
        let size = nodes.iter().filter(|x| x.item.is_some()).count();
        let height = Self::calc_height(&nodes, 0);
        let capacity = Self::row_start(nodes.len())*4 + 3; // allocate enough nodes that righti() is never out of bounds

        let mut data = Vec::with_capacity(capacity);
        for _ in 0..capacity {
            data.push(Node{item: None});
        }

        unsafe {
            ptr::copy_nonoverlapping(nodes.as_ptr(), data.as_mut_ptr(), nodes.len());
        }
        ::std::mem::forget(nodes);

        let cache = DeleteRangeCache::new(height);
        TeardownTree { data: data, size: size, delete_range_cache: Some(cache) }
    }

    pub fn into_node_vec(self) -> Vec<Node<T>> {
        self.data
    }

    fn calc_height(nodes: &Vec<Node<T>>, idx: usize) -> usize {
        if idx < nodes.len() && nodes[idx].item.is_some() {
            1 + max(Self::calc_height(nodes, Self::lefti(idx)),
                    Self::calc_height(nodes, Self::righti(idx)))
        } else {
            0
        }
    }

    /// finds the point to partition n keys for a nearly-complete binary tree
    /// http://stackoverflow.com/a/26896494/3646645
    fn build_select_root(n: usize) -> usize {
        // the highest power of two <= n
        let x = if n.is_power_of_two() { n }
                else { n.next_power_of_two() / 2 };

        if x/2 <= (n-x) + 1 {
            debug_assert!(x >= 1, "x={}, n={}", x, n);
            x - 1
        } else {
            n - x / 2
        }
    }

    /// returns the height of the tree
    fn build(sorted: &mut [Option<T>], idx: usize, data: &mut [Node<T>]) -> usize {
        match sorted.len() {
            0 => 0,
            n => {
                let mid = Self::build_select_root(n);
                let (lefti, righti) = (Self::lefti(idx), Self::righti(idx));
                let lh = Self::build(&mut sorted[..mid], lefti, data);
                let rh = Self::build(&mut sorted[mid+1..], righti, data);

                data[idx] = Node { item: sorted[mid].take() };
                debug_assert!(rh <= lh);
                1 + lh
            }
        }
    }

    pub fn len(&self) -> usize {
        self.data.len()
    }

    pub fn delete_range<D: TraversalDriver<T>>(&mut self, drv: &mut D, output: &mut Vec<T>) {
        debug_assert!(output.is_empty());
        output.truncate(0);
        {
            DeleteRange::new(self, output).delete_range(drv);
            debug_assert!({
                let cache: DeleteRangeCache<T> = self.delete_range_cache.take().unwrap();
                let ok = cache.slots_min.is_empty() && cache.slots_max.is_empty() && cache.delete_subtree_stack.is_empty();
                self.delete_range_cache = Some(cache);
                ok
            });
        }
        self.size -= output.len();
    }

    #[inline(always)]
    pub fn node(&self, idx: usize) -> &Node<T> {
        &self.data[idx]
    }

    #[inline(always)]
    pub fn node_mut(&mut self, idx: usize) -> &mut Node<T> {
        &mut self.data[idx]
    }

    #[inline(always)]
    fn node_mut_unsafe<'b>(&mut self, idx: usize) -> &'b mut Node<T> {
        unsafe {
            mem::transmute(&mut self.data[idx])
        }
    }

    pub fn item_mut_unwrap(&mut self, idx: usize) -> &mut T {
        self.node_mut(idx).item.as_mut().unwrap()
    }

    pub fn delete(&mut self, search: &T) -> bool {
        let mut idx = 0;
        if idx >= self.data.len() {
            return false;
        }

        let mut ord =
            if let Some(ref it) = self.node_mut_unsafe(idx).item {
                it.ord()
            } else {
                return false;
            };

        loop {
            let ordering = search.ord().cmp(&ord);

            idx = match ordering {
                Ordering::Equal   => {
                    self.size -= 1;
                    self.delete_idx(idx);
                    return true
                },
                Ordering::Less    => Self::lefti(idx),
                Ordering::Greater => Self::righti(idx),
            };

            if idx >= self.data.len() {
                return false;
            }

            if let Some(ref it) = self.node_mut_unsafe(idx).item {
                ord = it.ord();
            } else {
                return false;
            }
        }
    }

    #[inline]
    fn delete_idx(&mut self, idx: usize) -> T {
        debug_assert!(!self.is_null(idx));

        match (self.has_left(idx), self.has_right(idx)) {
            (false, false) => {
                let root = self.node_mut(idx);
                root.item.take().unwrap()
            },

            (true, false)  => {
                let left_max = self.delete_max(Self::lefti(idx));
                mem::replace(self.item_mut_unwrap(idx), left_max)
            },

            (false, true)  => {
                let right_min = self.delete_min(Self::righti(idx));
                mem::replace(self.item_mut_unwrap(idx), right_min)
            },

            (true, true)   => {
                let left_max = self.delete_max(Self::lefti(idx));
                mem::replace(self.item_mut_unwrap(idx), left_max)
            },
        }
    }

    #[inline]
    fn delete_max(&mut self, mut idx: usize) -> T {
        while self.has_right(idx) {
            idx = Self::righti(idx);
        }

        if self.has_left(idx) {
            let left_max = self.delete_max(Self::lefti(idx));
            mem::replace(self.item_mut_unwrap(idx), left_max)
        } else {
            let root = self.node_mut(idx);
            root.item.take().unwrap()
        }
    }

    #[inline]
    fn delete_min(&mut self, mut idx: usize) -> T {
        while self.has_left(idx) {
            idx = Self::lefti(idx);
        }

        if self.has_right(idx) {
            let right_min = self.delete_min(Self::righti(idx));
            mem::replace(self.item_mut_unwrap(idx), right_min)
        } else {
            let root = self.node_mut(idx);
            root.item.take().unwrap()
        }
    }

//    #[inline]
//    fn levels_count(&self) -> usize {
//        if self.data.is_empty() {
//            0
//        } else {
//            Self::level_of(self.data.len()-1) + 1
//        }
//    }

    #[inline]
    fn level_from(level: usize) -> usize {
        (1 << level) - 1
    }

    #[inline]
    fn level_of(idx: usize) -> usize {
        mem::size_of::<usize>()*8 - ((idx+1).leading_zeros() as usize) - 1
    }

    #[inline]
    fn row_start(idx: usize) -> usize {
        Self::level_from(Self::level_of(idx))
    }

    #[inline(always)]
    pub fn parenti(idx: usize) -> usize {
        (idx-1) >> 1
    }

    #[inline(always)]
    pub fn lefti(idx: usize) -> usize {
        (idx<<1) + 1
    }

    #[inline(always)]
    pub fn righti(idx: usize) -> usize {
        (idx<<1) + 2
    }

    #[inline(always)]
    pub fn parent(&self, idx: usize) -> &Node<T> {
        &self.data[Self::parenti(idx)]
    }

    #[inline(always)]
    pub fn left(&self, idx: usize) -> Option<&Node<T>> {
        let lefti = Self::lefti(idx);
        if lefti < self.data.len() {
            Some(&self.data[lefti])
        } else {
            None
        }
    }

    #[inline(always)]
    pub fn right(&self, idx: usize) -> Option<&Node<T>> {
        let righti = Self::righti(idx);
        if righti < self.data.len() {
            Some(&self.data[righti])
        } else {
            None
        }
    }

    #[inline]
    pub fn parent_mut(&mut self, idx: usize) -> &mut Node<T> {
        &mut self.data[Self::parenti(idx)]
    }

    #[inline]
    pub fn left_mut(&mut self, idx: usize) -> &mut Node<T> {
        &mut self.data[Self::lefti(idx)]
    }

    #[inline]
    pub fn right_mut(&mut self, idx: usize) -> &mut Node<T> {
        &mut self.data[Self::righti(idx)]
    }

    #[inline(always)]
    pub fn has_left(&self, idx: usize) -> bool {
        self.left(idx).and_then(|nd| nd.item.as_ref()).is_some()
    }

    #[inline(always)]
    pub fn has_right(&self, idx: usize) -> bool {
        self.right(idx).and_then(|nd| nd.item.as_ref()).is_some()
    }

    #[inline(always)]
    pub fn is_null(&self, idx: usize) -> bool {
        idx >= self.data.len() || self.data[idx].item.is_none()
    }

    #[inline(always)]
    pub fn size(&self) -> usize {
        self.size
    }
}

impl<K: Ord+Debug, T: Item<Key=K>> Debug for TeardownTree<T> {
    fn fmt(&self, fmt: &mut Formatter) -> ::std::fmt::Result {
        let mut nz: Vec<_> = self.data.iter()
            .rev()
            .skip_while(|node| node.item.is_none())
            .map(|node| match node.item {
                None => String::from("0"),
                Some(ref x) => format!("{:?}", x.ord())
            })
            .collect();
        nz.reverse();

        let _ = write!(fmt, "[");
        let mut sep = "";
        for ref key in nz.iter() {
            let _ = write!(fmt, "{}", sep);
            sep = ", ";
            let _ = write!(fmt, "{}", key);
        }
        let _ = write!(fmt, "]");
        Ok(())
    }
}
<commit_msg>impl Display for TeardownTree<commit_after>use std::ptr;
use std::mem;
use std::cmp::{max, Ordering};
use std::fmt;
use std::fmt::{Debug, Formatter};
use delete_range::{DeleteRange, DeleteRangeCache, TraversalDriver, TraversalDecision};

pub trait Item: Sized+Clone {
    type Key: Ord;

    fn ord(&self) -> Self::Key;
}

impl Item for usize {
    type Key = usize;

    fn ord(&self) -> Self::Key {
        *self
    }
}

#[derive(Debug, Clone)]
pub struct Node<T: Item> {
    pub item: Option<T>,
}

/// A fast way to refill the tree from a master copy; adds the requirement for T to implement Copy.
pub trait TeardownTreeRefill<T: Copy+Item> {
    fn refill(&mut self, master: &TeardownTree<T>);
}

impl<T: Copy+Item> TeardownTreeRefill<T> for TeardownTree<T> {
    fn refill(&mut self, master: &TeardownTree<T>) {
        let len = self.data.len();
        debug_assert!(len == master.data.len());
        self.data.truncate(0);
        unsafe {
            ptr::copy_nonoverlapping(master.data.as_ptr(), self.data.as_mut_ptr(), len);
            self.data.set_len(len);
        }
        self.size = master.size;
    }
}

pub struct DriverFromTo {
    from: usize,
    to: usize
}

impl DriverFromTo {
    pub fn new(from: usize, to: usize) -> DriverFromTo {
        DriverFromTo { from:from, to:to }
    }
}

impl TraversalDriver<usize> for DriverFromTo {
    #[inline(always)]
    fn decide(&self, x: &usize) -> TraversalDecision {
        let left = self.from <= *x;
        let right = *x <= self.to;

        TraversalDecision { left: left, right: right }
    }
}

#[derive(Clone)]
pub struct TeardownTree<T: Item> {
    data: Vec<Node<T>>,
    size: usize,

    pub delete_range_cache: Option<DeleteRangeCache<T>>,
}

impl<T: Item> TeardownTree<T> {
    pub fn new(sorted: Vec<T>) -> TeardownTree<T> {
        let size = sorted.len();

        let capacity = size;

        let mut data = Vec::with_capacity(capacity);
        for _ in 0..capacity {
            data.push(Node{item: None});
        }

        let mut sorted: Vec<Option<T>> = sorted.into_iter().map(|x| Some(x)).collect();
        let height = Self::build(&mut sorted, 0, &mut data);
        debug_assert!({ // we assert that the tree is nearly complete
            data.iter().take(sorted.len()).filter(|x| x.item.is_none()).count() == 0
        });
        let cache = DeleteRangeCache::new(height);
        TeardownTree { data: data, size: size, delete_range_cache: Some(cache) }
    }

    pub fn with_nodes(nodes: Vec<Node<T>>) -> TeardownTree<T> {
        let size = nodes.iter().filter(|x| x.item.is_some()).count();
        let height = Self::calc_height(&nodes, 0);
        let capacity = Self::row_start(nodes.len())*4 + 3; // allocate enough nodes that righti() is never out of bounds

        let mut data = Vec::with_capacity(capacity);
        for _ in 0..capacity {
            data.push(Node{item: None});
        }

        unsafe {
            ptr::copy_nonoverlapping(nodes.as_ptr(), data.as_mut_ptr(), nodes.len());
        }
        ::std::mem::forget(nodes);

        let cache = DeleteRangeCache::new(height);
        TeardownTree { data: data, size: size, delete_range_cache: Some(cache) }
    }

    pub fn into_node_vec(self) -> Vec<Node<T>> {
        self.data
    }

    fn calc_height(nodes: &Vec<Node<T>>, idx: usize) -> usize {
        if idx < nodes.len() && nodes[idx].item.is_some() {
            1 + max(Self::calc_height(nodes, Self::lefti(idx)),
                    Self::calc_height(nodes, Self::righti(idx)))
        } else {
            0
        }
    }

    /// finds the point to partition n keys for a nearly-complete binary tree
    /// http://stackoverflow.com/a/26896494/3646645
    fn build_select_root(n: usize) -> usize {
        // the highest power of two <= n
        let x = if n.is_power_of_two() { n }
                else { n.next_power_of_two() / 2 };

        if x/2 <= (n-x) + 1 {
            debug_assert!(x >= 1, "x={}, n={}", x, n);
            x - 1
        } else {
            n - x / 2
        }
    }

    /// returns the height of the tree
    fn build(sorted: &mut [Option<T>], idx: usize, data: &mut [Node<T>]) -> usize {
        match sorted.len() {
            0 => 0,
            n => {
                let mid = Self::build_select_root(n);
                let (lefti, righti) = (Self::lefti(idx), Self::righti(idx));
                let lh = Self::build(&mut sorted[..mid], lefti, data);
                let rh = Self::build(&mut sorted[mid+1..], righti, data);

                data[idx] = Node { item: sorted[mid].take() };
                debug_assert!(rh <= lh);
                1 + lh
            }
        }
    }

    pub fn len(&self) -> usize {
        self.data.len()
    }

    pub fn delete_range<D: TraversalDriver<T>>(&mut self, drv: &mut D, output: &mut Vec<T>) {
        debug_assert!(output.is_empty());
        output.truncate(0);
        {
            DeleteRange::new(self, output).delete_range(drv);
            debug_assert!({
                let cache: DeleteRangeCache<T> = self.delete_range_cache.take().unwrap();
                let ok = cache.slots_min.is_empty() && cache.slots_max.is_empty() && cache.delete_subtree_stack.is_empty();
                self.delete_range_cache = Some(cache);
                ok
            });
        }
        self.size -= output.len();
    }

    #[inline(always)]
    pub fn node(&self, idx: usize) -> &Node<T> {
        &self.data[idx]
    }

    #[inline(always)]
    pub fn node_mut(&mut self, idx: usize) -> &mut Node<T> {
        &mut self.data[idx]
    }

    #[inline(always)]
    fn node_mut_unsafe<'b>(&mut self, idx: usize) -> &'b mut Node<T> {
        unsafe {
            mem::transmute(&mut self.data[idx])
        }
    }

    pub fn item_mut_unwrap(&mut self, idx: usize) -> &mut T {
        self.node_mut(idx).item.as_mut().unwrap()
    }

    pub fn item_unwrap(&self, idx: usize) -> &T {
        self.node(idx).item.as_ref().unwrap()
    }

    pub fn delete(&mut self, search: &T) -> bool {
        let mut idx = 0;
        if idx >= self.data.len() {
            return false;
        }

        let mut ord =
            if let Some(ref it) = self.node_mut_unsafe(idx).item {
                it.ord()
            } else {
                return false;
            };

        loop {
            let ordering = search.ord().cmp(&ord);

            idx = match ordering {
                Ordering::Equal   => {
                    self.size -= 1;
                    self.delete_idx(idx);
                    return true
                },
                Ordering::Less    => Self::lefti(idx),
                Ordering::Greater => Self::righti(idx),
            };

            if idx >= self.data.len() {
                return false;
            }

            if let Some(ref it) = self.node_mut_unsafe(idx).item {
                ord = it.ord();
            } else {
                return false;
            }
        }
    }

    #[inline]
    fn delete_idx(&mut self, idx: usize) -> T {
        debug_assert!(!self.is_null(idx));

        match (self.has_left(idx), self.has_right(idx)) {
            (false, false) => {
                let root = self.node_mut(idx);
                root.item.take().unwrap()
            },

            (true, false)  => {
                let left_max = self.delete_max(Self::lefti(idx));
                mem::replace(self.item_mut_unwrap(idx), left_max)
            },

            (false, true)  => {
                let right_min = self.delete_min(Self::righti(idx));
                mem::replace(self.item_mut_unwrap(idx), right_min)
            },

            (true, true)   => {
                let left_max = self.delete_max(Self::lefti(idx));
                mem::replace(self.item_mut_unwrap(idx), left_max)
            },
        }
    }

    #[inline]
    fn delete_max(&mut self, mut idx: usize) -> T {
        while self.has_right(idx) {
            idx = Self::righti(idx);
        }

        if self.has_left(idx) {
            let left_max = self.delete_max(Self::lefti(idx));
            mem::replace(self.item_mut_unwrap(idx), left_max)
        } else {
            let root = self.node_mut(idx);
            root.item.take().unwrap()
        }
    }

    #[inline]
    fn delete_min(&mut self, mut idx: usize) -> T {
        while self.has_left(idx) {
            idx = Self::lefti(idx);
        }

        if self.has_right(idx) {
            let right_min = self.delete_min(Self::righti(idx));
            mem::replace(self.item_mut_unwrap(idx), right_min)
        } else {
            let root = self.node_mut(idx);
            root.item.take().unwrap()
        }
    }

//    #[inline]
//    fn levels_count(&self) -> usize {
//        if self.data.is_empty() {
//            0
//        } else {
//            Self::level_of(self.data.len()-1) + 1
//        }
//    }

    #[inline]
    fn level_from(level: usize) -> usize {
        (1 << level) - 1
    }

    #[inline]
    fn level_of(idx: usize) -> usize {
        mem::size_of::<usize>()*8 - ((idx+1).leading_zeros() as usize) - 1
    }

    #[inline]
    fn row_start(idx: usize) -> usize {
        Self::level_from(Self::level_of(idx))
    }

    #[inline(always)]
    pub fn parenti(idx: usize) -> usize {
        (idx-1) >> 1
    }

    #[inline(always)]
    pub fn lefti(idx: usize) -> usize {
        (idx<<1) + 1
    }

    #[inline(always)]
    pub fn righti(idx: usize) -> usize {
        (idx<<1) + 2
    }

    #[inline(always)]
    pub fn parent(&self, idx: usize) -> &Node<T> {
        &self.data[Self::parenti(idx)]
    }

    #[inline(always)]
    pub fn left(&self, idx: usize) -> Option<&Node<T>> {
        let lefti = Self::lefti(idx);
        if lefti < self.data.len() {
            Some(&self.data[lefti])
        } else {
            None
        }
    }

    #[inline(always)]
    pub fn right(&self, idx: usize) -> Option<&Node<T>> {
        let righti = Self::righti(idx);
        if righti < self.data.len() {
            Some(&self.data[righti])
        } else {
            None
        }
    }

    #[inline]
    pub fn parent_mut(&mut self, idx: usize) -> &mut Node<T> {
        &mut self.data[Self::parenti(idx)]
    }

    #[inline]
    pub fn left_mut(&mut self, idx: usize) -> &mut Node<T> {
        &mut self.data[Self::lefti(idx)]
    }

    #[inline]
    pub fn right_mut(&mut self, idx: usize) -> &mut Node<T> {
        &mut self.data[Self::righti(idx)]
    }

    #[inline(always)]
    pub fn has_left(&self, idx: usize) -> bool {
        self.left(idx).and_then(|nd| nd.item.as_ref()).is_some()
    }

    #[inline(always)]
    pub fn has_right(&self, idx: usize) -> bool {
        self.right(idx).and_then(|nd| nd.item.as_ref()).is_some()
    }

    #[inline(always)]
    pub fn is_null(&self, idx: usize) -> bool {
        idx >= self.data.len() || self.data[idx].item.is_none()
    }

    #[inline(always)]
    pub fn size(&self) -> usize {
        self.size
    }
}

impl<K: Ord+Debug, T: Item<Key=K>> Debug for TeardownTree<T> {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        let mut nz: Vec<_> = self.data.iter()
            .rev()
            .skip_while(|node| node.item.is_none())
            .map(|node| match node.item {
                None => String::from("0"),
                Some(ref x) => format!("{:?}", x.ord())
            })
            .collect();
        nz.reverse();

        let _ = write!(fmt, "[");
        let mut sep = "";
        for ref key in nz.iter() {
            let _ = write!(fmt, "{}", sep);
            sep = ", ";
            let _ = write!(fmt, "{}", key);
        }
        let _ = write!(fmt, "]");
        Ok(())
    }
}

impl<K: Ord+Debug, T: Item<Key=K>> fmt::Display for TeardownTree<T> {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        let mut ancestors = vec![];
        self.fmt_subtree(fmt, 0, &mut ancestors)
    }
}

impl<K: Ord+Debug, T: Item<Key=K>> TeardownTree<T> {
    fn fmt_branch(&self, fmt: &mut Formatter, ancestors: &Vec<bool>) -> fmt::Result {
        for (i, c) in ancestors.iter().enumerate() {
            if i == ancestors.len() - 1 {
                write!(fmt, "|--")?;
            } else {
                if *c {
                    write!(fmt, "|")?;
                } else {
                    write!(fmt, " ")?;
                }
                write!(fmt, "  ")?;
            }
        }

        Ok(())
    }

    fn fmt_subtree(&self, fmt: &mut Formatter, idx: usize, ancestors: &mut Vec<bool>) -> fmt::Result {
        self.fmt_branch(fmt, ancestors)?;

        if !self.is_null(idx) {
            writeln!(fmt, "{:?}", self.item_unwrap(idx).ord())?;

            if idx%2 == 0 && !ancestors.is_empty() {
                *ancestors.last_mut().unwrap() = false;
            }

            if self.has_left(idx) || self.has_right(idx) {
                ancestors.push(true);
                self.fmt_subtree(fmt, Self::lefti(idx), ancestors)?;
                self.fmt_subtree(fmt, Self::righti(idx), ancestors)?;
                ancestors.pop();
            }
        } else {
            writeln!(fmt, "X")?;
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before><commit_msg>Wrote some actual tests for Gc.<commit_after><|endoftext|>


<commit_before>use std;
use std::ffi::CStr;
use std::str::{Utf8Error};
use types::{
    to_bool,
    CFalse,
    Field,
    Tuple,
};

use postgres_bindings::{
    format_type_be,
    getTypeOutputInfo,
    get_namespace_name,
    macrowrap_PG_DETOAST_DATUM,
    macrowrap_PointerGetDatum,
    macrowrap_RelationGetNamespace,
    macrowrap_RelationGetRelationName,
    macrowrap_heap_getattr,
    pfree,
    Datum,
    HeapTuple,
    Oid,
    OidOutputFunctionCall,
    Struct_FormData_pg_attribute,
    TupleDesc,
    ReorderBufferTupleBuf,
    Relation,
};

// For any datatypes that we don't know, this function converts them into a string
// representation (which is always required by a datatype).
pub fn datum_to_string(typid:Oid, datum:Datum) -> Result<String, Utf8Error> {
    unsafe {
        let mut output_func = 0;
        let mut is_varlena  = CFalse;

        getTypeOutputInfo(typid, &mut output_func, &mut is_varlena);

        let real_datum = if to_bool(is_varlena) {
            let toasty = std::mem::transmute(macrowrap_PG_DETOAST_DATUM(datum));
            macrowrap_PointerGetDatum(toasty)
        } else {
            datum
        };

        pg_str_to_rs_str_and_free(OidOutputFunctionCall(output_func, real_datum))
    }
}

// You cannot use the input string after you call this function because its memory will have been freed.
pub fn pg_str_to_rs_str_and_free(pg_str: *mut i8) -> Result<String, Utf8Error> {
    unsafe {
      let slice   = CStr::from_ptr(pg_str);
      let to_free = std::mem::transmute(pg_str);
      pfree(to_free);
      let slice = try!(std::str::from_utf8(slice.to_bytes()));
      Ok(slice.to_string())
    }
}

pub fn pg_str_to_rs_str(pg_str: *mut i8) -> String {
    unsafe {
      let slice = CStr::from_ptr(pg_str);
      std::str::from_utf8(slice.to_bytes()).unwrap().to_string()
    }
}

pub fn parse_attname(i8str:[::libc::c_char; 64usize]) -> String {
    let u8str:[u8; 64usize] = unsafe { std::mem::transmute(i8str) };
    let str = String::from_utf8(u8str.to_vec()).unwrap(); // unwrap = danger!
    str.chars().take_while(|c| *c != '\u{0}').collect()
}

pub fn attribute(description:TupleDesc, attribute_number:isize) -> Struct_FormData_pg_attribute {
    let raw_desc = unsafe { *description };
    unsafe { **raw_desc.attrs.offset(attribute_number) }
}

pub fn type_name(pg_attribute:Struct_FormData_pg_attribute) -> Result<String, Utf8Error> {
    unsafe { pg_str_to_rs_str_and_free(format_type_be(pg_attribute.atttypid)) }
}

pub fn datum(tuple:HeapTuple, description:TupleDesc, attribute_number: i32) -> Option<Datum> {
    let isnull = &mut CFalse;
    let datum  = unsafe { macrowrap_heap_getattr(tuple, attribute_number + 1, description, isnull) };

    if to_bool(*isnull) {
        None
    } else {
        Some(datum)
    }
}

pub fn pg_tuple_to_rspgod_tuple(description:TupleDesc, heap:*mut ReorderBufferTupleBuf) -> Result<Tuple, String> {
    if heap.is_null() {
        return Err("pg_typel_to_rspgod_tuple: Tuple buffer is null".to_string());
    }

    let tuple            = unsafe { &mut (*heap).tuple };
    let raw_desc         = unsafe { *description };
    let num_attributes   = raw_desc.natts as u32;
    let mut fields       = vec![];

    for n in 0..num_attributes {
        let pg_attribute = attribute(description, n as isize);
        let name         = parse_attname(pg_attribute.attname.data);
        let type_name    = match type_name(pg_attribute) {
            Ok(name) => { name },
            Err(e)   => { return Err(e.to_string()); }
        };

        match datum(tuple, description, n as i32) {
            None => {
              fields.push(Field {
                  name:     name.clone(),
                  value:    None,
                  datatype: type_name,
              });
            },
            Some(d) => {
                match datum_to_string(pg_attribute.atttypid, d) {
                    Err(e)    => { return Err(e.to_string()); },
                    Ok(value) => {
                        fields.push(Field {
                            name:     name.clone(),
                            value:    Some(value),
                            datatype: type_name,
                        });
                    },
                }
            }
        }
    }

    Ok(fields)
}

pub fn get_namespace(relation:Relation) -> String {
    let c_namespace = unsafe { get_namespace_name(macrowrap_RelationGetNamespace(relation)) };
    pg_str_to_rs_str(c_namespace)
}

pub fn get_relation_name(relation:Relation) -> String {
    let c_relation_name = unsafe { macrowrap_RelationGetRelationName(relation) };
    pg_str_to_rs_str(c_relation_name)
}
<commit_msg>Makes unecessary postgres functions private<commit_after>use std;
use std::ffi::CStr;
use std::str::{Utf8Error};
use types::{
    to_bool,
    CFalse,
    Field,
    Tuple,
};

use postgres_bindings::{
    format_type_be,
    getTypeOutputInfo,
    get_namespace_name,
    macrowrap_PG_DETOAST_DATUM,
    macrowrap_PointerGetDatum,
    macrowrap_RelationGetNamespace,
    macrowrap_RelationGetRelationName,
    macrowrap_heap_getattr,
    pfree,
    Datum,
    HeapTuple,
    Oid,
    OidOutputFunctionCall,
    Struct_FormData_pg_attribute,
    TupleDesc,
    ReorderBufferTupleBuf,
    Relation,
};

pub fn pg_tuple_to_rspgod_tuple(description:TupleDesc, heap:*mut ReorderBufferTupleBuf) -> Result<Tuple, String> {
    if heap.is_null() {
        return Err("pg_typel_to_rspgod_tuple: Tuple buffer is null".to_string());
    }

    let tuple            = unsafe { &mut (*heap).tuple };
    let raw_desc         = unsafe { *description };
    let num_attributes   = raw_desc.natts as u32;
    let mut fields       = vec![];

    for n in 0..num_attributes {
        let pg_attribute = attribute(description, n as isize);
        let name         = parse_attname(pg_attribute.attname.data);
        let type_name    = match type_name(pg_attribute) {
            Ok(name) => { name },
            Err(e)   => { return Err(e.to_string()); }
        };

        match datum(tuple, description, n as i32) {
            None => {
              fields.push(Field {
                  name:     name.clone(),
                  value:    None,
                  datatype: type_name,
              });
            },
            Some(d) => {
                match datum_to_string(pg_attribute.atttypid, d) {
                    Err(e)    => { return Err(e.to_string()); },
                    Ok(value) => {
                        fields.push(Field {
                            name:     name.clone(),
                            value:    Some(value),
                            datatype: type_name,
                        });
                    },
                }
            }
        }
    }

    Ok(fields)
}

pub fn get_namespace(relation:Relation) -> String {
    let c_namespace = unsafe { get_namespace_name(macrowrap_RelationGetNamespace(relation)) };
    pg_str_to_rs_str(c_namespace)
}

pub fn get_relation_name(relation:Relation) -> String {
    let c_relation_name = unsafe { macrowrap_RelationGetRelationName(relation) };
    pg_str_to_rs_str(c_relation_name)
}

// For any datatypes that we don't know, this function converts them into a string
// representation (which is always required by a datatype).
fn datum_to_string(typid:Oid, datum:Datum) -> Result<String, Utf8Error> {
    unsafe {
        let mut output_func = 0;
        let mut is_varlena  = CFalse;

        getTypeOutputInfo(typid, &mut output_func, &mut is_varlena);

        let real_datum = if to_bool(is_varlena) {
            let toasty = std::mem::transmute(macrowrap_PG_DETOAST_DATUM(datum));
            macrowrap_PointerGetDatum(toasty)
        } else {
            datum
        };

        pg_str_to_rs_str_and_free(OidOutputFunctionCall(output_func, real_datum))
    }
}

// You cannot use the input string after you call this function because its memory will have been freed.
fn pg_str_to_rs_str_and_free(pg_str: *mut i8) -> Result<String, Utf8Error> {
    unsafe {
      let slice   = CStr::from_ptr(pg_str);
      let to_free = std::mem::transmute(pg_str);
      pfree(to_free);
      let slice = try!(std::str::from_utf8(slice.to_bytes()));
      Ok(slice.to_string())
    }
}

fn pg_str_to_rs_str(pg_str: *mut i8) -> String {
    unsafe {
      let slice = CStr::from_ptr(pg_str);
      std::str::from_utf8(slice.to_bytes()).unwrap().to_string()
    }
}

fn parse_attname(i8str:[::libc::c_char; 64usize]) -> String {
    let u8str:[u8; 64usize] = unsafe { std::mem::transmute(i8str) };
    let str = String::from_utf8(u8str.to_vec()).unwrap(); // unwrap = danger!
    str.chars().take_while(|c| *c != '\u{0}').collect()
}

fn attribute(description:TupleDesc, attribute_number:isize) -> Struct_FormData_pg_attribute {
    let raw_desc = unsafe { *description };
    unsafe { **raw_desc.attrs.offset(attribute_number) }
}

fn type_name(pg_attribute:Struct_FormData_pg_attribute) -> Result<String, Utf8Error> {
    unsafe { pg_str_to_rs_str_and_free(format_type_be(pg_attribute.atttypid)) }
}

fn datum(tuple:HeapTuple, description:TupleDesc, attribute_number: i32) -> Option<Datum> {
    let isnull = &mut CFalse;
    let datum  = unsafe { macrowrap_heap_getattr(tuple, attribute_number + 1, description, isnull) };

    if to_bool(*isnull) {
        None
    } else {
        Some(datum)
    }
}
<|endoftext|>


<commit_before>use libc::*;
use std::ffi::{CStr, CString};
use std::str::FromStr;

use engine::Engine;
use errors::*;

include!(concat!(env!("OUT_DIR"), "/cvar_array.rs"));

pub const EMPTY_CVAR_T: cvar_t = cvar_t {
    name: 0 as *const _,
    string: 0 as *mut _,
    flags: 0,
    value: 0f32,
    next: 0 as *mut _,
};

/// The engine CVar type.
#[repr(C)]
pub struct cvar_t {
    name: *const c_char,
    string: *mut c_char,
    flags: c_int,
    value: c_float,
    next: *mut cvar_t,
}

/// Safe wrapper for the engine CVar type.
pub struct CVar {
    engine_cvar: *mut cvar_t, // This pointer is always valid and points to a 'static.
    default_value: &'static str,
    name_cstring: CString,
}

impl cvar_t {
    pub fn string_is_non_null(&self) -> bool {
        !self.string.is_null()
    }
}

impl CVar {
    /// Creates a new CVar instance.
    pub fn new(engine_cvar: &'static mut cvar_t,
               name: &'static str,
               default_value: &'static str) -> Self {
        let cvar = Self {
            engine_cvar,
            default_value,
            name_cstring: CString::new(name).expect("could not convert the CVar name to CString")
        };

        engine_cvar.name = cvar.name_cstring.as_ptr();

        cvar
    }

    /// Retrieves a mutable reference to the engine CVar.
    ///
    /// # Safety
    /// Unsafe because this function should only be called from the main game thread.
    /// You should also ensure that you don't call any engine functions while holding
    /// this reference, because the game also has a mutable reference to this CVar.
    pub unsafe fn get_engine_cvar(&self) -> &'static mut cvar_t {
        &mut *self.engine_cvar
    }

    /// Registers this console variable.
    pub fn register(&self, engine: &mut Engine) -> Result<()> {
        let ptr = {
            let mut engine_cvar = engine.get_engine_cvar(self);

            // This CString needs to be valid only for the duration of Cvar_RegisterVariable().
            let default_value_cstring = CString::new(self.default_value)
                .chain_err(|| "could not convert CVar name to CString")?;

            let ptr = default_value_cstring.into_raw();
            engine_cvar.string = ptr;
            ptr
        };

        engine.register_variable(self).chain_err(|| "could not register the variable")?;

        // Free that CString from above.
        unsafe { CString::from_raw(ptr) };

        Ok(())
    }

    /// Returns the string this variable is set to.
    pub fn to_string(&self, engine: &mut Engine) -> Result<String> {
        let engine_cvar = engine.get_engine_cvar(self);
        ensure!(engine_cvar.string_is_non_null(), "the CVar string pointer was null");

        Ok(unsafe { CStr::from_ptr(engine_cvar.string) }.to_string_lossy().into_owned())
    }

    /// Tries parsing this variable's value to the desired type.
    pub fn parse<T>(&self, engine: &mut Engine) -> Result<T>
        where T: FromStr,
              <T as FromStr>::Err: ::std::error::Error + Send + 'static {
        let string = self.to_string(engine)
            .chain_err(|| "could not get this CVar's string value")?;
        string.parse()
            .chain_err(|| "could not convert the CVar string to the desired type")
    }
}
<commit_msg>Fix copy-paste mistake in an error message<commit_after>use libc::*;
use std::ffi::{CStr, CString};
use std::str::FromStr;

use engine::Engine;
use errors::*;

include!(concat!(env!("OUT_DIR"), "/cvar_array.rs"));

pub const EMPTY_CVAR_T: cvar_t = cvar_t {
    name: 0 as *const _,
    string: 0 as *mut _,
    flags: 0,
    value: 0f32,
    next: 0 as *mut _,
};

/// The engine CVar type.
#[repr(C)]
pub struct cvar_t {
    name: *const c_char,
    string: *mut c_char,
    flags: c_int,
    value: c_float,
    next: *mut cvar_t,
}

/// Safe wrapper for the engine CVar type.
pub struct CVar {
    engine_cvar: *mut cvar_t, // This pointer is always valid and points to a 'static.
    default_value: &'static str,
    name_cstring: CString,
}

impl cvar_t {
    pub fn string_is_non_null(&self) -> bool {
        !self.string.is_null()
    }
}

impl CVar {
    /// Creates a new CVar instance.
    pub fn new(engine_cvar: &'static mut cvar_t,
               name: &'static str,
               default_value: &'static str) -> Self {
        let cvar = Self {
            engine_cvar,
            default_value,
            name_cstring: CString::new(name).expect("could not convert the CVar name to CString")
        };

        engine_cvar.name = cvar.name_cstring.as_ptr();

        cvar
    }

    /// Retrieves a mutable reference to the engine CVar.
    ///
    /// # Safety
    /// Unsafe because this function should only be called from the main game thread.
    /// You should also ensure that you don't call any engine functions while holding
    /// this reference, because the game also has a mutable reference to this CVar.
    pub unsafe fn get_engine_cvar(&self) -> &'static mut cvar_t {
        &mut *self.engine_cvar
    }

    /// Registers this console variable.
    pub fn register(&self, engine: &mut Engine) -> Result<()> {
        let ptr = {
            let mut engine_cvar = engine.get_engine_cvar(self);

            // This CString needs to be valid only for the duration of Cvar_RegisterVariable().
            let default_value_cstring = CString::new(self.default_value)
                .chain_err(|| "could not convert default CVar value to CString")?;

            let ptr = default_value_cstring.into_raw();
            engine_cvar.string = ptr;
            ptr
        };

        engine.register_variable(self).chain_err(|| "could not register the variable")?;

        // Free that CString from above.
        unsafe { CString::from_raw(ptr) };

        Ok(())
    }

    /// Returns the string this variable is set to.
    pub fn to_string(&self, engine: &mut Engine) -> Result<String> {
        let engine_cvar = engine.get_engine_cvar(self);
        ensure!(engine_cvar.string_is_non_null(), "the CVar string pointer was null");

        Ok(unsafe { CStr::from_ptr(engine_cvar.string) }.to_string_lossy().into_owned())
    }

    /// Tries parsing this variable's value to the desired type.
    pub fn parse<T>(&self, engine: &mut Engine) -> Result<T>
        where T: FromStr,
              <T as FromStr>::Err: ::std::error::Error + Send + 'static {
        let string = self.to_string(engine)
            .chain_err(|| "could not get this CVar's string value")?;
        string.parse()
            .chain_err(|| "could not convert the CVar string to the desired type")
    }
}
<|endoftext|>


<commit_before>use table::{TableRow, TableHeader, Table};
use definitions::{ResultColumn, RusqlStatement, InsertDef, SelectDef};
use definitions::{AlterTableDef, AlterTable, Expression};
use definitions::{DeleteDef, InsertDataSource, UpdateDef, Order};
use expressions::{ExpressionResult, ExpressionEvaluator, expr_to_literal, result_to_literal};
use rusql::Rusql;

peg_file! parser("sql.rustpeg");

pub fn rusql_exec(db: &mut Rusql, sql_str: &str, callback: |&TableRow, &TableHeader|) -> Option<Table> {
    match parser::rusql_parse(sql_str) {
        Ok(res) => {
            for stmt in res.into_iter() {
                match stmt {
                    RusqlStatement::AlterTable(alter_table_def) => alter_table(db, alter_table_def),
                    RusqlStatement::CreateTable(table_def) => db.create_table(table_def),
                    RusqlStatement::Delete(delete_def) => delete(db, delete_def),
                    RusqlStatement::DropTable(drop_table_def) => db.drop_table(&drop_table_def.name),
                    RusqlStatement::Insert(insert_def) => insert(db, insert_def),
                    RusqlStatement::Select(select_def) => return Some(select(db, select_def, |a, b| callback(a, b))),
                    RusqlStatement::Update(update_def) => update(db, update_def),
                }
            }
        }
        Err(e) => println!("syntax error: {}", e),
    }
    None
}

fn alter_table(db: &mut Rusql, alter_table_def: AlterTableDef) {
    match alter_table_def.mode {
        AlterTable::RenameTo(new_name) => db.rename_table(&alter_table_def.name, new_name),
        AlterTable::AddColumn(column_def) => db.get_mut_table(&alter_table_def.name)
                                               .add_column(column_def),
    }
}

fn delete(db: &mut Rusql, delete_def: DeleteDef) {
    let table = db.get_mut_table(&delete_def.name);

    if let Some(ref expr) = delete_def.where_expr {
        // FIXME just making the borrow checker happy...
        let header = table.header.clone();
        table.delete_where(|row| ExpressionEvaluator::new(row, &header).eval_bool(expr));
    } else {
        table.clear();
    }
}

fn insert(db: &mut Rusql, insert_def: InsertDef) {
    match insert_def.data_source {
        InsertDataSource::Values(column_data) => {
            let mut table = db.get_mut_table(&insert_def.table_name);
            table.insert(column_data, &insert_def.column_names);
        }
        InsertDataSource::Select(select_def) => {
            let results_table = select(db, select_def, |_,_| {});
            let mut table = db.get_mut_table(&insert_def.table_name);

            for (_, row) in results_table.data.into_iter() {
                table.push_row(row);
            }
        }
        _ => {}
    }
}

fn update(db: &mut Rusql, update_def: UpdateDef) {
    let mut table = db.get_mut_table(&update_def.name);

    for (_, row) in table.data.iter_mut() {
        if let Some(ref expr) = update_def.where_expr {
            if !ExpressionEvaluator::new(row, &table.header).eval_bool(expr) {
                continue;
            }
        }

        for &(ref name, ref expr) in update_def.set.iter() {
            let x = table.header.iter().position(|ref cols| &cols.name == name).unwrap();

            row[x] = expr_to_literal(expr);
        }
    }
}

fn product(tables: Vec<&Table>, input_product: &mut Table, new_row_opt: Option<TableRow>) {
    let mut remaining = tables.clone();
    if let Some(table) = remaining.remove(0) {
        for row in table.data.values() {
            let mut new_row: TableRow = if let Some(ref new_row) = new_row_opt {
                new_row.clone()
            } else {
                Vec::new()
            };

            new_row.push_all(&*row.clone());

            product(remaining.clone(), input_product, Some(new_row));
        }
    } else {
        if let Some(new_row) = new_row_opt {
            input_product.push_row(new_row);
        }
    }
}

fn select(db: &mut Rusql, select_def: SelectDef, callback: |&TableRow, &TableHeader|) -> Table {
    let mut input_tables: Vec<&Table> = Vec::new();
    let mut input_product = generate_inputs(db, &mut input_tables, &select_def);

    filter_inputs(&mut input_product, &input_tables, &select_def);

    let results_table = generate_result_set(input_product, &input_tables, &select_def);

    for row in results_table.data.values() {
        callback(row, &results_table.header);
    }

    results_table
}

fn generate_inputs<'a>(db: &'a Rusql, input_tables: &mut Vec<&'a Table>, select_def: &SelectDef) -> Table {
    // https://www.sqlite.org/lang_select.html#fromclause
    let mut input_header: TableHeader = Vec::new();

    if let Some(ref table_or_subquery) = select_def.table_or_subquery {

        for name in table_or_subquery.iter() {
            let table = db.get_table(name);
            input_tables.push(table);
            input_header.push_all(&*table.header.clone());
        }

        let mut input_product = Table::new_result_table(input_header);

        product(input_tables.clone(), &mut input_product, None);

        input_product
    } else {
       let mut input_product = Table::new_result_table(input_header);
       let empty_row: TableRow = Vec::new();
       input_product.push_row(empty_row);

       input_product
    }
}

fn filter_inputs(input_product: &mut Table, input_tables: &Vec<&Table>, select_def: &SelectDef) {
    // https://www.sqlite.org/lang_select.html#whereclause

    if let Some(ref expr) = select_def.where_expr {
        let header = input_product.header.clone();
        input_product.delete_where(|row| {
            !ExpressionEvaluator::new(row, &header).with_tables(input_tables.clone())
                                                   .eval_bool(expr)
        });
    }
}

fn generate_result_set(input_product: Table, input_tables: &Vec<&Table>, select_def: &SelectDef) -> Table {
    // https://www.sqlite.org/lang_select.html#resultset
    let results_header: TableHeader = Vec::new();
    let mut results_table = Table::new_result_table(results_header);
    let mut rows: Vec<TableRow> = Vec::new();

    for row in input_product.data.values() {
        match select_def.result_column {
            ResultColumn::Expressions(ref exprs) => generate_row_from_expressions(&mut results_table, row, exprs, input_tables),
            ResultColumn::Asterisk => {
                if results_table.header.len() == 0 {
                    results_table.header = input_product.header.clone();
                }
                rows.push(row.clone());
            }
        }
    }

    if let Some(ref ordering_terms) = select_def.ordering_terms {
        debug!("ORDER BY");
        let mut ordering_terms = ordering_terms.clone();
        ordering_terms.as_mut_slice().reverse();
        for term in ordering_terms.iter() {
            rows.as_mut_slice().sort_by(|a, b| {
                // FIXME ... ugly.
                match term.order {
                    Order::Ascending => a[result_to_literal(
                            ExpressionEvaluator::new(a, &results_table.header)
                                                 .as_column_alias()
                                                 .eval_expr(&term.expr)
                        ).to_uint()].cmp(&b[result_to_literal(
                            ExpressionEvaluator::new(b, &results_table.header)
                                                 .as_column_alias()
                                                 .eval_expr(&term.expr)
                        ).to_uint()]),
                    Order::Descending => b[result_to_literal(
                            ExpressionEvaluator::new(b, &results_table.header)
                                                 .as_column_alias()
                                                 .eval_expr(&term.expr)
                        ).to_uint()].cmp(&a[result_to_literal(
                            ExpressionEvaluator::new(a, &results_table.header)
                                                 .as_column_alias()
                                                 .eval_expr(&term.expr)
                        ).to_uint()]),
                }
            });
        }
    }
    results_table.insert(rows, &None);

    results_table
}

fn generate_row_from_expressions(results_table: &mut Table, row: &TableRow, exprs: &Vec<Expression>, input_tables: &Vec<&Table>) {
    let mut new_row: TableRow = Vec::new();
    let push_header = if results_table.header.len() == 0 { true } else { false };

    for expr in exprs.iter() {
        if push_header {
            match ExpressionEvaluator::new(row, &results_table.header).with_tables(input_tables.clone())
                                                                      .with_column_def()
                                                                      .eval_expr(expr) {
                ExpressionResult::ColumnDef(def) => results_table.header.push(def.clone()),
                _ => {}, // FIXME No idea
            }
        }
        match ExpressionEvaluator::new(row, &results_table.header).with_tables(input_tables.clone())
                                                                  .eval_expr(expr) {
            ExpressionResult::Value(v) => new_row.push(v),
            _ => {}, // FIXME No idea
        }
    }

    results_table.push_row(new_row);
}
<commit_msg>Update to compile and test on latest nightly<commit_after>use table::{TableRow, TableHeader, Table};
use definitions::{ResultColumn, RusqlStatement, InsertDef, SelectDef};
use definitions::{AlterTableDef, AlterTable, Expression};
use definitions::{DeleteDef, InsertDataSource, UpdateDef, Order};
use expressions::{ExpressionResult, ExpressionEvaluator, expr_to_literal, result_to_literal};
use rusql::Rusql;

peg_file! parser("sql.rustpeg");

pub fn rusql_exec(db: &mut Rusql, sql_str: &str, callback: |&TableRow, &TableHeader|) -> Option<Table> {
    match parser::rusql_parse(sql_str) {
        Ok(res) => {
            for stmt in res.into_iter() {
                match stmt {
                    RusqlStatement::AlterTable(alter_table_def) => alter_table(db, alter_table_def),
                    RusqlStatement::CreateTable(table_def) => db.create_table(table_def),
                    RusqlStatement::Delete(delete_def) => delete(db, delete_def),
                    RusqlStatement::DropTable(drop_table_def) => db.drop_table(&drop_table_def.name),
                    RusqlStatement::Insert(insert_def) => insert(db, insert_def),
                    RusqlStatement::Select(select_def) => return Some(select(db, select_def, |a, b| callback(a, b))),
                    RusqlStatement::Update(update_def) => update(db, update_def),
                }
            }
        }
        Err(e) => println!("syntax error: {}", e),
    }
    None
}

fn alter_table(db: &mut Rusql, alter_table_def: AlterTableDef) {
    match alter_table_def.mode {
        AlterTable::RenameTo(new_name) => db.rename_table(&alter_table_def.name, new_name),
        AlterTable::AddColumn(column_def) => db.get_mut_table(&alter_table_def.name)
                                               .add_column(column_def),
    }
}

fn delete(db: &mut Rusql, delete_def: DeleteDef) {
    let table = db.get_mut_table(&delete_def.name);

    if let Some(ref expr) = delete_def.where_expr {
        // FIXME just making the borrow checker happy...
        let header = table.header.clone();
        table.delete_where(|row| ExpressionEvaluator::new(row, &header).eval_bool(expr));
    } else {
        table.clear();
    }
}

fn insert(db: &mut Rusql, insert_def: InsertDef) {
    match insert_def.data_source {
        InsertDataSource::Values(column_data) => {
            let mut table = db.get_mut_table(&insert_def.table_name);
            table.insert(column_data, &insert_def.column_names);
        }
        InsertDataSource::Select(select_def) => {
            let results_table = select(db, select_def, |_,_| {});
            let mut table = db.get_mut_table(&insert_def.table_name);

            for (_, row) in results_table.data.into_iter() {
                table.push_row(row);
            }
        }
        _ => {}
    }
}

fn update(db: &mut Rusql, update_def: UpdateDef) {
    let mut table = db.get_mut_table(&update_def.name);

    for (_, row) in table.data.iter_mut() {
        if let Some(ref expr) = update_def.where_expr {
            if !ExpressionEvaluator::new(row, &table.header).eval_bool(expr) {
                continue;
            }
        }

        for &(ref name, ref expr) in update_def.set.iter() {
            let x = table.header.iter().position(|ref cols| &cols.name == name).unwrap();

            row[x] = expr_to_literal(expr);
        }
    }
}

fn product(tables: Vec<&Table>, input_product: &mut Table, new_row_opt: Option<TableRow>) {
    let mut remaining = tables.clone();

    if remaining.len() == 0 {
        if let Some(new_row) = new_row_opt {
            input_product.push_row(new_row);
        }
    } else {
        let table = remaining.remove(0);
        for row in table.data.values() {
            let mut new_row: TableRow = if let Some(ref new_row) = new_row_opt {
                new_row.clone()
            } else {
                Vec::new()
            };

            new_row.push_all(&*row.clone());

            product(remaining.clone(), input_product, Some(new_row));
        }
    }
}

fn select(db: &mut Rusql, select_def: SelectDef, callback: |&TableRow, &TableHeader|) -> Table {
    let mut input_tables: Vec<&Table> = Vec::new();
    let mut input_product = generate_inputs(db, &mut input_tables, &select_def);

    filter_inputs(&mut input_product, &input_tables, &select_def);

    let results_table = generate_result_set(input_product, &input_tables, &select_def);

    for row in results_table.data.values() {
        callback(row, &results_table.header);
    }

    results_table
}

fn generate_inputs<'a>(db: &'a Rusql, input_tables: &mut Vec<&'a Table>, select_def: &SelectDef) -> Table {
    // https://www.sqlite.org/lang_select.html#fromclause
    let mut input_header: TableHeader = Vec::new();

    if let Some(ref table_or_subquery) = select_def.table_or_subquery {

        for name in table_or_subquery.iter() {
            let table = db.get_table(name);
            input_tables.push(table);
            input_header.push_all(&*table.header.clone());
        }

        let mut input_product = Table::new_result_table(input_header);

        product(input_tables.clone(), &mut input_product, None);

        input_product
    } else {
       let mut input_product = Table::new_result_table(input_header);
       let empty_row: TableRow = Vec::new();
       input_product.push_row(empty_row);

       input_product
    }
}

fn filter_inputs(input_product: &mut Table, input_tables: &Vec<&Table>, select_def: &SelectDef) {
    // https://www.sqlite.org/lang_select.html#whereclause

    if let Some(ref expr) = select_def.where_expr {
        let header = input_product.header.clone();
        input_product.delete_where(|row| {
            !ExpressionEvaluator::new(row, &header).with_tables(input_tables.clone())
                                                   .eval_bool(expr)
        });
    }
}

fn generate_result_set(input_product: Table, input_tables: &Vec<&Table>, select_def: &SelectDef) -> Table {
    // https://www.sqlite.org/lang_select.html#resultset
    let results_header: TableHeader = Vec::new();
    let mut results_table = Table::new_result_table(results_header);
    let mut rows: Vec<TableRow> = Vec::new();

    for row in input_product.data.values() {
        match select_def.result_column {
            ResultColumn::Expressions(ref exprs) => generate_row_from_expressions(&mut results_table, row, exprs, input_tables),
            ResultColumn::Asterisk => {
                if results_table.header.len() == 0 {
                    results_table.header = input_product.header.clone();
                }
                rows.push(row.clone());
            }
        }
    }

    if let Some(ref ordering_terms) = select_def.ordering_terms {
        debug!("ORDER BY");
        let mut ordering_terms = ordering_terms.clone();
        ordering_terms.as_mut_slice().reverse();
        for term in ordering_terms.iter() {
            rows.as_mut_slice().sort_by(|a, b| {
                // FIXME ... ugly.
                match term.order {
                    Order::Ascending => a[result_to_literal(
                            ExpressionEvaluator::new(a, &results_table.header)
                                                 .as_column_alias()
                                                 .eval_expr(&term.expr)
                        ).to_uint()].cmp(&b[result_to_literal(
                            ExpressionEvaluator::new(b, &results_table.header)
                                                 .as_column_alias()
                                                 .eval_expr(&term.expr)
                        ).to_uint()]),
                    Order::Descending => b[result_to_literal(
                            ExpressionEvaluator::new(b, &results_table.header)
                                                 .as_column_alias()
                                                 .eval_expr(&term.expr)
                        ).to_uint()].cmp(&a[result_to_literal(
                            ExpressionEvaluator::new(a, &results_table.header)
                                                 .as_column_alias()
                                                 .eval_expr(&term.expr)
                        ).to_uint()]),
                }
            });
        }
    }
    results_table.insert(rows, &None);

    results_table
}

fn generate_row_from_expressions(results_table: &mut Table, row: &TableRow, exprs: &Vec<Expression>, input_tables: &Vec<&Table>) {
    let mut new_row: TableRow = Vec::new();
    let push_header = if results_table.header.len() == 0 { true } else { false };

    for expr in exprs.iter() {
        if push_header {
            match ExpressionEvaluator::new(row, &results_table.header).with_tables(input_tables.clone())
                                                                      .with_column_def()
                                                                      .eval_expr(expr) {
                ExpressionResult::ColumnDef(def) => results_table.header.push(def.clone()),
                _ => {}, // FIXME No idea
            }
        }
        match ExpressionEvaluator::new(row, &results_table.header).with_tables(input_tables.clone())
                                                                  .eval_expr(expr) {
            ExpressionResult::Value(v) => new_row.push(v),
            _ => {}, // FIXME No idea
        }
    }

    results_table.push_row(new_row);
}
<|endoftext|>


<commit_before><commit_msg>Remove empty execute.rs file<commit_after><|endoftext|>


<commit_before>use std::collections::HashMap;
use std::io::Write;
use std::sync;

use liquid_error::Result;
use liquid_interpreter as interpreter;
use liquid_interpreter::Renderable;

pub struct Template {
    pub(crate) template: interpreter::Template,
    pub(crate) filters: sync::Arc<HashMap<&'static str, interpreter::BoxedValueFilter>>,
}

impl Template {
    /// Renders an instance of the Template, using the given globals.
    pub fn render(&self, globals: &interpreter::Globals) -> Result<String> {
        const BEST_GUESS: usize = 10_000;
        let mut data = Vec::with_capacity(BEST_GUESS);
        self.render_to(&mut data, globals)?;
        Ok(String::from_utf8(data).expect("render only writes UTF-8"))
    }

    /// Renders an instance of the Template, using the given globals.
    pub fn render_to(&self, writer: &mut Write, globals: &interpreter::Globals) -> Result<()> {
        let mut data = interpreter::ContextBuilder::new()
            .set_filters(&self.filters)
            .set_globals(globals)
            .build();
        self.template.render_to(writer, &mut data)
    }
}
<commit_msg>perf: Bypass UTF-8 validation overhead<commit_after>use std::collections::HashMap;
use std::io::Write;
use std::sync;

use liquid_error::Result;
use liquid_interpreter as interpreter;
use liquid_interpreter::Renderable;

pub struct Template {
    pub(crate) template: interpreter::Template,
    pub(crate) filters: sync::Arc<HashMap<&'static str, interpreter::BoxedValueFilter>>,
}

impl Template {
    /// Renders an instance of the Template, using the given globals.
    pub fn render(&self, globals: &interpreter::Globals) -> Result<String> {
        const BEST_GUESS: usize = 10_000;
        let mut data = Vec::with_capacity(BEST_GUESS);
        self.render_to(&mut data, globals)?;

        Ok(convert_buffer(data))
    }

    /// Renders an instance of the Template, using the given globals.
    pub fn render_to(&self, writer: &mut Write, globals: &interpreter::Globals) -> Result<()> {
        let mut data = interpreter::ContextBuilder::new()
            .set_filters(&self.filters)
            .set_globals(globals)
            .build();
        self.template.render_to(writer, &mut data)
    }
}

#[cfg(debug_assertions)]
fn convert_buffer(buffer: Vec<u8>) -> String {
    String::from_utf8(buffer)
        .expect("render can only write UTF-8 because all inputs and processing preserve utf-8")
}

#[cfg(not(debug_assertions))]
fn convert_buffer(buffer: Vec<u8>) -> String {
    unsafe { String::from_utf8_unchecked(buffer) }
}
<|endoftext|>


<commit_before>pub struct Game {
    name: String,
    original_platforms: Vec<String>
}

pub struct GameEdition {
    game: Game,
    name: String,
    platform: String
}

pub struct GameContent {
    game: Game,
    name: String,
}

pub struct ContentEdition {
    content: GameContent,
    edition: GameEdition
}
<commit_msg>Make the game type fields public<commit_after>#[derive(RustcDecodable, RustcEncodable)]
pub struct Game {
    pub name: String,
    pub original_platforms: Vec<String>
}

pub struct GameEdition {
    pub game: Game,
    pub name: String,
    pub platform: String
}

pub struct GameContent {
    pub game: Game,
    pub name: String,
}

pub struct GameContentEdition {
    pub content: GameContent,
    pub edition: GameEdition
}
<|endoftext|>


<commit_before>#![feature(associated_consts)]
#![feature(plugin)]
#![plugin(tapioca)]

#[macro_use]
extern crate tapioca;

infer_api!(uber, "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/OpenAPI.next/examples/v3.0/uber.yaml");

fn main() {
    use uber::products;

    let query_params = products::get::QueryParams {
        latitude: 10.3,
        longitude: 237.8,
    };

    match products::get(query_params) {
        Ok(result) => match result.body() {
            products::get::OkBody::Status200(body) => {
                let list = body.products.unwrap_or(vec![]);
                println!("First product: {:?}", list[0]);
            },
        },
        Err(result) => match result.body() {
            products::get::ErrBody::Status520(body) => {
                println!("Error message: {:?}", body.message);
            },
            products::get::ErrBody::NetworkFailure() => {
                println!("Request failed!");
            },
        },
    }
}
<commit_msg>Tidy up example<commit_after>#![feature(associated_consts)]
#![feature(plugin)]
#![plugin(tapioca)]

#[macro_use]
extern crate tapioca;

infer_api!(uber, "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/OpenAPI.next/examples/v3.0/uber.yaml");

fn main() {
    use uber::products::get::{QueryParams, OkBody, ErrBody};

    let query_params = QueryParams {
        latitude: 10.3,
        longitude: 237.8,
    };

    match uber::products::get(query_params) {
        Ok(result) => match result.body() {
            OkBody::Status200(body) => {
                let list = body.products.unwrap_or(vec![]);
                println!("First product: {:?}", list[0]);
            },
        },
        Err(result) => match result.body() {
            ErrBody::Status520(body) => println!(
                "Error message: {:?}",
                body.message
                    .unwrap_or(String::from("[No message]"))
            ),
            ErrBody::NetworkFailure() => println!("Request failed!"),
        },
    }
}
<|endoftext|>


<commit_before>//! Contains the HTTP server component.

use std::collections::HashMap;
use std::fs;
use std::io;
use std::net::{SocketAddr, ToSocketAddrs};
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};

use porthole;
use nickel::{self, Nickel, HttpRouter, StaticFilesHandler};

use markdown;

/// The HTTP server.
///
/// The server listens on the provided port, rendering the markdown preview when a GET request is
/// received at the server root.
pub struct Server {
    local_addr: SocketAddr,

    /// The "current working directory" of the server. Any static file requests will be joined to
    /// this directory.
    cwd: Arc<Mutex<PathBuf>>,
}

impl Server {
    /// Creates a new server that listens on socket address `addr`.
    pub fn new<A, P>(addr: A, working_directory: P) -> Server
        where A: ToSocketAddrs,
              P: AsRef<Path>
    {
        let socket_addr = addr.to_socket_addrs()
            .unwrap()
            .map(|addr| {
                if addr.port() == 0 {
                    let unused_port = porthole::open().unwrap();
                    format!("localhost:{}", unused_port)
                        .to_socket_addrs()
                        .unwrap()
                        .next()
                        .unwrap()
                } else {
                    addr
                }
            })
            .next()
            .unwrap();

        Server {
            local_addr: socket_addr,
            cwd: Arc::new(Mutex::new(working_directory.as_ref().to_owned())),
        }
    }

    pub fn change_working_directory<P>(&mut self, dir: P)
        where P: AsRef<Path>
    {
        let mut cwd = self.cwd.lock().unwrap();
        *cwd = dir.as_ref().to_owned();
    }

    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        Ok(self.local_addr)
    }

    fn listen(&self, websocket_port: u16, config: &::Config) {
        let mut server = Nickel::new();
        server.options = nickel::Options::default().output_on_listen(false);

        let mut data = HashMap::new();
        data.insert("websocket_port", websocket_port.to_string());

        data.insert("initial_markdown",
                    markdown::to_html(&config.initial_markdown));
        data.insert("highlight_theme", config.highlight_theme.to_owned());
        data.insert("custom_css", config.custom_css.to_owned());

        let root = Path::new(env!("CARGO_MANIFEST_DIR"));

        let mut markdown_view = root.to_path_buf();
        markdown_view.push("templates/markdown_view.html");

        server.get("/",
                   middleware! { |_request, response|
            return response.render(markdown_view.to_str().unwrap(), &data);
        });

        let local_cwd = self.cwd.clone();
        server.utilize(middleware! { |request, response|
            let path = request.path_without_query().map(|path| {
                path[1..].to_owned()
            });

            if let Some(path) = path {
                let path = local_cwd.lock().unwrap().clone().join(path);
                match fs::metadata(&path) {
                    Ok(ref attr) if attr.is_file() => return response.send_file(&path),
                    Err(ref e) if e.kind() != io::ErrorKind::NotFound => {
                        debug!("Error getting metadata for file '{:?}': {:?}",
                                                                  path, e)
                    }
                    _ => {}
                }
            };
        });

        let mut static_dir = root.to_path_buf();
        static_dir.push("static");
        assert!(static_dir.is_absolute());
        server.utilize(StaticFilesHandler::new(static_dir.to_str().unwrap()));

        let listening = server.listen(self.local_addr).unwrap();
        listening.detach();
    }

    /// Starts the server.
    ///
    /// Once a connection is received, the client will initiate WebSocket connections on
    /// `websocket_port`. If `initial_markdown` is present, it will be displayed on the first
    /// connection.
    pub fn start(&self, websocket_port: u16, config: &::Config) {
        self.listen(websocket_port, &config);
    }
}
<commit_msg>resolve static files before user's static files<commit_after>//! Contains the HTTP server component.

use std::collections::HashMap;
use std::fs;
use std::io;
use std::net::{SocketAddr, ToSocketAddrs};
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};

use porthole;
use nickel::{self, Nickel, HttpRouter, StaticFilesHandler};

use markdown;

/// The HTTP server.
///
/// The server listens on the provided port, rendering the markdown preview when a GET request is
/// received at the server root.
pub struct Server {
    local_addr: SocketAddr,

    /// The "current working directory" of the server. Any static file requests will be joined to
    /// this directory.
    cwd: Arc<Mutex<PathBuf>>,
}

impl Server {
    /// Creates a new server that listens on socket address `addr`.
    pub fn new<A, P>(addr: A, working_directory: P) -> Server
        where A: ToSocketAddrs,
              P: AsRef<Path>
    {
        let socket_addr = addr.to_socket_addrs()
            .unwrap()
            .map(|addr| {
                if addr.port() == 0 {
                    let unused_port = porthole::open().unwrap();
                    format!("localhost:{}", unused_port)
                        .to_socket_addrs()
                        .unwrap()
                        .next()
                        .unwrap()
                } else {
                    addr
                }
            })
            .next()
            .unwrap();

        Server {
            local_addr: socket_addr,
            cwd: Arc::new(Mutex::new(working_directory.as_ref().to_owned())),
        }
    }

    pub fn change_working_directory<P>(&mut self, dir: P)
        where P: AsRef<Path>
    {
        let mut cwd = self.cwd.lock().unwrap();
        *cwd = dir.as_ref().to_owned();
    }

    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        Ok(self.local_addr)
    }

    fn listen(&self, websocket_port: u16, config: &::Config) {
        let mut server = Nickel::new();
        server.options = nickel::Options::default().output_on_listen(false);

        let mut data = HashMap::new();
        data.insert("websocket_port", websocket_port.to_string());

        data.insert("initial_markdown",
                    markdown::to_html(&config.initial_markdown));
        data.insert("highlight_theme", config.highlight_theme.to_owned());
        data.insert("custom_css", config.custom_css.to_owned());

        let root = Path::new(env!("CARGO_MANIFEST_DIR"));

        let mut static_dir = root.to_path_buf();
        static_dir.push("static");
        assert!(static_dir.is_absolute());
        server.utilize(StaticFilesHandler::new(static_dir.to_str().unwrap()));

        let mut markdown_view = root.to_path_buf();
        markdown_view.push("templates/markdown_view.html");

        server.get("/",
                   middleware! { |_request, response|
            return response.render(markdown_view.to_str().unwrap(), &data);
        });

        let local_cwd = self.cwd.clone();
        server.utilize(middleware! { |request, response|
            let path = request.path_without_query().map(|path| {
                path[1..].to_owned()
            });

            if let Some(path) = path {
                let path = local_cwd.lock().unwrap().clone().join(path);
                match fs::metadata(&path) {
                    Ok(ref attr) if attr.is_file() => return response.send_file(&path),
                    Err(ref e) if e.kind() != io::ErrorKind::NotFound => {
                        debug!("Error getting metadata for file '{:?}': {:?}",
                                                                  path, e)
                    }
                    _ => {}
                }
            };
        });

        let listening = server.listen(self.local_addr).unwrap();
        listening.detach();
    }

    /// Starts the server.
    ///
    /// Once a connection is received, the client will initiate WebSocket connections on
    /// `websocket_port`. If `initial_markdown` is present, it will be displayed on the first
    /// connection.
    pub fn start(&self, websocket_port: u16, config: &::Config) {
        self.listen(websocket_port, &config);
    }
}
<|endoftext|>


<commit_before><commit_msg>Resolve clippy needless_return lint<commit_after><|endoftext|>


<commit_before><commit_msg>Skip ExternType::Kind check if type is known trivial<commit_after><|endoftext|>