<commit_before>// Copyright:: Copyright (c) 2015-2016 Chef Software, Inc.
//
// The terms of the Evaluation Agreement (Habitat) between Chef Software Inc.
// and the party accessing this file ("Licensee") apply to Licensee's use of
// the Software until such time that the Software is made available under an
// open source license such as the Apache 2.0 License.

use std::path::Path;
use std::result;

use clap::{App, AppSettings};
use url::Url;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

pub fn get() -> App<'static, 'static> {
    let alias_inject = sub_rumor_inject()
                           .about("Alias for 'rumor inject'")
                           .setting(AppSettings::Hidden);
    let alias_install = sub_package_install()
                            .about("Alias for 'pkg install'")
                            .setting(AppSettings::Hidden);

    clap_app!(hab =>
        (about: "\"A Habitat is the natural environment for your services\" - Alan Turing")
        (version: VERSION)
        (author: "\nAuthors: The Habitat Maintainers <humans@habitat.sh>\n")
        (@setting VersionlessSubcommands)
        (@setting ArgRequiredElseHelp)
        (@subcommand archive =>
            (about: "Runs Habitat package archive commands")
            (@subcommand upload =>
                (about: "Uploads a local package archive to a depot")
                (@arg DEPOT_URL: -u --url +takes_value {valid_url}
                 "Use a specific package depot URL")
                (@arg ARCHIVE: +required {file_exists}
                 "A path to an archive file (ex: /home/chef-redis-3.0.7-21120102031201.hab)")
            )
        )
        (@subcommand pkg =>
            (about: "Runs Habitat package commands")
            (subcommand: sub_package_install())
        )
        (@subcommand rumor =>
            (about: "Runs Habitat rumor commands")
            (subcommand: sub_rumor_inject())
        )
        (@subcommand sup =>
            (about: "Runs Habitat supervisor commands")
        )
        (subcommand: alias_inject)
        (subcommand: alias_install)
        (subcommand: alias_start())
        (after_help: "ALIASES:\
             \n    inject      Alias for: 'rumor inject'\
             \n    install     Alias for: 'pkg install'\
             \n    start       Alias for: 'sup start'\
             \n"
        )
    )
}

#[cfg_attr(rustfmt, rustfmt_skip)]
fn sub_package_install() -> App<'static, 'static> {
    clap_app!(@subcommand install =>
        (about: "Installs a package from a repo or locally from an archive file")
        (@arg REPO_URL: -u --url +takes_value {valid_url} "Use a specific package repo URL")
        (@arg PKG_IDENT_OR_ARCHIVE: +required "A package identifier (ex: chef/redis) \
         or path to an archive file (ex: /home/chef-redis-3.0.7-21120102031201.hab)")
    )
}

#[cfg_attr(rustfmt, rustfmt_skip)]
fn sub_rumor_inject() -> App<'static, 'static> {
    clap_app!(@subcommand inject =>
        (about: "Injects a configuration or configuration file into a group of Supervisors")
        (@arg PEERS: -p --peers +takes_value
         "A comma-delimited list of one or more gossip peers to infect (default: 127.0.0.1:9634)")
        (@arg SERVICE_GROUP: +required
         "Target service group for this injection (ex: redis.default)")
        (@arg VERSION_NUMBER: +required
         "A version number (integer) for this configuration (ex: 42)")
        (@arg FILE: {file_exists_or_stdin}
         "Path to local file on disk (ex: /tmp/config.toml, default: <stdin>)")
    )
}

#[cfg_attr(rustfmt, rustfmt_skip)]
fn alias_start() -> App<'static, 'static> {
    clap_app!(@subcommand start =>
        (about: "Starts a Habitat-supervised service")
        (@setting Hidden)
    )
}

fn file_exists(val: String) -> result::Result<(), String> {
    if Path::new(&val).is_file() {
        Ok(())
    } else {
        Err(format!("File: '{}' cannot be found", &val))
    }
}

fn file_exists_or_stdin(val: String) -> result::Result<(), String> {
    if val == "-" {
        Ok(())
    } else {
        file_exists(val)
    }
}

fn valid_url(val: String) -> result::Result<(), String> {
    match Url::parse(&val) {
        Ok(_) => Ok(()),
        Err(_) => Err(format!("URL: '{}' is not valid", &val)),
    }
}
<commit_msg>[hab] Display help on empty subcommands by default (ex: `hab pkg`).<commit_after>// Copyright:: Copyright (c) 2015-2016 Chef Software, Inc.
//
// The terms of the Evaluation Agreement (Habitat) between Chef Software Inc.
// and the party accessing this file ("Licensee") apply to Licensee's use of
// the Software until such time that the Software is made available under an
// open source license such as the Apache 2.0 License.

use std::path::Path;
use std::result;

use clap::{App, AppSettings};
use url::Url;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

pub fn get() -> App<'static, 'static> {
    let alias_inject = sub_rumor_inject()
                           .about("Alias for 'rumor inject'")
                           .setting(AppSettings::Hidden);
    let alias_install = sub_package_install()
                            .about("Alias for 'pkg install'")
                            .setting(AppSettings::Hidden);

    clap_app!(hab =>
        (about: "\"A Habitat is the natural environment for your services\" - Alan Turing")
        (version: VERSION)
        (author: "\nAuthors: The Habitat Maintainers <humans@habitat.sh>\n")
        (@setting VersionlessSubcommands)
        (@setting ArgRequiredElseHelp)
        (@subcommand archive =>
            (about: "Runs Habitat package archive commands")
            (@setting ArgRequiredElseHelp)
            (@subcommand upload =>
                (about: "Uploads a local package archive to a depot")
                (@arg DEPOT_URL: -u --url +takes_value {valid_url}
                 "Use a specific package depot URL")
                (@arg ARCHIVE: +required {file_exists}
                 "A path to an archive file (ex: /home/chef-redis-3.0.7-21120102031201.hab)")
            )
        )
        (@subcommand pkg =>
            (about: "Runs Habitat package commands")
            (@setting ArgRequiredElseHelp)
            (subcommand: sub_package_install())
        )
        (@subcommand rumor =>
            (about: "Runs Habitat rumor commands")
            (@setting ArgRequiredElseHelp)
            (subcommand: sub_rumor_inject())
        )
        (@subcommand sup =>
            (about: "Runs Habitat supervisor commands")
        )
        (subcommand: alias_inject)
        (subcommand: alias_install)
        (subcommand: alias_start())
        (after_help: "ALIASES:\
             \n    inject      Alias for: 'rumor inject'\
             \n    install     Alias for: 'pkg install'\
             \n    start       Alias for: 'sup start'\
             \n"
        )
    )
}

#[cfg_attr(rustfmt, rustfmt_skip)]
fn sub_package_install() -> App<'static, 'static> {
    clap_app!(@subcommand install =>
        (about: "Installs a package from a repo or locally from an archive file")
        (@arg REPO_URL: -u --url +takes_value {valid_url} "Use a specific package repo URL")
        (@arg PKG_IDENT_OR_ARCHIVE: +required "A package identifier (ex: chef/redis) \
         or path to an archive file (ex: /home/chef-redis-3.0.7-21120102031201.hab)")
    )
}

#[cfg_attr(rustfmt, rustfmt_skip)]
fn sub_rumor_inject() -> App<'static, 'static> {
    clap_app!(@subcommand inject =>
        (about: "Injects a configuration or configuration file into a group of Supervisors")
        (@arg PEERS: -p --peers +takes_value
         "A comma-delimited list of one or more gossip peers to infect (default: 127.0.0.1:9634)")
        (@arg SERVICE_GROUP: +required
         "Target service group for this injection (ex: redis.default)")
        (@arg VERSION_NUMBER: +required
         "A version number (integer) for this configuration (ex: 42)")
        (@arg FILE: {file_exists_or_stdin}
         "Path to local file on disk (ex: /tmp/config.toml, default: <stdin>)")
    )
}

#[cfg_attr(rustfmt, rustfmt_skip)]
fn alias_start() -> App<'static, 'static> {
    clap_app!(@subcommand start =>
        (about: "Starts a Habitat-supervised service")
        (@setting Hidden)
    )
}

fn file_exists(val: String) -> result::Result<(), String> {
    if Path::new(&val).is_file() {
        Ok(())
    } else {
        Err(format!("File: '{}' cannot be found", &val))
    }
}

fn file_exists_or_stdin(val: String) -> result::Result<(), String> {
    if val == "-" {
        Ok(())
    } else {
        file_exists(val)
    }
}

fn valid_url(val: String) -> result::Result<(), String> {
    match Url::parse(&val) {
        Ok(_) => Ok(()),
        Err(_) => Err(format!("URL: '{}' is not valid", &val)),
    }
}
<|endoftext|>


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

use dom::bindings::cell::DOMRefCell;
use dom::bindings::js::{JS, Root};
use dom::document::Document;
use dom::window::Window;
use msg::constellation_msg::PipelineId;
use std::cell::Cell;
use std::rc::Rc;

/// Encapsulates a handle to a frame in a frame tree.
#[derive(JSTraceable, HeapSizeOf)]
#[allow(unrooted_must_root)] // FIXME(#6687) this is wrong
pub struct Page {
    /// Pipeline id associated with this page.
    id: PipelineId,

    /// The outermost frame containing the document and window.
    frame: DOMRefCell<Option<Frame>>,

    /// Indicates if reflow is required when reloading.
    needs_reflow: Cell<bool>,

    // Child Pages.
    pub children: DOMRefCell<Vec<Rc<Page>>>,
}

pub struct PageIterator {
    stack: Vec<Rc<Page>>,
}

pub trait IterablePage {
    fn iter(&self) -> PageIterator;
    fn find(&self, id: PipelineId) -> Option<Rc<Page>>;
}

impl IterablePage for Rc<Page> {
    fn iter(&self) -> PageIterator {
        PageIterator {
            stack: vec!(self.clone()),
        }
    }
    fn find(&self, id: PipelineId) -> Option<Rc<Page>> {
        if self.id == id { return Some(self.clone()); }
        for page in &*self.children.borrow() {
            let found = page.find(id);
            if found.is_some() { return found; }
        }
        None
    }

}

impl Page {
    pub fn new(id: PipelineId) -> Page {
        Page {
            id: id,
            frame: DOMRefCell::new(None),
            needs_reflow: Cell::new(true),
            children: DOMRefCell::new(vec!()),
        }
    }

    pub fn pipeline(&self) -> PipelineId {
        self.id
    }

    pub fn window(&self) -> Root<Window> {
        Root::from_ref(&*self.frame.borrow().as_ref().unwrap().window)
    }

    pub fn document(&self) -> Root<Document> {
        Root::from_ref(&*self.frame.borrow().as_ref().unwrap().document)
    }

    // must handle root case separately
    pub fn remove(&self, id: PipelineId) -> Option<Rc<Page>> {
        let remove_idx = {
            self.children
                .borrow_mut()
                .iter_mut()
                .position(|page_tree| page_tree.id == id)
        };
        match remove_idx {
            Some(idx) => Some(self.children.borrow_mut().remove(idx)),
            None => {
                self.children
                    .borrow_mut()
                    .iter_mut()
                    .filter_map(|page_tree| page_tree.remove(id))
                    .next()
            }
        }
    }
}

impl Iterator for PageIterator {
    type Item = Rc<Page>;

    fn next(&mut self) -> Option<Rc<Page>> {
        match self.stack.pop() {
            Some(next) => {
                for child in &*next.children.borrow() {
                    self.stack.push(child.clone());
                }
                Some(next)
            },
            None => None,
        }
    }
}

impl Page {
    pub fn set_reflow_status(&self, status: bool) -> bool {
        let old = self.needs_reflow.get();
        self.needs_reflow.set(status);
        old
    }

    #[allow(unrooted_must_root)]
    pub fn set_frame(&self, frame: Option<Frame>) {
        *self.frame.borrow_mut() = frame;
    }
}

/// Information for one frame in the browsing context.
#[derive(JSTraceable, HeapSizeOf)]
#[must_root]
pub struct Frame {
    /// The document for this frame.
    pub document: JS<Document>,
    /// The window object for this frame.
    pub window: JS<Window>,
}
<commit_msg>Auto merge of #8483 - frewsxcv:cleanup-pageiterator-nxt, r=Manishearth<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::cell::DOMRefCell;
use dom::bindings::js::{JS, Root};
use dom::document::Document;
use dom::window::Window;
use msg::constellation_msg::PipelineId;
use std::cell::Cell;
use std::rc::Rc;

/// Encapsulates a handle to a frame in a frame tree.
#[derive(JSTraceable, HeapSizeOf)]
#[allow(unrooted_must_root)] // FIXME(#6687) this is wrong
pub struct Page {
    /// Pipeline id associated with this page.
    id: PipelineId,

    /// The outermost frame containing the document and window.
    frame: DOMRefCell<Option<Frame>>,

    /// Indicates if reflow is required when reloading.
    needs_reflow: Cell<bool>,

    // Child Pages.
    pub children: DOMRefCell<Vec<Rc<Page>>>,
}

pub struct PageIterator {
    stack: Vec<Rc<Page>>,
}

pub trait IterablePage {
    fn iter(&self) -> PageIterator;
    fn find(&self, id: PipelineId) -> Option<Rc<Page>>;
}

impl IterablePage for Rc<Page> {
    fn iter(&self) -> PageIterator {
        PageIterator {
            stack: vec!(self.clone()),
        }
    }
    fn find(&self, id: PipelineId) -> Option<Rc<Page>> {
        if self.id == id { return Some(self.clone()); }
        for page in &*self.children.borrow() {
            let found = page.find(id);
            if found.is_some() { return found; }
        }
        None
    }

}

impl Page {
    pub fn new(id: PipelineId) -> Page {
        Page {
            id: id,
            frame: DOMRefCell::new(None),
            needs_reflow: Cell::new(true),
            children: DOMRefCell::new(vec!()),
        }
    }

    pub fn pipeline(&self) -> PipelineId {
        self.id
    }

    pub fn window(&self) -> Root<Window> {
        Root::from_ref(&*self.frame.borrow().as_ref().unwrap().window)
    }

    pub fn document(&self) -> Root<Document> {
        Root::from_ref(&*self.frame.borrow().as_ref().unwrap().document)
    }

    // must handle root case separately
    pub fn remove(&self, id: PipelineId) -> Option<Rc<Page>> {
        let remove_idx = {
            self.children
                .borrow_mut()
                .iter_mut()
                .position(|page_tree| page_tree.id == id)
        };
        match remove_idx {
            Some(idx) => Some(self.children.borrow_mut().remove(idx)),
            None => {
                self.children
                    .borrow_mut()
                    .iter_mut()
                    .filter_map(|page_tree| page_tree.remove(id))
                    .next()
            }
        }
    }
}

impl Iterator for PageIterator {
    type Item = Rc<Page>;

    fn next(&mut self) -> Option<Rc<Page>> {
        let popped = self.stack.pop();
        if let Some(ref page) = popped {
            self.stack.extend(page.children.borrow().iter().cloned());
        }
        popped
    }
}

impl Page {
    pub fn set_reflow_status(&self, status: bool) -> bool {
        let old = self.needs_reflow.get();
        self.needs_reflow.set(status);
        old
    }

    #[allow(unrooted_must_root)]
    pub fn set_frame(&self, frame: Option<Frame>) {
        *self.frame.borrow_mut() = frame;
    }
}

/// Information for one frame in the browsing context.
#[derive(JSTraceable, HeapSizeOf)]
#[must_root]
pub struct Frame {
    /// The document for this frame.
    pub document: JS<Document>,
    /// The window object for this frame.
    pub window: JS<Window>,
}
<|endoftext|>


<commit_before>use crate::spec::{LinkerFlavor, TargetOptions};

pub fn opts() -> TargetOptions {
    let mut base = super::linux_gnu_base::opts();
    base.os = "android".to_string();
    // Many of the symbols defined in compiler-rt are also defined in libgcc.
    // Android's linker doesn't like that by default.
    base.pre_link_args
        .entry(LinkerFlavor::Gcc)
        .or_default()
        .push("-Wl,--allow-multiple-definition".to_string());
    base.dwarf_version = Some(2);
    base.position_independent_executables = true;
    base.has_elf_tls = false;
    // This is for backward compatibility, see https://github.com/rust-lang/rust/issues/49867
    // for context. (At that time, there was no `-C force-unwind-tables`, so the only solution
    // was to always emit `uwtable`).
    base.default_uwtable = true;
    base.crt_static_respected = false;
    base
}
<commit_msg>Android is not GNU<commit_after>use crate::spec::{LinkerFlavor, TargetOptions};

pub fn opts() -> TargetOptions {
    let mut base = super::linux_base::opts();
    base.os = "android".to_string();
    // Many of the symbols defined in compiler-rt are also defined in libgcc.
    // Android's linker doesn't like that by default.
    base.pre_link_args
        .entry(LinkerFlavor::Gcc)
        .or_default()
        .push("-Wl,--allow-multiple-definition".to_string());
    base.dwarf_version = Some(2);
    base.position_independent_executables = true;
    base.has_elf_tls = false;
    // This is for backward compatibility, see https://github.com/rust-lang/rust/issues/49867
    // for context. (At that time, there was no `-C force-unwind-tables`, so the only solution
    // was to always emit `uwtable`).
    base.default_uwtable = true;
    base.crt_static_respected = false;
    base
}
<|endoftext|>


<commit_before>type Puzzle = Vec<Vec<[i32; 3]>>;
type PuzzleDense = [[[i32; 3]; 3]; 3];

fn main() {

    let puzzle = blue();
    for piece in &puzzle {
        println!("{:?}", piece);
    }
    println!("");

    let pieces = push_to_zero(puzzle);
    for piece in pieces {
        for part in piece {
            println!("{:?}", part);
        }
        println!("");
    }
}

fn zeros() -> [[[i32; 3]; 3]; 3] {
    let zeros = [
        [
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
        ],
        [
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
        ],
        [
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
        ],
    ];
    zeros
}

fn push_to_zero(puzzle: Puzzle) -> Vec<PuzzleDense> {
    let mut pieces = Vec::new();
    for _ in 0..puzzle.len() {
        pieces.push(zeros());
    }

    for i in 0..puzzle.len() {
        let mut min_x = 99;
        let mut min_y = 99;
        let mut min_z = 99;
        for [x, y, z] in &puzzle[i] {
            if x < &min_x {
                min_x = *x;
            }
            if y < &min_y {
                min_y = *y;
            }
            if z < &min_z {
                min_z = *z;
            }
        }
        for [x, y, z] in &puzzle[i] {
            pieces[i][(x - min_x) as usize][(y - min_y) as usize][(z - min_z) as usize] = (i + 1) as i32;
        }

    }

    pieces
}

fn blue() -> Puzzle {
    let mut blue = Vec::new();

    blue.push(vec!(
        [2, 0, 2],
        [2, 1, 2],
        [2, 2, 2],
    ));

    let piece_2 = vec!(
        [1, 0, 2],
        [1, 1, 1],
        [1, 1, 2],
        [2, 0, 2],
    );
    for _ in 0..3 {
        blue.push(piece_2.clone());
    }

    let piece_3 = vec!(
        [1, 0, 2],
        [1, 1, 2],
        [2, 0, 1],
        [2, 0, 2],
    );
    for _ in 0..3 {
        blue.push(piece_3.clone());
    }

    blue
}
<commit_msg>Solve for 2 pieces, pretty draw.<commit_after>use std::fmt;

type Piece = Vec<[i32; 3]>;
type Puzzle = Vec<Piece>;

#[derive(Clone, Debug)]
struct PuzzleDense {
    data: [[[i32; 3]; 3]; 3],
}

impl fmt::Display for PuzzleDense {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        writeln!(f, "{:?}", self.data[0])?;
        writeln!(f, "{:?}", self.data[1])?;
        writeln!(f, "{:?}", self.data[2])
    }
}

fn main() {

    let puzzle = blue();
    let pieces = push_to_zero(puzzle);
    for piece in &pieces {
        for part in piece {
            println!("{:?}", part);
        }
        println!("");
    }

    let mut solutions = Vec::new();
    solutions.push(PuzzleDense { data: zeros() });

    let piece = &pieces[0];
    solutions = all_puts(solutions, 1, piece);

    let piece = &pieces[1];
    solutions = all_puts(solutions, 2, piece);

    for solution in solutions {
        println!("{:}", solution);
    }

}

fn max_xyz(piece: &Piece) -> (i32, i32, i32) {
    let mut max_x = -1;
    let mut max_y = -1;
    let mut max_z = -1;

    for [x, y, z] in piece {
        if x > &max_x {
            max_x = *x;
        }
        if y > &max_y{
            max_y = *y;
        }
        if z > &max_z{
            max_z = *z;
        }
    }
    (max_x, max_y, max_z)
}

fn all_puts(already_placed: Vec<PuzzleDense>, piece_count: i32, piece: &Piece) -> Vec<PuzzleDense> {
    let mut all_solutions = Vec::new();
    let (max_x, max_y, max_z) = max_xyz(&piece);

    for x_step in 0..3 - max_x {
        for y_step in 0..3 - max_y {
            for z_step in 0..3 - max_z {
                let already_placed = already_placed.clone();
                'next_piece:
                for mut puzzle in already_placed {

                    for [x, y, z] in piece {
                        if puzzle.data[(x + x_step) as usize][(y + y_step) as usize][(z + z_step) as usize] > 0 {
                            continue 'next_piece;
                        }
                    }

                    for [x, y, z] in piece {
                        puzzle.data[(x + x_step) as usize][(y + y_step) as usize][(z + z_step) as usize] = piece_count;
                    }

                    all_solutions.push(puzzle);
                }
            }
        }
    }

    all_solutions
}

fn zeros() -> [[[i32; 3]; 3]; 3] {
    let zeros = [
        [
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
        ],
        [
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
        ],
        [
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
        ],
    ];
    zeros
}

fn push_to_zero(puzzle: Puzzle) -> Puzzle {
    let mut pieces = Vec::new();

    for i in 0..puzzle.len() {
        let mut piece = Vec::new();
        let mut min_x = 99;
        let mut min_y = 99;
        let mut min_z = 99;

        for [x, y, z] in &puzzle[i] {
            if x < &min_x {
                min_x = *x;
            }
            if y < &min_y {
                min_y = *y;
            }
            if z < &min_z {
                min_z = *z;
            }
        }
        for [x, y, z] in &puzzle[i] {
            piece.push([x - min_x, y - min_y, z - min_z]);
        }

        pieces.push(piece);
    }

    pieces
}

fn blue() -> Puzzle {
    let mut blue = Vec::new();

    blue.push(vec!(
        [2, 0, 2],
        [2, 1, 2],
        [2, 2, 2],
    ));

    let piece_2 = vec!(
        [1, 0, 2],
        [1, 1, 1],
        [1, 1, 2],
        [2, 0, 2],
    );
    for _ in 0..3 {
        blue.push(piece_2.clone());
    }

    let piece_3 = vec!(
        [1, 0, 2],
        [1, 1, 2],
        [2, 0, 1],
        [2, 0, 2],
    );
    for _ in 0..3 {
        blue.push(piece_3.clone());
    }

    blue
}
<|endoftext|>


<commit_before>use std::collections::HashSet;
use std::fmt;

type Piece = Vec<[i32; 3]>;
type Puzzle = Vec<Piece>;

const SIN: [i32; 4] = [0, 1, 0, -1];
const COS: [i32; 4] = [1, 0, -1, 0];

#[derive(Clone, Debug)]
struct PuzzleDense {
    data: [[[i32; 3]; 3]; 3],
}

impl fmt::Display for PuzzleDense {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        writeln!(f, "{:?}", self.data[0])?;
        writeln!(f, "{:?}", self.data[1])?;
        writeln!(f, "{:?}", self.data[2])
    }
}

fn main() {
    let puzzle = blue();
    let pieces = push_to_zero(puzzle);
    for piece in &pieces {
        for part in piece {
            println!("{:?}", part);
        }
        println!();
    }

    let zero = vec![PuzzleDense { data: zeros() }];

    let mut solutions = Vec::new();
    for (i, piece) in pieces.iter().enumerate() {
        if i == 0 {
            solutions = all_puts(zero.clone(), (i + 1) as i32, piece);
        } else {
            solutions = all_rotations_and_puts(solutions.clone(), (i + 1) as i32, piece);
        }
    }

    for solution in solutions {
        println!("{:}", solution);
    }
}

fn all_rotations_and_puts(
    already_placed: Vec<PuzzleDense>,
    piece_count: i32,
    piece: &Piece,
) -> Vec<PuzzleDense> {
    let mut solutions = Vec::new();
    for rotation in all_rotations(piece) {
        for s in all_puts(already_placed.clone(), piece_count, &rotation) {
            solutions.push(s);
        }
    }
    solutions
}

fn all_rotations(piece: &Piece) -> Vec<Vec<[i32; 3]>> {
    let mut all_rots = Vec::new();
    for theta in 0..4 {
        let mut rotations = Vec::new();
        for [x, y, z] in piece {
            let rotated_z = [
                x * COS[theta] - y * SIN[theta],
                x * SIN[theta] + y * COS[theta],
                *z,
            ];
            rotations.push(rotated_z);
        }
        all_rots.push(rotations);
    }

    let mut all_rotss = all_rots.clone();
    for piece in &all_rots {
        for theta in 0..4 {
            let mut rotations = Vec::new();
            for [x, y, z] in piece {
                let rotated_yz = [
                    x * COS[theta] + z * SIN[theta],
                    *y,
                    -x * SIN[theta] + z * COS[theta],
                ];
                rotations.push(rotated_yz);
            }
            all_rotss.push(rotations);
        }
    }

    let mut all_rotsss = all_rotss.clone();
    for piece in &all_rotss {
        for theta in 0..4 {
            let mut rotations = Vec::new();
            for [x, y, z] in piece {
                let rotated_xyz = [
                    *x,
                    y * COS[theta] - z * SIN[theta],
                    y * SIN[theta] + z * COS[theta],
                ];
                rotations.push(rotated_xyz);
            }
            all_rotsss.push(rotations)
        }
    }

    let mut unique_solutions = HashSet::new();
    let rots = push_to_zero(all_rotsss);
    for mut solution in rots {
        solution.sort();
        unique_solutions.insert(solution);
    }

    let mut rotations = Vec::new();
    for solution in unique_solutions {
        rotations.push(solution);
    }
    rotations
}

fn max_xyz(piece: &Piece) -> (i32, i32, i32) {
    let mut max_x = -1;
    let mut max_y = -1;
    let mut max_z = -1;

    for [x, y, z] in piece {
        if x > &max_x {
            max_x = *x;
        }
        if y > &max_y {
            max_y = *y;
        }
        if z > &max_z {
            max_z = *z;
        }
    }
    (max_x, max_y, max_z)
}

fn all_puts(already_placed: Vec<PuzzleDense>, piece_count: i32, piece: &Piece) -> Vec<PuzzleDense> {
    let mut all_solutions = Vec::new();
    let (max_x, max_y, max_z) = max_xyz(piece);

    for x_step in 0..3 - max_x {
        for y_step in 0..3 - max_y {
            for z_step in 0..3 - max_z {
                let already_placed = already_placed.clone();
                'next_piece: for mut puzzle in already_placed {
                    for [x, y, z] in piece {
                        if puzzle.data[(x + x_step) as usize][(y + y_step) as usize]
                            [(z + z_step) as usize]
                            > 0
                        {
                            continue 'next_piece;
                        }
                    }

                    for [x, y, z] in piece {
                        puzzle.data[(x + x_step) as usize][(y + y_step) as usize]
                            [(z + z_step) as usize] = piece_count;
                    }

                    all_solutions.push(puzzle);
                }
            }
        }
    }

    all_solutions
}

fn zeros() -> [[[i32; 3]; 3]; 3] {
    [
        [[0, 0, 0], [0, 0, 0], [0, 0, 0]],
        [[0, 0, 0], [0, 0, 0], [0, 0, 0]],
        [[0, 0, 0], [0, 0, 0], [0, 0, 0]],
    ]
}

fn push_to_zero(puzzle: Puzzle) -> Puzzle {
    let mut pieces = Vec::new();

    for part in &puzzle {
        let mut piece = Vec::new();
        let mut min_x = 99;
        let mut min_y = 99;
        let mut min_z = 99;

        for [x, y, z] in part {
            if x < &min_x {
                min_x = *x;
            }
            if y < &min_y {
                min_y = *y;
            }
            if z < &min_z {
                min_z = *z;
            }
        }
        for [x, y, z] in part {
            piece.push([x - min_x, y - min_y, z - min_z]);
        }

        pieces.push(piece);
    }

    pieces
}

fn blue() -> Puzzle {
    let mut blue = Vec::new();

    blue.push(vec![[2, 0, 2], [2, 1, 2], [2, 2, 2]]);

    let piece_2 = vec![[1, 0, 2], [1, 1, 1], [1, 1, 2], [2, 0, 2]];
    for _ in 0..3 {
        blue.push(piece_2.clone());
    }

    let piece_3 = vec![[1, 0, 2], [1, 1, 2], [2, 0, 1], [2, 0, 2]];
    for _ in 0..3 {
        blue.push(piece_3.clone());
    }

    blue
}
<commit_msg>Solve the minotaur.<commit_after>use std::collections::HashSet;
use std::fmt;

type Piece = Vec<[i32; 3]>;
type Puzzle = Vec<Piece>;

const SIN: [i32; 4] = [0, 1, 0, -1];
const COS: [i32; 4] = [1, 0, -1, 0];

#[derive(Clone, Debug)]
struct PuzzleDense {
    data: [[[i32; 3]; 3]; 3],
}

impl fmt::Display for PuzzleDense {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        writeln!(f, "{:?}", self.data[0])?;
        writeln!(f, "{:?}", self.data[1])?;
        writeln!(f, "{:?}", self.data[2])
    }
}

fn main() {
    let puzzle = minotaur();
    let pieces = push_to_zero(puzzle);
    for piece in &pieces {
        for part in piece {
            println!("{:?}", part);
        }
        println!();
    }

    let zero = vec![PuzzleDense { data: zeros() }];

    let mut solutions = Vec::new();
    for (i, piece) in pieces.iter().enumerate() {
        if i == 0 {
            solutions = all_puts(zero.clone(), (i + 1) as i32, piece);
        } else {
            solutions = all_rotations_and_puts(solutions.clone(), (i + 1) as i32, piece);
        }
    }

    for solution in solutions {
        println!("{:}", solution);
    }
}

fn all_rotations_and_puts(
    already_placed: Vec<PuzzleDense>,
    piece_count: i32,
    piece: &Piece,
) -> Vec<PuzzleDense> {
    let mut solutions = Vec::new();
    for rotation in all_rotations(piece) {
        for s in all_puts(already_placed.clone(), piece_count, &rotation) {
            solutions.push(s);
        }
    }
    solutions
}

fn all_rotations(piece: &Piece) -> Vec<Vec<[i32; 3]>> {
    let mut all_rots = Vec::new();
    for theta in 0..4 {
        let mut rotations = Vec::new();
        for [x, y, z] in piece {
            let rotated_z = [
                x * COS[theta] - y * SIN[theta],
                x * SIN[theta] + y * COS[theta],
                *z,
            ];
            rotations.push(rotated_z);
        }
        all_rots.push(rotations);
    }

    let mut all_rotss = all_rots.clone();
    for piece in &all_rots {
        for theta in 0..4 {
            let mut rotations = Vec::new();
            for [x, y, z] in piece {
                let rotated_yz = [
                    x * COS[theta] + z * SIN[theta],
                    *y,
                    -x * SIN[theta] + z * COS[theta],
                ];
                rotations.push(rotated_yz);
            }
            all_rotss.push(rotations);
        }
    }

    let mut all_rotsss = all_rotss.clone();
    for piece in &all_rotss {
        for theta in 0..4 {
            let mut rotations = Vec::new();
            for [x, y, z] in piece {
                let rotated_xyz = [
                    *x,
                    y * COS[theta] - z * SIN[theta],
                    y * SIN[theta] + z * COS[theta],
                ];
                rotations.push(rotated_xyz);
            }
            all_rotsss.push(rotations)
        }
    }

    let mut unique_solutions = HashSet::new();
    let rots = push_to_zero(all_rotsss);
    for mut solution in rots {
        solution.sort();
        unique_solutions.insert(solution);
    }

    let mut rotations = Vec::new();
    for solution in unique_solutions {
        rotations.push(solution);
    }
    rotations
}

fn max_xyz(piece: &Piece) -> (i32, i32, i32) {
    let mut max_x = -1;
    let mut max_y = -1;
    let mut max_z = -1;

    for [x, y, z] in piece {
        if x > &max_x {
            max_x = *x;
        }
        if y > &max_y {
            max_y = *y;
        }
        if z > &max_z {
            max_z = *z;
        }
    }
    (max_x, max_y, max_z)
}

fn all_puts(already_placed: Vec<PuzzleDense>, piece_count: i32, piece: &Piece) -> Vec<PuzzleDense> {
    let mut all_solutions = Vec::new();
    let (max_x, max_y, max_z) = max_xyz(piece);

    for x_step in 0..3 - max_x {
        for y_step in 0..3 - max_y {
            for z_step in 0..3 - max_z {
                let already_placed = already_placed.clone();
                'next_piece: for mut puzzle in already_placed {
                    for [x, y, z] in piece {
                        if puzzle.data[(x + x_step) as usize][(y + y_step) as usize]
                            [(z + z_step) as usize]
                            > 0
                        {
                            continue 'next_piece;
                        }
                    }

                    for [x, y, z] in piece {
                        puzzle.data[(x + x_step) as usize][(y + y_step) as usize]
                            [(z + z_step) as usize] = piece_count;
                    }

                    all_solutions.push(puzzle);
                }
            }
        }
    }

    all_solutions
}

fn zeros() -> [[[i32; 3]; 3]; 3] {
    [
        [[0, 0, 0], [0, 0, 0], [0, 0, 0]],
        [[0, 0, 0], [0, 0, 0], [0, 0, 0]],
        [[0, 0, 0], [0, 0, 0], [0, 0, 0]],
    ]
}

fn push_to_zero(puzzle: Puzzle) -> Puzzle {
    let mut pieces = Vec::new();

    for part in &puzzle {
        let mut piece = Vec::new();
        let mut min_x = 99;
        let mut min_y = 99;
        let mut min_z = 99;

        for [x, y, z] in part {
            if x < &min_x {
                min_x = *x;
            }
            if y < &min_y {
                min_y = *y;
            }
            if z < &min_z {
                min_z = *z;
            }
        }
        for [x, y, z] in part {
            piece.push([x - min_x, y - min_y, z - min_z]);
        }

        pieces.push(piece);
    }

    pieces
}

fn blue() -> Puzzle {
    let mut blue = Vec::new();

    blue.push(vec![[2, 0, 2], [2, 1, 2], [2, 2, 2]]);

    let piece_2 = vec![[1, 0, 2], [1, 1, 1], [1, 1, 2], [2, 0, 2]];
    for _ in 0..3 {
        blue.push(piece_2.clone());
    }

    let piece_3 = vec![[1, 0, 2], [1, 1, 2], [2, 0, 1], [2, 0, 2]];
    for _ in 0..3 {
        blue.push(piece_3.clone());
    }

    blue
}

fn minotaur() -> Puzzle {
    let mut minotaur = Vec::new();
    minotaur.push(vec![[1, 2, 1], [2, 2, 1], [2, 1, 1], [2, 1, 2]]);
    minotaur.push(vec![[1, 2, 1], [2, 2, 1], [2, 2, 2], [2, 1, 2]]);
    minotaur.push(vec![[1, 1, 1], [2, 1, 1], [3, 1, 1], [2, 2, 1]]);
    minotaur.push(vec![[1, 1, 2], [1, 2, 2], [1, 2, 1], [1, 3, 1], [2, 2, 1]]);
    minotaur.push(vec![[1, 3, 1], [2, 1, 2], [2, 2, 2], [2, 2, 1], [2, 3, 1]]);
    minotaur.push(vec![[1, 1, 1], [1, 2, 1], [1, 3, 1], [2, 1, 1], [1, 2, 2]]);
    minotaur
}<|endoftext|>


<commit_before>use itertools::Itertools;
use lightning::map::{Map, ObjectMap};
use rayon::prelude::*;
use std::{
    collections::{BTreeSet, HashMap, HashSet},
    sync::Arc,
};
use tokio_stream::StreamExt;

use dovahkiin::types::{OwnedValue, SharedValue};

use crate::ram::{
    cell::{header_from_chunk_raw, select_from_chunk_raw},
    chunk::Chunk,
};

mod histogram;
pub mod sm;

pub struct SchemaStatistics {
    histogram: HashMap<u64, [OwnedValue; 10]>,
    count: usize,
    segs: usize,
    bytes: usize,
    timestamp: u64,
}

pub struct ChunkStatistics {
    schemas: ObjectMap<Arc<SchemaStatistics>>,
}

const HISTOGRAM_PARTITATION_SIZE: usize = 1024;
const HISTOGRAM_PARTITATION_DEPTH: usize = 128;

type HistogramKey = [u8; 8];

impl ChunkStatistics {
    pub fn from_chunk(chunk: &Chunk) -> Self {
        let histogram_partitations = chunk
            .cell_index
            .entries()
            .chunks(HISTOGRAM_PARTITATION_SIZE)
            .map(|s| s.to_vec())
            .collect_vec();
        let partitations: Vec<_> = histogram_partitations
            .into_par_iter()
            .map(|partitation| {
                // Build exact histogram for each of the partitation and then approximate overall histogram
                let mut sizes = HashMap::new();
                let mut segs = HashMap::new();
                let mut exact_accumlators = HashMap::new();
                let partitation_size = partitation.len();
                for (hash, _) in partitation {
                    let loc = if let Ok(ptr) = chunk.location_for_read(hash as u64) {
                        ptr
                    } else {
                        trace!("Cannot obtain cell lock {} for statistics", hash);
                        continue;
                    };
                    match header_from_chunk_raw(*loc) {
                        Ok((header, _, entry_header)) => {
                            let cell_size = entry_header.content_length as usize;
                            let cell_seg = chunk.allocator.id_by_addr(*loc);
                            let schema_id = header.schema;
                            if let Some(schema) = chunk.meta.schemas.get(&schema_id) {
                                let fields = schema.index_fields.keys().cloned().collect_vec();
                                if let Ok(partial_cell) =
                                    select_from_chunk_raw(*loc, chunk, fields.as_slice())
                                {
                                    let field_array = if fields.len() == 1 {
                                        vec![partial_cell]
                                    } else if let SharedValue::Array(arr) = partial_cell {
                                        arr
                                    } else {
                                        error!(
                                            "Cannot decode partial cell for statistics {:?}",
                                            partial_cell
                                        );
                                        continue;
                                    };
                                    for (i, val) in field_array.into_iter().enumerate() {
                                        if val == SharedValue::Null || val == SharedValue::NA {
                                            continue;
                                        }
                                        let field_id = fields[i];
                                        exact_accumlators
                                            .entry(schema_id)
                                            .or_insert_with(|| HashMap::new())
                                            .entry(field_id)
                                            .or_insert_with(|| Vec::with_capacity(partitation_size))
                                            .push(val.feature());
                                    }
                                    *sizes.entry(schema_id).or_insert(0) += cell_size;
                                    *segs.entry(schema_id).or_insert(0) += 1;
                                }
                            } else {
                                warn!("Cannot get schema {} for statistics", schema_id);
                            }
                        }
                        Err(e) => {
                            warn!("Failed to read {} for statistics, error: {:?}", hash, e);
                        }
                    }
                }
                let histograms: HashMap<_, _> = exact_accumlators
                    .into_iter()
                    .map(|(schema_id, schema_histograms)| {
                        let compiled_histograms = schema_histograms
                            .into_iter()
                            .map(|(field, mut items)| {
                                items.sort();
                                let depth = items.len() / HISTOGRAM_PARTITATION_DEPTH;
                                let mut histogram = (0..HISTOGRAM_PARTITATION_DEPTH)
                                    .map(|tile| items[tile * depth])
                                    .collect_vec();
                                let last_item = &items[items.len() - 1];
                                if histogram.last().unwrap() != last_item {
                                    histogram.push(*last_item);
                                }
                                (field, (histogram, items.len(), depth))
                            })
                            .collect::<HashMap<_, _>>();
                        (schema_id, compiled_histograms)
                    })
                    .collect::<HashMap<_, _>>();
                (sizes, segs, histograms)
            })
            .collect();
        let schema_ids: Vec<_> = partitations
            .iter()
            .map(|(sizes, _, _)| sizes.keys())
            .flatten()
            .dedup()
            .collect();
        let total_size = schema_ids
            .iter()
            .map(|sid| {
                (
                    *sid,
                    partitations
                        .iter()
                        .map(|(sizes, _, _)| sizes.get(sid).unwrap_or(&0))
                        .sum::<usize>(),
                )
            })
            .collect::<HashMap<_, _>>();
        let total_segs = schema_ids
            .iter()
            .map(|sid| {
                (
                    *sid,
                    partitations
                        .iter()
                        .map(|(_, segs, _)| segs.get(sid).unwrap_or(&0))
                        .sum::<usize>(),
                )
            })
            .collect::<HashMap<_, _>>();
        let empty_histo = Default::default();
        let schema_histograms = schema_ids
            .iter()
            .map(|sid| {
                (*sid, {
                    let parted_histos = partitations
                        .iter()
                        .map(|(_, _, histo)| histo.get(sid).unwrap_or(&empty_histo))
                        .collect_vec();
                    let field_ids = parted_histos
                        .iter()
                        .map(|histo_map| histo_map.keys())
                        .flatten()
                        .dedup()
                        .collect::<Vec<_>>();
                    field_ids.iter().map(|field_id| {
                        let schema_field_histograms = parted_histos
                            .iter()
                            .map(|histo_map| &histo_map[field_id])
                            .collect_vec();
                        (**field_id, build_histogram(schema_field_histograms))
                    })
                    .collect::<HashMap<u64, Vec<HistogramKey>>>()
                })
            })
            .collect::<HashMap<_, _>>();
        unimplemented!()
    }
}

fn build_histogram(partitations: Vec<&(Vec<HistogramKey>, usize, usize)>) -> Vec<HistogramKey> {
    unimplemented!()
}<commit_msg>count segments<commit_after>use itertools::Itertools;
use lightning::map::{Map, ObjectMap};
use rayon::prelude::*;
use std::{
    collections::{BTreeSet, HashMap, HashSet},
    sync::Arc,
};
use tokio_stream::StreamExt;

use dovahkiin::types::{OwnedValue, SharedValue};

use crate::ram::{
    cell::{header_from_chunk_raw, select_from_chunk_raw},
    chunk::Chunk,
};

mod histogram;
pub mod sm;

pub struct SchemaStatistics {
    histogram: HashMap<u64, [OwnedValue; 10]>,
    count: usize,
    segs: usize,
    bytes: usize,
    timestamp: u64,
}

pub struct ChunkStatistics {
    schemas: ObjectMap<Arc<SchemaStatistics>>,
}

const HISTOGRAM_PARTITATION_SIZE: usize = 1024;
const HISTOGRAM_PARTITATION_DEPTH: usize = 128;

type HistogramKey = [u8; 8];

impl ChunkStatistics {
    pub fn from_chunk(chunk: &Chunk) -> Self {
        let histogram_partitations = chunk
            .cell_index
            .entries()
            .chunks(HISTOGRAM_PARTITATION_SIZE)
            .map(|s| s.to_vec())
            .collect_vec();
        let partitations: Vec<_> = histogram_partitations
            .into_par_iter()
            .map(|partitation| {
                // Build exact histogram for each of the partitation and then approximate overall histogram
                let mut sizes = HashMap::new();
                let mut segs = HashMap::new();
                let mut exact_accumlators = HashMap::new();
                let partitation_size = partitation.len();
                for (hash, _) in partitation {
                    let loc = if let Ok(ptr) = chunk.location_for_read(hash as u64) {
                        ptr
                    } else {
                        trace!("Cannot obtain cell lock {} for statistics", hash);
                        continue;
                    };
                    match header_from_chunk_raw(*loc) {
                        Ok((header, _, entry_header)) => {
                            let cell_size = entry_header.content_length as usize;
                            let cell_seg = chunk.allocator.id_by_addr(*loc);
                            let schema_id = header.schema;
                            if let Some(schema) = chunk.meta.schemas.get(&schema_id) {
                                let fields = schema.index_fields.keys().cloned().collect_vec();
                                if let Ok(partial_cell) =
                                    select_from_chunk_raw(*loc, chunk, fields.as_slice())
                                {
                                    let field_array = if fields.len() == 1 {
                                        vec![partial_cell]
                                    } else if let SharedValue::Array(arr) = partial_cell {
                                        arr
                                    } else {
                                        error!(
                                            "Cannot decode partial cell for statistics {:?}",
                                            partial_cell
                                        );
                                        continue;
                                    };
                                    for (i, val) in field_array.into_iter().enumerate() {
                                        if val == SharedValue::Null || val == SharedValue::NA {
                                            continue;
                                        }
                                        let field_id = fields[i];
                                        exact_accumlators
                                            .entry(schema_id)
                                            .or_insert_with(|| HashMap::new())
                                            .entry(field_id)
                                            .or_insert_with(|| Vec::with_capacity(partitation_size))
                                            .push(val.feature());
                                    }
                                    *sizes.entry(schema_id).or_insert(0) += cell_size;
                                    segs.entry(schema_id)
                                        .or_insert_with(|| HashSet::new())
                                        .insert(cell_seg);
                                }
                            } else {
                                warn!("Cannot get schema {} for statistics", schema_id);
                            }
                        }
                        Err(e) => {
                            warn!("Failed to read {} for statistics, error: {:?}", hash, e);
                        }
                    }
                }
                let histograms: HashMap<_, _> = exact_accumlators
                    .into_iter()
                    .map(|(schema_id, schema_histograms)| {
                        let compiled_histograms = schema_histograms
                            .into_iter()
                            .map(|(field, mut items)| {
                                items.sort();
                                let depth = items.len() / HISTOGRAM_PARTITATION_DEPTH;
                                let mut histogram = (0..HISTOGRAM_PARTITATION_DEPTH)
                                    .map(|tile| items[tile * depth])
                                    .collect_vec();
                                let last_item = &items[items.len() - 1];
                                if histogram.last().unwrap() != last_item {
                                    histogram.push(*last_item);
                                }
                                (field, (histogram, items.len(), depth))
                            })
                            .collect::<HashMap<_, _>>();
                        (schema_id, compiled_histograms)
                    })
                    .collect::<HashMap<_, _>>();
                (sizes, segs, histograms)
            })
            .collect();
        let schema_ids: Vec<_> = partitations
            .iter()
            .map(|(sizes, _, _)| sizes.keys())
            .flatten()
            .dedup()
            .collect();
        let total_size = schema_ids
            .iter()
            .map(|sid| {
                (
                    *sid,
                    partitations
                        .iter()
                        .map(|(sizes, _, _)| sizes.get(sid).unwrap_or(&0))
                        .sum::<usize>(),
                )
            })
            .collect::<HashMap<_, _>>();
        let total_segs = schema_ids
            .iter()
            .map(|sid| {
                (
                    *sid,
                    partitations
                        .iter()
                        .map(|(_, segs, _)| segs.get(sid).map(|set| set.len()).unwrap_or(0))
                        .sum::<usize>(),
                )
            })
            .collect::<HashMap<_, _>>();
        let empty_histo = Default::default();
        let schema_histograms = schema_ids
            .iter()
            .map(|sid| {
                (*sid, {
                    let parted_histos = partitations
                        .iter()
                        .map(|(_, _, histo)| histo.get(sid).unwrap_or(&empty_histo))
                        .collect_vec();
                    let field_ids = parted_histos
                        .iter()
                        .map(|histo_map| histo_map.keys())
                        .flatten()
                        .dedup()
                        .collect::<Vec<_>>();
                    field_ids
                        .par_iter()
                        .map(|field_id| {
                            let schema_field_histograms = parted_histos
                                .iter()
                                .map(|histo_map| &histo_map[field_id])
                                .collect_vec();
                            (**field_id, build_histogram(schema_field_histograms))
                        })
                        .collect::<HashMap<u64, Vec<HistogramKey>>>()
                })
            })
            .collect::<HashMap<_, _>>();
        unimplemented!()
    }
}

fn build_histogram(partitations: Vec<&(Vec<HistogramKey>, usize, usize)>) -> Vec<HistogramKey> {
    unimplemented!()
}
<|endoftext|>


<commit_before>/// List of material font icons. Use this to generate a font Icon.
// emacs: use C-x 8 Ret => #xf207 ("BUS"-Glyph)
pub const FLOPPY_FONT_ICON: &str = "";
pub const ADD_FONT_ICON: &str = "";
pub const LOAD_FONT_ICON: &str = "";
pub const SAVE_FONT_ICON: &str = "";
pub const KEYBOARD_ARROW_LEFT_FONT_ICON: &str = "";
pub const KEYBOARD_ARROW_RIGHT_FONT_ICON: &str = "";
pub const REMOVE_ICON: &str = "";
pub const ARROW_DOWN_ICON: &str = "";

pub const MENU_FONT_ICON: &str = "";
pub const SETTINGS_FONT_ICON: &str = "";
pub const HELP_OUTLINE_FONT_ICON: &str = "";

// category: Social
pub const ANDROID_FONT_ICON: &str = "";
pub const APPLE_FONT_ICON: &str = "";
pub const GITHUB_FONT_ICON: &str = "";
pub const GOOGLE_FONT_ICON: &str = "";
pub const GOOGLE_DRIVE_FONT_ICON: &str = "";
pub const GOOGLE_MAPS_FONT_ICON: &str = "";
pub const LANGUAGE_JAVASCRIPT_FONT_ICON: &str = "";
pub const LANGUAGE_HTML5_FONT_ICON: &str = "";
pub const LANGUAGE_PYTHON_ICON: &str = "";
pub const PAYPAL_FONT_ICON: &str = "";
pub const POCKET_FONT_ICON: &str = "";
pub const RSS_FONT_ICON: &str = "";
pub const SHARE_FONT_ICON: &str = "";
pub const STEAM_FONT_ICON: &str = "";
pub const TWITTER_BOX_FONT_ICON: &str = "";
pub const TWITTER_FONT_ICON: &str = "";
pub const WIKIPEDIA_FONT_ICON: &str = "";
pub const LINKEDIN_FONT_ICON: &str = "";
pub const REDDIT_FONT_ICON: &str = "";
pub const VIMEO_FONT_ICON: &str = "";
pub const WINDOWS_FONT_ICON: &str = "";

// category: Person
pub const ACCOUNT_FONT_ICON: &str = "";
pub const ACCOUNT_ADD_FONT_ICON: &str = "";
pub const ACCOUNT_BOX_FONT_ICON: &str = "";
pub const ACCOUNT_CIRCLE_FONT_ICON: &str = "";
pub const ACCOUNTS_ADD_FONT_ICON: &str = "";
pub const ACCOUNTS_FONT_ICON: &str = "";
pub const MALE_FONT_ICON: &str = "";
pub const FEMALE_FONT_ICON: &str = "";
pub const MALE_FEMALE_FONT_ICON: &str = "";
pub const RUN_FONT_ICON: &str = "";
pub const WALK_FONT_ICON: &str = "";

// category: File
pub const CLOUD_FONT_ICON: &str = "";
pub const DOWNLOAD_FONT_ICON: &str = "";
pub const UPLOAD_FONT_ICON: &str = "";
pub const FILE_FONT_ICON: &str = "";
pub const FOLDER_FONT_ICON: &str = "";
pub const FOLDER_OUTLINE_FONT_ICON: &str = "";
pub const CLOUD_DONE_FONT_ICON: &str = "";
pub const CLOUD_OFF_FONT_ICON: &str = "";
pub const CLOUD_DOWNLOAD_FONT_ICON: &str = "";
pub const CLOUD_OUTLINE_FONT_ICON: &str = "";
pub const CLOUD_UPLOAD_FONT_ICON: &str = "";

// category: Comment
pub const COMMENT_FONT_ICON: &str = "";
pub const COMMENT_LIST_FONT_ICON: &str = "";
pub const COMMENT_IMAGE_FONT_ICON: &str = "";
pub const COMMENT_EDIT_FONT_ICON: &str = "";
pub const COMMENT_ALERT_FONT_ICON: &str = "";
pub const COMMENT_MORE_FONT_ICON: &str = "";
pub const COMMENT_OUTLINE_FONT_ICON: &str = "";
pub const COMMENTS_FONT_ICON: &str = "";
pub const COMMENT_VIDEO_TEXT_FONT_ICON: &str = "";
pub const COMMENT_TEXT_FONT_ICON: &str = "";

// category: Form
pub const CHECK_ALL_FONT_ICON: &str = "";
pub const CHECK_CIRCLE_U_FONT_ICON: &str = "";
pub const CHECK_CIRCLE_FONT_ICON: &str = "";
pub const CHECK_SQUARE_FONT_ICON: &str = "";
pub const CHECK_FONT_ICON: &str = "";
//pub const CHECK_FONT_ICON: &str = "";
pub const CIRCLE_O_FONT_ICON: &str = "";
pub const CIRCLE_FONT_ICON: &str = "";
pub const DOT_CIRCLE_ALT_FONT_ICON: &str = "";
pub const DOT_CIRCLE_FONT_ICON: &str = "";
pub const MINUS_CIRCLE_OUTLINE_FONT_ICON: &str = "";
pub const MINUS_CIRCLE_FONT_ICON: &str = "";
pub const MINUS_SQUARE_FONT_ICON: &str = "";
pub const MINUS_FONT_ICON: &str = "";
//pub const MINUS_FONT_ICON: &str = "";
pub const PLUS_CIRCLE_O_DUPLICATE_FONT_ICON: &str = "";
pub const PLUS_CIRCLE_O_FONT_ICON: &str = "";
pub const PLUS_CIRCLE_FONT_ICON: &str = "";
pub const PLUS_SQUARE_FONT_ICON: &str = "";
pub const PLUS_FONT_ICON: &str = "";
pub const SQUARE_O_FONT_ICON: &str = "";
pub const STAR_CIRCLE_FONT_ICON: &str = "";
pub const STAR_HALF_FONT_ICON: &str = "";
pub const STAR_OUTLINE_FONT_ICON: &str = "";
pub const STAR_STAR_FONT_ICON: &str = "";
<commit_msg>Temp fix icons.<commit_after>/// List of material font icons. Use this to generate a font Icon.
// emacs: use C-x 8 Ret => #xf207 ("BUS"-Glyph)
// pub const FLOPPY_FONT_ICON: &str = "";
// pub const ADD_FONT_ICON: &str = "";
// pub const LOAD_FONT_ICON: &str = "";
// pub const SAVE_FONT_ICON: &str = "";
// pub const KEYBOARD_ARROW_LEFT_FONT_ICON: &str = "";
// pub const KEYBOARD_ARROW_RIGHT_FONT_ICON: &str = "";
// pub const REMOVE_ICON: &str = "";
// pub const ARROW_DOWN_ICON: &str = "";

// pub const MENU_FONT_ICON: &str = "";
// pub const SETTINGS_FONT_ICON: &str = "";
// pub const HELP_OUTLINE_FONT_ICON: &str = "";

// // category: Social
// pub const ANDROID_FONT_ICON: &str = "";
// pub const APPLE_FONT_ICON: &str = "";
// pub const GITHUB_FONT_ICON: &str = "";
// pub const GOOGLE_FONT_ICON: &str = "";
// pub const GOOGLE_DRIVE_FONT_ICON: &str = "";
// pub const GOOGLE_MAPS_FONT_ICON: &str = "";
// pub const LANGUAGE_JAVASCRIPT_FONT_ICON: &str = "";
// pub const LANGUAGE_HTML5_FONT_ICON: &str = "";
// pub const LANGUAGE_PYTHON_ICON: &str = "";
// pub const PAYPAL_FONT_ICON: &str = "";
// pub const POCKET_FONT_ICON: &str = "";
// pub const RSS_FONT_ICON: &str = "";
// pub const SHARE_FONT_ICON: &str = "";
// pub const STEAM_FONT_ICON: &str = "";
// pub const TWITTER_BOX_FONT_ICON: &str = "";
// pub const TWITTER_FONT_ICON: &str = "";
// pub const WIKIPEDIA_FONT_ICON: &str = "";
// pub const LINKEDIN_FONT_ICON: &str = "";
// pub const REDDIT_FONT_ICON: &str = "";
// pub const VIMEO_FONT_ICON: &str = "";
// pub const WINDOWS_FONT_ICON: &str = "";

// // category: Person
// pub const ACCOUNT_FONT_ICON: &str = "";
// pub const ACCOUNT_ADD_FONT_ICON: &str = "";
// pub const ACCOUNT_BOX_FONT_ICON: &str = "";
// pub const ACCOUNT_CIRCLE_FONT_ICON: &str = "";
// pub const ACCOUNTS_ADD_FONT_ICON: &str = "";
// pub const ACCOUNTS_FONT_ICON: &str = "";
// pub const MALE_FONT_ICON: &str = "";
// pub const FEMALE_FONT_ICON: &str = "";
// pub const MALE_FEMALE_FONT_ICON: &str = "";
// pub const RUN_FONT_ICON: &str = "";
// pub const WALK_FONT_ICON: &str = "";

// // category: File
// pub const CLOUD_FONT_ICON: &str = "";
// pub const DOWNLOAD_FONT_ICON: &str = "";
// pub const UPLOAD_FONT_ICON: &str = "";
// pub const FILE_FONT_ICON: &str = "";
// pub const FOLDER_FONT_ICON: &str = "";
// pub const FOLDER_OUTLINE_FONT_ICON: &str = "";
// pub const CLOUD_DONE_FONT_ICON: &str = "";
// pub const CLOUD_OFF_FONT_ICON: &str = "";
// pub const CLOUD_DOWNLOAD_FONT_ICON: &str = "";
// pub const CLOUD_OUTLINE_FONT_ICON: &str = "";
// pub const CLOUD_UPLOAD_FONT_ICON: &str = "";

// // category: Comment
// pub const COMMENT_FONT_ICON: &str = "";
// pub const COMMENT_LIST_FONT_ICON: &str = "";
// pub const COMMENT_IMAGE_FONT_ICON: &str = "";
// pub const COMMENT_EDIT_FONT_ICON: &str = "";
// pub const COMMENT_ALERT_FONT_ICON: &str = "";
// pub const COMMENT_MORE_FONT_ICON: &str = "";
// pub const COMMENT_OUTLINE_FONT_ICON: &str = "";
// pub const COMMENTS_FONT_ICON: &str = "";
// pub const COMMENT_VIDEO_TEXT_FONT_ICON: &str = "";
// pub const COMMENT_TEXT_FONT_ICON: &str = "";

// // category: Form
// pub const CHECK_ALL_FONT_ICON: &str = "";
// pub const CHECK_CIRCLE_U_FONT_ICON: &str = "";
// pub const CHECK_CIRCLE_FONT_ICON: &str = "";
// pub const CHECK_SQUARE_FONT_ICON: &str = "";
// pub const CHECK_FONT_ICON: &str = "";
// //pub const CHECK_FONT_ICON: &str = "";
// pub const CIRCLE_O_FONT_ICON: &str = "";
// pub const CIRCLE_FONT_ICON: &str = "";
// pub const DOT_CIRCLE_ALT_FONT_ICON: &str = "";
// pub const DOT_CIRCLE_FONT_ICON: &str = "";
// pub const MINUS_CIRCLE_OUTLINE_FONT_ICON: &str = "";
// pub const MINUS_CIRCLE_FONT_ICON: &str = "";
// pub const MINUS_SQUARE_FONT_ICON: &str = "";
// pub const MINUS_FONT_ICON: &str = "";
// //pub const MINUS_FONT_ICON: &str = "";
// pub const PLUS_CIRCLE_O_DUPLICATE_FONT_ICON: &str = "";
// pub const PLUS_CIRCLE_O_FONT_ICON: &str = "";
// pub const PLUS_CIRCLE_FONT_ICON: &str = "";
// pub const PLUS_SQUARE_FONT_ICON: &str = "";
// pub const PLUS_FONT_ICON: &str = "";
// pub const SQUARE_O_FONT_ICON: &str = "";
// pub const STAR_CIRCLE_FONT_ICON: &str = "";
// pub const STAR_HALF_FONT_ICON: &str = "";
// pub const STAR_OUTLINE_FONT_ICON: &str = "";
// pub const STAR_STAR_FONT_ICON: &str = "";

/// List of material font icons. Use this to generate a font Icon.
pub const FLOPPY_FONT_ICON: &str = "";
pub const CHECK_FONT_ICON: &str = "";
pub const ADD_FONT_ICON: &str = "";
pub const MINUS_FONT_ICON: &str = "";
pub const LOAD_FONT_ICON: &str = "";
pub const SAVE_FONT_ICON: &str = "";
pub const KEYBOARD_ARROW_LEFT_FONT_ICON: &str = "";
pub const KEYBOARD_ARROW_RIGHT_FONT_ICON: &str = "";
pub const REMOVE_ICON: &str = "";
pub const ARROW_DOWN_ICON: &str = "";<|endoftext|>


<commit_before>use cgmath::prelude::*;
use cgmath::{Vector3, Vector4, Point3};

use glium;
use glium::{VertexBuffer, IndexBuffer, Surface, DrawParameters};
use glium::backend::Facade;
use glium::texture::{RawImage2d, Texture2d};

use camera::Camera;
use renderer::{Vertex, Ray, Hit};
use scene::Scene;

pub struct PTRenderer {
    shader: glium::Program,
    vertex_buffer: VertexBuffer<Vertex>,
    index_buffer: IndexBuffer<u32>,
}

impl PTRenderer {
    pub fn new<F: Facade>(facade: &F) -> PTRenderer {
        let vertices = vec!(
            Vertex { position: [-1.0, -1.0, 0.0],
                     normal: [0.0, 0.0, 0.0],
                     tex_coords: [0.0, 0.0] },
            Vertex { position: [1.0, -1.0, 0.0],
                     normal: [0.0, 0.0, 0.0],
                     tex_coords: [1.0, 0.0] },
            Vertex { position: [1.0, 1.0, 0.0],
                     normal: [0.0, 0.0, 0.0],
                     tex_coords: [1.0, 1.0] },
            Vertex { position: [-1.0, 1.0, 0.0],
                     normal: [0.0, 0.0, 0.0],
                     tex_coords: [0.0, 1.0] },
        );
        let vertex_buffer = VertexBuffer::new(facade, &vertices)
            .expect("Failed to create vertex buffer!");
        let indices = vec!(0, 1, 2, 0, 2, 3);
        let index_buffer = IndexBuffer::new(facade,
                                            glium::index::PrimitiveType::TrianglesList,
                                            &indices)
            .expect("Failed to create index buffer!");

        // Image shader
        let vertex_shader_src = include_str!("../image.vert");
        let fragment_shader_src = include_str!("../image.frag");
        let program = glium::Program::from_source(facade, vertex_shader_src, fragment_shader_src, None)
            .expect("Failed to create program!");
        PTRenderer { shader: program, vertex_buffer: vertex_buffer, index_buffer: index_buffer }
    }

    #[cfg_attr(feature="clippy", allow(needless_range_loop))]
    pub fn render<S: Surface, F: Facade>(&self, scene: &Scene, target: &mut S, facade: &F,
                                         width: usize, height: usize, camera: &Camera) {
        let clip_to_world = (camera.get_camera_to_clip(width as u32, height as u32)
            * camera.get_world_to_camera()).invert().expect("Non invertible world to clip");
        let mut image = vec![0.0; 3 * width * height];
        for y in 0..height {
            for x in 0..width {
                let clip_x = 2.0 * x as f32 / width as f32 - 1.0;
                let clip_y = 2.0 * y as f32 / height as f32 - 1.0;
                let clip_p = Vector4::new(clip_x, clip_y, 1.0, 1.0);
                let world_p = clip_to_world * clip_p;
                let dir = ((world_p / world_p.w).truncate() - camera.pos.to_vec()).normalize();
                let ray = Ray::new(camera.pos, dir, 100.0);
                let mut current_hit: Option<Hit> = None;

                for tri in &scene.triangles {
                    if let Some(hit) = tri.intersect(&ray) {
                        if let Some(best) = current_hit.take() {
                            if hit.t < best.t {
                                current_hit = Some(hit);
                            } else {
                                current_hit = Some(best);
                            }
                        } else {
                            current_hit = Some(hit);
                        }
                    }
                }

                if let Some(hit) = current_hit {
                    let c = hit.tri.get_diffuse(hit.u, hit.v);
                    image[3 * (y * width + x)]     = c.x;
                    image[3 * (y * width + x) + 1] = c.y;
                    image[3 * (y * width + x) + 2] = c.z;
                } else {
                    image[3 * (y * width + x)]     = 0.0;
                    image[3 * (y * width + x) + 1] = 0.0;
                    image[3 * (y * width + x) + 2] = 0.0;
                }

            }
        }
        let mut raw_image = RawImage2d::from_raw_rgb(image, (width as u32, height as u32));
        raw_image.format = glium::texture::ClientFormat::F32F32F32;
        let texture = Texture2d::new(facade, raw_image).expect("Failed to upload traced image!");
        let uniforms = uniform! {
            image: &texture,
        };
        let draw_parameters = DrawParameters {
            ..Default::default()
        };
        target.draw(&self.vertex_buffer, &self.index_buffer, &self.shader,
                    &uniforms, &draw_parameters).unwrap();
    }
}
<commit_msg>Remove unused imports<commit_after>use cgmath::prelude::*;
use cgmath::Vector4;

use glium;
use glium::{VertexBuffer, IndexBuffer, Surface, DrawParameters};
use glium::backend::Facade;
use glium::texture::{RawImage2d, Texture2d};

use camera::Camera;
use renderer::{Vertex, Ray, Hit};
use scene::Scene;

pub struct PTRenderer {
    shader: glium::Program,
    vertex_buffer: VertexBuffer<Vertex>,
    index_buffer: IndexBuffer<u32>,
}

impl PTRenderer {
    pub fn new<F: Facade>(facade: &F) -> PTRenderer {
        let vertices = vec!(
            Vertex { position: [-1.0, -1.0, 0.0],
                     normal: [0.0, 0.0, 0.0],
                     tex_coords: [0.0, 0.0] },
            Vertex { position: [1.0, -1.0, 0.0],
                     normal: [0.0, 0.0, 0.0],
                     tex_coords: [1.0, 0.0] },
            Vertex { position: [1.0, 1.0, 0.0],
                     normal: [0.0, 0.0, 0.0],
                     tex_coords: [1.0, 1.0] },
            Vertex { position: [-1.0, 1.0, 0.0],
                     normal: [0.0, 0.0, 0.0],
                     tex_coords: [0.0, 1.0] },
        );
        let vertex_buffer = VertexBuffer::new(facade, &vertices)
            .expect("Failed to create vertex buffer!");
        let indices = vec!(0, 1, 2, 0, 2, 3);
        let index_buffer = IndexBuffer::new(facade,
                                            glium::index::PrimitiveType::TrianglesList,
                                            &indices)
            .expect("Failed to create index buffer!");

        // Image shader
        let vertex_shader_src = include_str!("../image.vert");
        let fragment_shader_src = include_str!("../image.frag");
        let program = glium::Program::from_source(facade, vertex_shader_src, fragment_shader_src, None)
            .expect("Failed to create program!");
        PTRenderer { shader: program, vertex_buffer: vertex_buffer, index_buffer: index_buffer }
    }

    #[cfg_attr(feature="clippy", allow(needless_range_loop))]
    pub fn render<S: Surface, F: Facade>(&self, scene: &Scene, target: &mut S, facade: &F,
                                         width: usize, height: usize, camera: &Camera) {
        let clip_to_world = (camera.get_camera_to_clip(width as u32, height as u32)
            * camera.get_world_to_camera()).invert().expect("Non invertible world to clip");
        let mut image = vec![0.0; 3 * width * height];
        for y in 0..height {
            for x in 0..width {
                let clip_x = 2.0 * x as f32 / width as f32 - 1.0;
                let clip_y = 2.0 * y as f32 / height as f32 - 1.0;
                let clip_p = Vector4::new(clip_x, clip_y, 1.0, 1.0);
                let world_p = clip_to_world * clip_p;
                let dir = ((world_p / world_p.w).truncate() - camera.pos.to_vec()).normalize();
                let ray = Ray::new(camera.pos, dir, 100.0);
                let mut current_hit: Option<Hit> = None;

                for tri in &scene.triangles {
                    if let Some(hit) = tri.intersect(&ray) {
                        if let Some(best) = current_hit.take() {
                            if hit.t < best.t {
                                current_hit = Some(hit);
                            } else {
                                current_hit = Some(best);
                            }
                        } else {
                            current_hit = Some(hit);
                        }
                    }
                }

                if let Some(hit) = current_hit {
                    let c = hit.tri.get_diffuse(hit.u, hit.v);
                    image[3 * (y * width + x)]     = c.x;
                    image[3 * (y * width + x) + 1] = c.y;
                    image[3 * (y * width + x) + 2] = c.z;
                } else {
                    image[3 * (y * width + x)]     = 0.0;
                    image[3 * (y * width + x) + 1] = 0.0;
                    image[3 * (y * width + x) + 2] = 0.0;
                }

            }
        }
        let mut raw_image = RawImage2d::from_raw_rgb(image, (width as u32, height as u32));
        raw_image.format = glium::texture::ClientFormat::F32F32F32;
        let texture = Texture2d::new(facade, raw_image).expect("Failed to upload traced image!");
        let uniforms = uniform! {
            image: &texture,
        };
        let draw_parameters = DrawParameters {
            ..Default::default()
        };
        target.draw(&self.vertex_buffer, &self.index_buffer, &self.shader,
                    &uniforms, &draw_parameters).unwrap();
    }
}
<|endoftext|>


<commit_before>extern crate find_folder;

use std::path::PathBuf;

pub struct Manager {
    assets_path: PathBuf,
}

impl Manager {
    pub fn new() -> Self {
        Manager { assets_path: find_folder::Search::KidsThenParents(3, 5).for_folder("assets").unwrap() }
    }

    pub fn get_asset(&self, name: &str) -> PathBuf {
        self.assets_path.join(name)
    }

    pub fn get_font(&self) -> PathBuf {
        self.get_asset("NotoSans-Regular.ttf")
    }
}
<commit_msg>Resource manager test (new)<commit_after>extern crate find_folder;

use std::path::PathBuf;

pub struct Manager {
    assets_path: PathBuf,
}

impl Manager {
    pub fn new() -> Self {
        Manager { assets_path: find_folder::Search::KidsThenParents(3, 5).for_folder("assets").unwrap() }
    }

    pub fn get_asset(&self, name: &str) -> PathBuf {
        self.assets_path.join(name)
    }

    pub fn get_font(&self) -> PathBuf {
        self.get_asset("NotoSans-Regular.ttf")
    }
}

#[test]
fn new() {
    let manager = Manager::new();
    assert!(!manager.assets_path.to_string_lossy().is_empty());
    assert!(manager.assets_path.is_absolute());
    assert_eq!(None, manager.assets_path.extension());

//    assert_eq!("tts", manager.assets_path.extension().unwrap());
}

<|endoftext|>


<commit_before>//! This module is UNSTABLE, the reason is - recently added.

use std::convert::From;
use std::fmt;
use std::io::Write;

use super::super::value::{Float, Integer, ValueRef};
use super::FixedValueWriteError;
use super::ValueWriteError;
use super::WriteError;
use super::write_array_len;
use super::write_bin;
use super::write_bool;
use super::write_ext_meta;
use super::write_f32;
use super::write_f64;
use super::write_map_len;
use super::write_nil;
use super::write_sint;
use super::write_str;
use super::write_uint;

#[derive(Debug)]
pub struct Error(WriteError);

impl fmt::Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Error(ref err) => err.fmt(fmt),
        }
    }
}

impl From<FixedValueWriteError> for Error {
    fn from(err: FixedValueWriteError) -> Error {
        match err {
            FixedValueWriteError(err) => Error(err)
        }
    }
}

impl From<ValueWriteError> for Error {
    fn from(err: ValueWriteError) -> Error {
        match err {
            ValueWriteError::InvalidMarkerWrite(err) => Error(err),
            ValueWriteError::InvalidDataWrite(err) => Error(err)
        }
    }
}

pub fn write_value_ref<W>(wr: &mut W, val: &ValueRef) -> Result<(), Error>
    where W: Write
{
    match val {
        &ValueRef::Nil => try!(write_nil(wr)),
        &ValueRef::Boolean(val) => try!(write_bool(wr, val)),
        &ValueRef::Integer(Integer::U64(val)) => {
            try!(write_uint(wr, val));
        }
        &ValueRef::Integer(Integer::I64(val)) => {
            try!(write_sint(wr, val));
        }
        // TODO: Replace with generic write_float(...).
        &ValueRef::Float(Float::F32(val)) => try!(write_f32(wr, val)),
        &ValueRef::Float(Float::F64(val)) => try!(write_f64(wr, val)),
        &ValueRef::String(val) => {
            try!(write_str(wr, val));
        }
        &ValueRef::Binary(val) => {
            try!(write_bin(wr, val));
        }
        &ValueRef::Array(ref val) => {
            let len = val.len() as u32;

            try!(write_array_len(wr, len));

            for item in val {
                try!(write_value_ref(wr, item));
            }
        }
        &ValueRef::Map(ref val) => {
            let len = val.len() as u32;

            try!(write_map_len(wr, len));

            for &(ref key, ref val) in val {
                try!(write_value_ref(wr, key));
                try!(write_value_ref(wr, val));
            }
        }
        &ValueRef::Ext(ty, data) => {
            try!(write_ext_meta(wr, data.len() as u32, ty));
            try!(wr.write_all(data).map_err(|err| ValueWriteError::InvalidDataWrite(WriteError(err))));
        }
    }

    Ok(())
}

#[cfg(test)]
mod test {
    #[test]
    fn display_trait() {
        use std::io;
        use super::super::WriteError;
        use super::Error;

        // Delegates to I/O Error.
        let err = Error(WriteError(io::Error::new(io::ErrorKind::Other, "unexpected EOF")));

        assert_eq!("err: error while writing MessagePack'ed value", format!("err: {}", err));
    }
}
<commit_msg>ValueRef: error trait for encode error.<commit_after>//! This module is UNSTABLE, the reason is - recently added.

use std::convert::From;
use std::error;
use std::fmt;
use std::io::Write;

use super::super::value::{Float, Integer, ValueRef};
use super::FixedValueWriteError;
use super::ValueWriteError;
use super::WriteError;
use super::write_array_len;
use super::write_bin;
use super::write_bool;
use super::write_ext_meta;
use super::write_f32;
use super::write_f64;
use super::write_map_len;
use super::write_nil;
use super::write_sint;
use super::write_str;
use super::write_uint;

#[derive(Debug)]
pub struct Error(WriteError);

impl fmt::Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Error(ref err) => err.fmt(fmt),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match self {
            &Error(ref err) => err.description(),
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match self {
            &Error(ref err) => err.cause(),
        }
    }
}

impl From<FixedValueWriteError> for Error {
    fn from(err: FixedValueWriteError) -> Error {
        match err {
            FixedValueWriteError(err) => Error(err)
        }
    }
}

impl From<ValueWriteError> for Error {
    fn from(err: ValueWriteError) -> Error {
        match err {
            ValueWriteError::InvalidMarkerWrite(err) => Error(err),
            ValueWriteError::InvalidDataWrite(err) => Error(err)
        }
    }
}

pub fn write_value_ref<W>(wr: &mut W, val: &ValueRef) -> Result<(), Error>
    where W: Write
{
    match val {
        &ValueRef::Nil => try!(write_nil(wr)),
        &ValueRef::Boolean(val) => try!(write_bool(wr, val)),
        &ValueRef::Integer(Integer::U64(val)) => {
            try!(write_uint(wr, val));
        }
        &ValueRef::Integer(Integer::I64(val)) => {
            try!(write_sint(wr, val));
        }
        // TODO: Replace with generic write_float(...).
        &ValueRef::Float(Float::F32(val)) => try!(write_f32(wr, val)),
        &ValueRef::Float(Float::F64(val)) => try!(write_f64(wr, val)),
        &ValueRef::String(val) => {
            try!(write_str(wr, val));
        }
        &ValueRef::Binary(val) => {
            try!(write_bin(wr, val));
        }
        &ValueRef::Array(ref val) => {
            let len = val.len() as u32;

            try!(write_array_len(wr, len));

            for item in val {
                try!(write_value_ref(wr, item));
            }
        }
        &ValueRef::Map(ref val) => {
            let len = val.len() as u32;

            try!(write_map_len(wr, len));

            for &(ref key, ref val) in val {
                try!(write_value_ref(wr, key));
                try!(write_value_ref(wr, val));
            }
        }
        &ValueRef::Ext(ty, data) => {
            try!(write_ext_meta(wr, data.len() as u32, ty));
            try!(wr.write_all(data).map_err(|err| ValueWriteError::InvalidDataWrite(WriteError(err))));
        }
    }

    Ok(())
}

#[cfg(test)]
mod test {
    use std::error;
    use std::io;
    use super::super::WriteError;
    use super::Error;

    #[test]
    fn display_trait() {
        let err = Error(WriteError(io::Error::new(io::ErrorKind::Other, "unexpected EOF")));

        assert_eq!("err: error while writing MessagePack'ed value", format!("err: {}", err));
    }

    #[test]
    fn error_trait_description() {
        // Delegates to I/O Error.
        let err = Error(WriteError(io::Error::new(io::ErrorKind::Other, "unexpected EOF")));

        fn test<E: error::Error>(err: E) {
            assert_eq!("error while writing MessagePack'ed value", err.description());
            assert!(err.cause().is_some());
        }

        test(err);
    }
}
<|endoftext|>