<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::codegen::BindingDeclarations::HTMLOptGroupElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLOptGroupElementDerived;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLOptGroupElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLOptGroupElement {
    pub htmlelement: HTMLElement
}

impl HTMLOptGroupElementDerived for EventTarget {
    fn is_htmloptgroupelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLOptGroupElementTypeId))
    }
}

impl HTMLOptGroupElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLOptGroupElement {
        HTMLOptGroupElement {
            htmlelement: HTMLElement::new_inherited(HTMLOptGroupElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLOptGroupElement> {
        let element = HTMLOptGroupElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLOptGroupElementBinding::Wrap)
    }
}

pub trait HTMLOptGroupElementMethods {
    fn Disabled(&self) -> bool;
    fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult;
    fn Label(&self) -> DOMString;
    fn SetLabel(&mut self, _label: DOMString) -> ErrorResult;
}

impl<'a> HTMLOptGroupElementMethods for JSRef<'a, HTMLOptGroupElement> {
    fn Disabled(&self) -> bool {
        false
    }

    fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult {
        Ok(())
    }

    fn Label(&self) -> DOMString {
        "".to_owned()
    }

    fn SetLabel(&mut self, _label: DOMString) -> ErrorResult {
        Ok(())
    }
}
<commit_msg>Remove needless '&mut self' from HTMLOptGroupElementMethods.<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::codegen::BindingDeclarations::HTMLOptGroupElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLOptGroupElementDerived;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLOptGroupElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLOptGroupElement {
    pub htmlelement: HTMLElement
}

impl HTMLOptGroupElementDerived for EventTarget {
    fn is_htmloptgroupelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLOptGroupElementTypeId))
    }
}

impl HTMLOptGroupElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLOptGroupElement {
        HTMLOptGroupElement {
            htmlelement: HTMLElement::new_inherited(HTMLOptGroupElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLOptGroupElement> {
        let element = HTMLOptGroupElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLOptGroupElementBinding::Wrap)
    }
}

pub trait HTMLOptGroupElementMethods {
    fn Disabled(&self) -> bool;
    fn SetDisabled(&self, _disabled: bool) -> ErrorResult;
    fn Label(&self) -> DOMString;
    fn SetLabel(&self, _label: DOMString) -> ErrorResult;
}

impl<'a> HTMLOptGroupElementMethods for JSRef<'a, HTMLOptGroupElement> {
    fn Disabled(&self) -> bool {
        false
    }

    fn SetDisabled(&self, _disabled: bool) -> ErrorResult {
        Ok(())
    }

    fn Label(&self) -> DOMString {
        "".to_owned()
    }

    fn SetLabel(&self, _label: DOMString) -> ErrorResult {
        Ok(())
    }
}
<|endoftext|>


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

#[macro_use]
extern crate serde_derive;

extern crate dirs;
extern crate nalgebra;
extern crate num_complex;
extern crate num_traits;
extern crate rand;
extern crate sfml;
extern crate serde;
extern crate serde_json;
extern crate serde_yaml;

extern crate specs;
extern crate circle_collision;
extern crate gravity;
extern crate xsecurelock_saver;

use std::fs;
use std::fs::File;
use std::io::{BufReader, ErrorKind};
use std::path::{Path, PathBuf};

use gravity::{
    GravitationalConstant,
    GravitySource,
    GravitySystem,
    GravityTarget,
};
use circle_collision::{
    BruteForceCollisionDetector,
    ClearCollisionsInvolvingSceneEntities,
    CircleCollider,
    CollisionMatrix,
    LastUpdateCollisions,
};
use xsecurelock_saver::engine::{
    EngineBuilder,
    systems::physics::{
        SympleticEulerForceStep,
        SympleticEulerVelocityStep,
    },
};

use collision::{
    DeleteCollidedPlanets,
    MergeCollidedPlanets,
    MergedInto,
};
use config::GeneticOrbitsConfig;
use statustracker::{ActiveWorld, ScoreKeeper};
use storage::sqlite::SqliteStorage;
use worldgenerator::WorldGenerator;

mod collision;
mod config;
mod model;
mod storage;
mod statustracker;
mod worldgenerator;

fn main() {
    let config = get_config();
    let storage = match &config.database.database_path {
        Some(path) => {
            println!("using database {}", path);
            SqliteStorage::open(path).unwrap()
        },
        None => open_default_storage(),
    };

    let GeneticOrbitsConfig { scoring, generator, .. } = config;

    EngineBuilder::new()
        .with_initial_sceneloader(WorldGenerator::<SqliteStorage>::default())
        .with_resource(GravitationalConstant(1000.))
        .with_resource(LastUpdateCollisions::default())
        .with_resource({
            let mut matrix = CollisionMatrix::default();
            matrix.enable_collision(collision::planet(), collision::planet());
            matrix
        })
        .with_resource(scoring)
        .with_resource(generator)
        .with_resource(storage)
        .with_resource(ActiveWorld::default())
        .with_component::<CircleCollider>()
        .with_component::<GravitySource>()
        .with_component::<GravityTarget>()
        .with_component::<MergedInto>()
        .with_scene_change_sys(ClearCollisionsInvolvingSceneEntities, "", &[])
        // Run scorekeeping during the first stage of physics updates.
        .with_physics_update_sys(ScoreKeeper::<SqliteStorage>::default(), "score-keeper", &[])
        .with_physics_update_sys(GravitySystem, "apply-gravity", &[])
        // Barrier between adding forces and adding integration.
        .with_physics_update_barrier()
        .with_physics_update_sys(SympleticEulerForceStep, "integrate-forces", &[])
        .with_physics_update_sys(
            BruteForceCollisionDetector, "detect-collisions", &["integrate-forces"])
        .with_physics_update_sys(
            MergeCollidedPlanets, "merge-collided", &["detect-collisions"])
        .with_physics_update_sys(
            DeleteCollidedPlanets, "delete-collided", &["merge-collided"])
        .with_physics_update_sys(
            SympleticEulerVelocityStep,
            "integrate-velocities",
            &["integrate-forces", "detect-collisions", "merge-collided"],
        )
        .build()
        .run();
}

/// The screensaver folder name, used both for saving the database in the user data directory and
/// for looking for configs in the
const SAVER_DIR: &'static str = "xsecurelock-saver-genetic-orbits";

/// Open SqliteStorage somewhere, either in the user data dir or in memory.
fn open_default_storage() -> SqliteStorage {
    if let Some(mut data_dir) = dirs::data_dir() {
        data_dir.push(SAVER_DIR);
        let create_res = fs::create_dir(&data_dir)
            .or_else(|err| if err.kind() == ErrorKind::AlreadyExists {
                Ok(())
            } else {
                Err(err)
            });
        match create_res {
            Ok(()) => {
                data_dir.push("scenario-db.sqlite3");
                println!("using database {:?}", data_dir);
                return SqliteStorage::open(data_dir).unwrap();
            },
            Err(err) => println!("Unable to create storage directory ({}), opening in memory", err),
        }
    }
    println!("using in-memory database");
    SqliteStorage::open_in_memory().unwrap()
}

/// Load the config from the user config directory.
fn get_config() -> GeneticOrbitsConfig {
    match find_config_file() {
        Some(config_file) => {
            match serde_yaml::from_reader::<_, GeneticOrbitsConfig>(config_file) {
                Ok(mut config) => {
                    config.fix_invalid();
                    config
                },
                Err(err) => {
                    println!("Error loading config: {}", err);
                    Default::default()
                },
            }
        },
        None => Default::default(),
    }
}

fn find_config_file() -> Option<BufReader<File>> {
    let config_file = dirs::home_dir()
        .and_then(|mut home| {
            home.push(".xsecurelock-saver-genetic-orbits.yaml");
            try_open_config_file(home)
        })
        .or_else(|| {
            dirs::config_dir()
                .and_then(|mut config| {
                    config.push(SAVER_DIR);
                    config.push("config.yaml");
                    try_open_config_file(config)
                })
        });
    let config_file = if cfg!(target_family = "unix") {
        config_file.or_else(|| try_open_config_file(
                PathBuf::from(r"/etc/xsecurelock-saver-genetic-orbits/config.yaml")))
    } else {
        config_file
    };
    config_file.map(BufReader::new)
}

fn try_open_config_file<P: AsRef<Path>>(b: P) -> Option<File> {
    File::open(b.as_ref())
        .or_else(|err| if err.kind() == ErrorKind::NotFound {
            Err(())
        } else {
            println!("unable to read config file {:?}: {}", b.as_ref(), err);
            Err(())
        })
        .ok()
}
<commit_msg>Run merge as the first step in physics update, before scorekeeping, so that move interpolation from the last step is shown before in graphical updates<commit_after>// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate serde_derive;

extern crate dirs;
extern crate nalgebra;
extern crate num_complex;
extern crate num_traits;
extern crate rand;
extern crate sfml;
extern crate serde;
extern crate serde_json;
extern crate serde_yaml;

extern crate specs;
extern crate circle_collision;
extern crate gravity;
extern crate xsecurelock_saver;

use std::fs;
use std::fs::File;
use std::io::{BufReader, ErrorKind};
use std::path::{Path, PathBuf};

use gravity::{
    GravitationalConstant,
    GravitySource,
    GravitySystem,
    GravityTarget,
};
use circle_collision::{
    BruteForceCollisionDetector,
    ClearCollisionsInvolvingSceneEntities,
    CircleCollider,
    CollisionMatrix,
    LastUpdateCollisions,
};
use xsecurelock_saver::engine::{
    EngineBuilder,
    systems::physics::{
        SympleticEulerForceStep,
        SympleticEulerVelocityStep,
    },
};

use collision::{
    DeleteCollidedPlanets,
    MergeCollidedPlanets,
    MergedInto,
};
use config::GeneticOrbitsConfig;
use statustracker::{ActiveWorld, ScoreKeeper};
use storage::sqlite::SqliteStorage;
use worldgenerator::WorldGenerator;

mod collision;
mod config;
mod model;
mod storage;
mod statustracker;
mod worldgenerator;

fn main() {
    let config = get_config();
    let storage = match &config.database.database_path {
        Some(path) => {
            println!("using database {}", path);
            SqliteStorage::open(path).unwrap()
        },
        None => open_default_storage(),
    };

    let GeneticOrbitsConfig { scoring, generator, .. } = config;

    EngineBuilder::new()
        .with_initial_sceneloader(WorldGenerator::<SqliteStorage>::default())
        .with_resource(GravitationalConstant(1000.))
        .with_resource(LastUpdateCollisions::default())
        .with_resource({
            let mut matrix = CollisionMatrix::default();
            matrix.enable_collision(collision::planet(), collision::planet());
            matrix
        })
        .with_resource(scoring)
        .with_resource(generator)
        .with_resource(storage)
        .with_resource(ActiveWorld::default())
        .with_component::<CircleCollider>()
        .with_component::<GravitySource>()
        .with_component::<GravityTarget>()
        .with_component::<MergedInto>()
        .with_scene_change_sys(ClearCollisionsInvolvingSceneEntities, "", &[])
        // Run the real merge just before scoring.
        .with_physics_update_sys(
            MergeCollidedPlanets, "merge-collided", &[])
        .with_physics_update_sys(
            DeleteCollidedPlanets, "delete-collided", &["merge-collided"])
        .with_physics_update_barrier()
        // Run scorekeeping before integrating.
        .with_physics_update_sys(ScoreKeeper::<SqliteStorage>::default(), "score-keeper", &[])
        .with_physics_update_sys(GravitySystem, "apply-gravity", &[])
        // Barrier between adding forces and adding integration.
        .with_physics_update_barrier()
        .with_physics_update_sys(SympleticEulerForceStep, "integrate-forces", &[])
        .with_physics_update_sys(
            BruteForceCollisionDetector, "detect-collisions", &["integrate-forces"])
        .with_physics_update_sys(
            SympleticEulerVelocityStep, "integrate-velocities", &["detect-collisions"])
        .build()
        .run();
}

/// The screensaver folder name, used both for saving the database in the user data directory and
/// for looking for configs in the
const SAVER_DIR: &'static str = "xsecurelock-saver-genetic-orbits";

/// Open SqliteStorage somewhere, either in the user data dir or in memory.
fn open_default_storage() -> SqliteStorage {
    if let Some(mut data_dir) = dirs::data_dir() {
        data_dir.push(SAVER_DIR);
        let create_res = fs::create_dir(&data_dir)
            .or_else(|err| if err.kind() == ErrorKind::AlreadyExists {
                Ok(())
            } else {
                Err(err)
            });
        match create_res {
            Ok(()) => {
                data_dir.push("scenario-db.sqlite3");
                println!("using database {:?}", data_dir);
                return SqliteStorage::open(data_dir).unwrap();
            },
            Err(err) => println!("Unable to create storage directory ({}), opening in memory", err),
        }
    }
    println!("using in-memory database");
    SqliteStorage::open_in_memory().unwrap()
}

/// Load the config from the user config directory.
fn get_config() -> GeneticOrbitsConfig {
    match find_config_file() {
        Some(config_file) => {
            match serde_yaml::from_reader::<_, GeneticOrbitsConfig>(config_file) {
                Ok(mut config) => {
                    config.fix_invalid();
                    config
                },
                Err(err) => {
                    println!("Error loading config: {}", err);
                    Default::default()
                },
            }
        },
        None => Default::default(),
    }
}

fn find_config_file() -> Option<BufReader<File>> {
    let config_file = dirs::home_dir()
        .and_then(|mut home| {
            home.push(".xsecurelock-saver-genetic-orbits.yaml");
            try_open_config_file(home)
        })
        .or_else(|| {
            dirs::config_dir()
                .and_then(|mut config| {
                    config.push(SAVER_DIR);
                    config.push("config.yaml");
                    try_open_config_file(config)
                })
        });
    let config_file = if cfg!(target_family = "unix") {
        config_file.or_else(|| try_open_config_file(
                PathBuf::from(r"/etc/xsecurelock-saver-genetic-orbits/config.yaml")))
    } else {
        config_file
    };
    config_file.map(BufReader::new)
}

fn try_open_config_file<P: AsRef<Path>>(b: P) -> Option<File> {
    File::open(b.as_ref())
        .or_else(|err| if err.kind() == ErrorKind::NotFound {
            Err(())
        } else {
            println!("unable to read config file {:?}: {}", b.as_ref(), err);
            Err(())
        })
        .ok()
}
<|endoftext|>


<commit_before>use scaly::memory::page::_Page;
use scaly::memory::page::_PAGE_SIZE;
use std::alloc::alloc;
use std::alloc::dealloc;
use std::alloc::Layout;
use std::mem::size_of;
use std::ptr::null_mut;

const _STACK_BUCKET_PAGES: usize = 0x100;

pub struct _Region<'a> {
    page: &'a mut _Page,
}

impl<'a> _Region<'a> {
    pub fn create(page: &_Page) -> _Region<'a> {
        let our_page_address = _StackBucket::new_page(page);
        _Region {
            page: unsafe { &mut *(our_page_address as *mut _Page) },
        }
    }
}

impl<'a> Drop for _Region<'a> {
    fn drop(&mut self) {
        self.page.deallocate_extensions();
    }
}

struct _StackBucket {
    next_bucket: *mut _StackBucket,
}

impl _StackBucket {
    pub fn new_page(page: &_Page) -> *mut _Page {
        let page_address = page as *const _Page as usize;
        let stack_bucket_page_address = page_address & !(_PAGE_SIZE * _STACK_BUCKET_PAGES - 1);
        _StackBucket::get_next_page(stack_bucket_page_address, page_address)
    }

    fn get_next_page(stack_bucket_page_address: usize, page_address: usize) -> *mut _Page {
        let overflowed_page_address = stack_bucket_page_address + _PAGE_SIZE * _STACK_BUCKET_PAGES;
        let our_page_address = page_address + _PAGE_SIZE;
        if overflowed_page_address == our_page_address {
            let stack_bucket =
                (stack_bucket_page_address + size_of::<_Page>()) as *mut _StackBucket;
            unsafe { (*stack_bucket).get_page_from_next_bucket() }
        } else {
            our_page_address as *mut _Page
        }
    }

    fn get_page_from_next_bucket(self: &mut _StackBucket) -> *mut _Page {
        if self.next_bucket == null_mut() {
            self.next_bucket = _StackBucket::create();
        }
        _Page::get_page(self.next_bucket as usize)
    }

    fn create() -> *mut _StackBucket {
        unsafe {
            let memory = alloc(Layout::from_size_align_unchecked(
                _PAGE_SIZE * _STACK_BUCKET_PAGES,
                _PAGE_SIZE * _STACK_BUCKET_PAGES,
            ));
            if memory == null_mut() {
                panic!("Unable to crete a new stack bucket: Out of memory.");
            }
            let page = &mut *(memory as *mut _Page);
            page.reset();
            let bucket = page.allocate(_StackBucket {
                next_bucket: null_mut(),
            });
            bucket
        }
    }

    pub fn deallocate(& self) {
        let mut bucket = self as *const _StackBucket;
        unsafe {
            while !(*bucket).next_bucket.is_null() {
                let next_bucket = (*bucket).next_bucket;
                let page = _Page::get_page(bucket as usize);
                dealloc (
                    page as *mut u8,
                    Layout::from_size_align_unchecked(
                    _PAGE_SIZE * _STACK_BUCKET_PAGES,
                    _PAGE_SIZE * _STACK_BUCKET_PAGES,
                ));

                bucket = next_bucket;
            }
        }
    }
}

impl Drop for _StackBucket {
    fn drop(&mut self) {
        self.deallocate();
    }
}

#[test]
fn test_region() {
    unsafe {
        let root_stack_bucket = _StackBucket::create();
        let r1 = _Region::create(&*_Page::get_page(root_stack_bucket as usize));
        {
            let r2 = _Region::create(r1.page);
            {
                let _ = _Region::create(r2.page);
            }
        }
        (*root_stack_bucket).deallocate();
    }
    unsafe {
        let root_stack_bucket = _StackBucket::create();

        let mut r = _Region::create(&*_Page::get_page(root_stack_bucket as usize));
        for _ in 1.._STACK_BUCKET_PAGES * 2 {
            r = _Region::create(r.page);
        }

        (*root_stack_bucket).deallocate();
    }
}
<commit_msg>rustfmt<commit_after>use scaly::memory::page::_Page;
use scaly::memory::page::_PAGE_SIZE;
use std::alloc::alloc;
use std::alloc::dealloc;
use std::alloc::Layout;
use std::mem::size_of;
use std::ptr::null_mut;

const _STACK_BUCKET_PAGES: usize = 0x100;

pub struct _Region<'a> {
    page: &'a mut _Page,
}

impl<'a> _Region<'a> {
    pub fn create(page: &_Page) -> _Region<'a> {
        let our_page_address = _StackBucket::new_page(page);
        _Region {
            page: unsafe { &mut *(our_page_address as *mut _Page) },
        }
    }
}

impl<'a> Drop for _Region<'a> {
    fn drop(&mut self) {
        self.page.deallocate_extensions();
    }
}

struct _StackBucket {
    next_bucket: *mut _StackBucket,
}

impl _StackBucket {
    pub fn new_page(page: &_Page) -> *mut _Page {
        let page_address = page as *const _Page as usize;
        let stack_bucket_page_address = page_address & !(_PAGE_SIZE * _STACK_BUCKET_PAGES - 1);
        _StackBucket::get_next_page(stack_bucket_page_address, page_address)
    }

    fn get_next_page(stack_bucket_page_address: usize, page_address: usize) -> *mut _Page {
        let overflowed_page_address = stack_bucket_page_address + _PAGE_SIZE * _STACK_BUCKET_PAGES;
        let our_page_address = page_address + _PAGE_SIZE;
        if overflowed_page_address == our_page_address {
            let stack_bucket =
                (stack_bucket_page_address + size_of::<_Page>()) as *mut _StackBucket;
            unsafe { (*stack_bucket).get_page_from_next_bucket() }
        } else {
            our_page_address as *mut _Page
        }
    }

    fn get_page_from_next_bucket(self: &mut _StackBucket) -> *mut _Page {
        if self.next_bucket == null_mut() {
            self.next_bucket = _StackBucket::create();
        }
        _Page::get_page(self.next_bucket as usize)
    }

    fn create() -> *mut _StackBucket {
        unsafe {
            let memory = alloc(Layout::from_size_align_unchecked(
                _PAGE_SIZE * _STACK_BUCKET_PAGES,
                _PAGE_SIZE * _STACK_BUCKET_PAGES,
            ));
            if memory == null_mut() {
                panic!("Unable to crete a new stack bucket: Out of memory.");
            }
            let page = &mut *(memory as *mut _Page);
            page.reset();
            let bucket = page.allocate(_StackBucket {
                next_bucket: null_mut(),
            });
            bucket
        }
    }

    pub fn deallocate(&self) {
        let mut bucket = self as *const _StackBucket;
        unsafe {
            while !(*bucket).next_bucket.is_null() {
                let next_bucket = (*bucket).next_bucket;
                let page = _Page::get_page(bucket as usize);
                dealloc(
                    page as *mut u8,
                    Layout::from_size_align_unchecked(
                        _PAGE_SIZE * _STACK_BUCKET_PAGES,
                        _PAGE_SIZE * _STACK_BUCKET_PAGES,
                    ),
                );

                bucket = next_bucket;
            }
        }
    }
}

impl Drop for _StackBucket {
    fn drop(&mut self) {
        self.deallocate();
    }
}

#[test]
fn test_region() {
    unsafe {
        let root_stack_bucket = _StackBucket::create();
        let r1 = _Region::create(&*_Page::get_page(root_stack_bucket as usize));
        {
            let r2 = _Region::create(r1.page);
            {
                let _ = _Region::create(r2.page);
            }
        }
        (*root_stack_bucket).deallocate();
    }
    unsafe {
        let root_stack_bucket = _StackBucket::create();

        let mut r = _Region::create(&*_Page::get_page(root_stack_bucket as usize));
        for _ in 1.._STACK_BUCKET_PAGES * 2 {
            r = _Region::create(r.page);
        }

        (*root_stack_bucket).deallocate();
    }
}
<|endoftext|>


<commit_before>// Chapter 1
// ------------------ print macros start ------------------
// Macros: Macros look like functions, except that their name ends with a bang !,
// but instead of generating a function call, macros are expanded into source code
// that gets compiled with the rest of the program. eg. println!
// println! -> prints statement to console in a new line

// !!!--- start uncommenting from line below ---!!!
// fn main() {
//     println!("April has {} days.", 31);
//     println!("{month} has {numberOfDays} days.",
//         month = "January",
//         numberOfDays = "31");
//     // Special formating is used here
//     // {:b} -> converts 2 to 10 (binary form)
//     println!("{} of {:b} people know binary, the other half doesn't", 1, 2);
//     let width = 6;
//     println!("{number:>width$} {spaces} spaces and {number}", number = 1, width = width, spaces = width - 1);
//     println!("{}", format!("{:05}", 12));

//     // rounds off the number
//     let pi = 3.141592;
//     println!("Pi is roughly {:.3}", pi);
// }
// !!!--- end uncommenting from line above ---!!!
// ------------------ print macros end ------------------

// Chapter 2
// ------------------ Debugging start ------------------
// In JS we use console.log() for logging and debugging purposes.
// console.log() can be used to print pretty any type of object.
// However, in Rust this is not possible as all types which want to use
// std::fmt formatting traits require an implementation to be printable.
// The fmt::Debug trait makes this very straightforward.
// All types can derive (automatically create) the fmt::Debug implementation.
// This is not true for fmt::Display which must be manually implemented.
// Below given example shows automatic derive(Debug) implementation
// and manual Display implementation.

// !!!--- start uncommenting from line below ---!!!
// Import (via `use`) the `fmt` module to make it available.
use std::fmt; // Import `fmt`
#[derive(Debug)]
struct Person<'a> {
    name: &'a str,
    age: u8
}

// Implement `Display` for `Person`.
impl<'a> fmt::Display for Person<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Try `write!` to see if it errors. If it errors, return
        // the error. Otherwise continue.
        write!(f, "(Name is {} and Age is {})", self.name, self.age)?;
        write!(f, "")
    }
}
fn main() {
    let name = "Peter";
    let age = 27;
    let peter = Person { name, age };

    println!("Compare Person");
    println!("Debug: Normal {:?}", peter);
    println!("Debug: Pretty {:#?}", peter);
    println!("Display: {}", peter);
}
// !!!--- end uncommenting from line above ---!!!
// ------------------ Debugging end ------------------<commit_msg>add another example for implementing Display<commit_after>// Chapter 1
// ------------------ print macros start ------------------
// Macros: Macros look like functions, except that their name ends with a bang !,
// but instead of generating a function call, macros are expanded into source code
// that gets compiled with the rest of the program. eg. println!
// println! -> prints statement to console in a new line

// !!!--- start uncommenting from line below ---!!!
// fn main() {
//     println!("April has {} days.", 31);
//     println!("{month} has {numberOfDays} days.",
//         month = "January",
//         numberOfDays = "31");
//     // Special formating is used here
//     // {:b} -> converts 2 to 10 (binary form)
//     println!("{} of {:b} people know binary, the other half doesn't", 1, 2);
//     let width = 6;
//     println!("{number:>width$} {spaces} spaces and {number}", number = 1, width = width, spaces = width - 1);
//     println!("{}", format!("{:05}", 12));

//     // rounds off the number
//     let pi = 3.141592;
//     println!("Pi is roughly {:.3}", pi);
// }
// !!!--- end uncommenting from line above ---!!!
// ------------------ print macros end ------------------

// Chapter 2
// ------------------ Debugging start ------------------
// In JS we use console.log() for logging and debugging purposes.
// console.log() can be used to print pretty any type of object.
// However, in Rust this is not possible as all types which want to use
// std::fmt formatting traits require an implementation to be printable.
// The fmt::Debug trait makes this very straightforward.
// All types can derive (automatically create) the fmt::Debug implementation.
// This is not true for fmt::Display which must be manually implemented.
// Below given example shows automatic derive(Debug) implementation
// and manual Display implementation.

// !!!--- start uncommenting from line below ---!!!
// Import (via `use`) the `fmt` module to make it available.
use std::fmt::{self, Formatter, Display};
#[derive(Debug)]
struct Person<'a> {
    name: &'a str,
    age: u8
}

// Implement `Display` for `Person`.
impl<'a> fmt::Display for Person<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Try `write!` to see if it errors. If it errors, return
        // the error. Otherwise continue.
        write!(f, "(Name is {} and Age is {})", self.name, self.age)?;
        write!(f, "")
    }
}

#[derive(Debug)]
struct Color {
    red: u8,
    green: u8,
    blue: u8,
}

impl Display for Color {
    // `f` is a buffer, this method must write the formatted string into it
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        // `write!` is like `format!`, but it will write the formatted string
        // into a buffer (the first argument)
        write!(f, "RGB ({}, {}, {}) 0x{:02.X}{:02.X}{:02.X}",
            self.red, self.green, self.blue, self.red, self.green, self.blue)
    }
}

fn main() {
    let name = "Peter";
    let age = 27;
    let peter = Person { name, age };

    println!("Compare Person");
    println!("Debug: Normal {:?}", peter);
    println!("Debug: Pretty {:#?}", peter);
    println!("Display: {}", peter);

    for color in [
        Color { red: 128, green: 255, blue: 90 },
        Color { red: 0, green: 3, blue: 254 },
        Color { red: 0, green: 0, blue: 0 },
    ].iter() {
        // Switch this to use {} once you've added an implementation
        // for fmt::Display
        println!("{:}", *color);
    }
}
// !!!--- end uncommenting from line above ---!!!
// ------------------ Debugging end ------------------<|endoftext|>


<commit_before>fn main() {

    // ------------------ print macros start ------------------
    // Macros: Macros look like functions, except that their name ends with a bang !,
    // but instead of generating a function call, macros are expanded into source code
    // that gets compiled with the rest of the program. eg. println!
    // println! -> prints statement to console in a new line

    println!("April has {} days.", 31);
    println!("{month} has {numberOfDays} days.",
        month = "January",
        numberOfDays = "31");
    // Special formating is used here
    // {:b} -> converts 2 to 10 (binary form)
    println!("{} of {:b} people know binary, the other half doesn't", 1, 2);
    let width = 6;
    println!("{number:>width$} {spaces} spaces and {number}", number = 1, width = width, spaces = width - 1);
    println!("{}", format!("{:05}", 12));

    // rounds off the number
    let pi = 3.141592;
    println!("Pi is roughly {:.3}", pi);
    // ------------------ print macros end ------------------

}<commit_msg>add code for debugging<commit_after>// Chapter 1
// ------------------ print macros start ------------------
// Macros: Macros look like functions, except that their name ends with a bang !,
// but instead of generating a function call, macros are expanded into source code
// that gets compiled with the rest of the program. eg. println!
// println! -> prints statement to console in a new line

// !!!--- start uncommenting from line below ---!!!
// fn main() {
//     println!("April has {} days.", 31);
//     println!("{month} has {numberOfDays} days.",
//         month = "January",
//         numberOfDays = "31");
//     // Special formating is used here
//     // {:b} -> converts 2 to 10 (binary form)
//     println!("{} of {:b} people know binary, the other half doesn't", 1, 2);
//     let width = 6;
//     println!("{number:>width$} {spaces} spaces and {number}", number = 1, width = width, spaces = width - 1);
//     println!("{}", format!("{:05}", 12));

//     // rounds off the number
//     let pi = 3.141592;
//     println!("Pi is roughly {:.3}", pi);
// }
// !!!--- end uncommenting from line above ---!!!
// ------------------ print macros end ------------------

// Chapter 2
// ------------------ Debugging start ------------------
// In JS we use console.log() for logging and debugging purposes.
// console.log() can be used to print pretty any type of object.
// However, in Rust this is not possible as all types which want to use
// std::fmt formatting traits require an implementation to be printable.
// The fmt::Debug trait makes this very straightforward.
// All types can derive (automatically create) the fmt::Debug implementation.
// This is not true for fmt::Display which must be manually implemented.

// !!!--- start uncommenting from line below ---!!!
#[derive(Debug)]
struct Person<'a> {
    name: &'a str,
    age: u8
}
fn main() {
    let name = "Peter";
    let age = 27;
    let peter = Person { name, age };

    // Pretty print
    println!("{:#?}", peter);
}
// !!!--- end uncommenting from line above ---!!!
// ------------------ Debugging end ------------------<|endoftext|>


<commit_before>//! BookmarkCollection module
//!
//! A BookmarkCollection is nothing more than a simple store entry. One can simply call functions
//! from the libimagentrylink::external::ExternalLinker trait on this to generate external links.
//!
//! The BookmarkCollection type offers helper functions to get all links or such things.
use std::ops::Deref;
use std::ops::DerefMut;

use regex::Regex;

use error::BookmarkError as BE;
use error::BookmarkErrorKind as BEK;
use error::MapErrInto;
use result::Result;
use module_path::ModuleEntryPath;

use libimagstore::store::Store;
use libimagstore::storeid::IntoStoreId;
use libimagstore::store::FileLockEntry;
use libimagentrylink::external::ExternalLinker;
use libimagentrylink::internal::InternalLinker;
use libimagentrylink::internal::Link as StoreLink;
use libimagerror::into::IntoError;
use url::Url;

use link::Link;

pub struct BookmarkCollection<'a> {
    fle: FileLockEntry<'a>,
    store: &'a Store,
}

/// {Internal, External}Linker is implemented as Deref is implemented
impl<'a> Deref for BookmarkCollection<'a> {
    type Target = FileLockEntry<'a>;

    fn deref(&self) -> &FileLockEntry<'a> {
        &self.fle
    }

}

impl<'a> DerefMut for BookmarkCollection<'a> {

    fn deref_mut(&mut self) -> &mut FileLockEntry<'a> {
        &mut self.fle
    }

}

impl<'a> BookmarkCollection<'a> {

    pub fn new(store: &'a Store, name: &str) -> Result<BookmarkCollection<'a>> {
        let id = ModuleEntryPath::new(name).into_storeid();
        store.create(id)
            .map(|fle| {
                BookmarkCollection {
                    fle: fle,
                    store: store,
                }
            })
            .map_err_into(BEK::StoreReadError)
    }

    pub fn get(store: &'a Store, name: &str) -> Result<BookmarkCollection<'a>> {
        let id = ModuleEntryPath::new(name).into_storeid();
        store.get(id)
            .map_err_into(BEK::StoreReadError)
            .and_then(|fle| {
                match fle {
                    None => Err(BEK::CollectionNotFound.into_error()),
                    Some(e) => Ok(BookmarkCollection {
                        fle: e,
                        store: store,
                    }),
                }
            })
    }

    pub fn delete(store: &Store, name: &str) -> Result<()> {
        store.delete(ModuleEntryPath::new(name).into_storeid()).map_err_into(BEK::StoreReadError)
    }

    pub fn links(&self) -> Result<Vec<Url>> {
        self.fle.get_external_links(&self.store).map_err_into(BEK::LinkError)
    }

    pub fn link_entries(&self) -> Result<Vec<StoreLink>> {
        use libimagentrylink::external::is_external_link_storeid;

        self.fle
            .get_internal_links()
            .map(|v| v.into_iter().filter(|id| is_external_link_storeid(id)).collect())
            .map_err_into(BEK::StoreReadError)
    }

    pub fn add_link(&mut self, l: Link) -> Result<()> {
        use link::IntoUrl;

        l.into_url()
            .and_then(|url| self.add_external_link(self.store, url).map_err_into(BEK::LinkingError))
            .map_err_into(BEK::LinkError)
    }

    pub fn get_link(&self, l: Link) -> Result<Link> {
        unimplemented!()
    }

    pub fn get_links_matching(&self, r: Regex) -> Result<Link> {
        unimplemented!()
    }

    pub fn remove_link(&self, l: Link) -> Result<()> {
        unimplemented!()
    }

}

<commit_msg>fixup for 9231cf5f<commit_after>//! BookmarkCollection module
//!
//! A BookmarkCollection is nothing more than a simple store entry. One can simply call functions
//! from the libimagentrylink::external::ExternalLinker trait on this to generate external links.
//!
//! The BookmarkCollection type offers helper functions to get all links or such things.
use std::ops::Deref;
use std::ops::DerefMut;

use regex::Regex;

use error::BookmarkError as BE;
use error::BookmarkErrorKind as BEK;
use error::MapErrInto;
use result::Result;
use module_path::ModuleEntryPath;

use libimagstore::store::Store;
use libimagstore::storeid::IntoStoreId;
use libimagstore::store::FileLockEntry;
use libimagentrylink::external::ExternalLinker;
use libimagentrylink::internal::InternalLinker;
use libimagentrylink::internal::Link as StoreLink;
use libimagerror::into::IntoError;
use url::Url;

use link::Link;

pub struct BookmarkCollection<'a> {
    fle: FileLockEntry<'a>,
    store: &'a Store,
}

/// {Internal, External}Linker is implemented as Deref is implemented
impl<'a> Deref for BookmarkCollection<'a> {
    type Target = FileLockEntry<'a>;

    fn deref(&self) -> &FileLockEntry<'a> {
        &self.fle
    }

}

impl<'a> DerefMut for BookmarkCollection<'a> {

    fn deref_mut(&mut self) -> &mut FileLockEntry<'a> {
        &mut self.fle
    }

}

impl<'a> BookmarkCollection<'a> {

    pub fn new(store: &'a Store, name: &str) -> Result<BookmarkCollection<'a>> {
        let id = ModuleEntryPath::new(name).into_storeid();
        store.create(id)
            .map(|fle| {
                BookmarkCollection {
                    fle: fle,
                    store: store,
                }
            })
            .map_err_into(BEK::StoreReadError)
    }

    pub fn get(store: &'a Store, name: &str) -> Result<BookmarkCollection<'a>> {
        let id = ModuleEntryPath::new(name).into_storeid();
        store.get(id)
            .map_err_into(BEK::StoreReadError)
            .and_then(|fle| {
                match fle {
                    None => Err(BEK::CollectionNotFound.into_error()),
                    Some(e) => Ok(BookmarkCollection {
                        fle: e,
                        store: store,
                    }),
                }
            })
    }

    pub fn delete(store: &Store, name: &str) -> Result<()> {
        store.delete(ModuleEntryPath::new(name).into_storeid()).map_err_into(BEK::StoreReadError)
    }

    pub fn links(&self) -> Result<Vec<Url>> {
        self.fle.get_external_links(&self.store).map_err_into(BEK::LinkError)
    }

    pub fn link_entries(&self) -> Result<Vec<StoreLink>> {
        use libimagentrylink::external::is_external_link_storeid;

        self.fle
            .get_internal_links()
            .map(|v| v.into_iter().filter(|id| is_external_link_storeid(id)).collect())
            .map_err_into(BEK::StoreReadError)
    }

    pub fn add_link(&mut self, l: Link) -> Result<()> {
        use link::IntoUrl;

        l.into_url()
            .and_then(|url| self.add_external_link(self.store, url).map_err_into(BEK::LinkingError))
            .map_err_into(BEK::LinkError)
    }

    pub fn get_links_matching(&self, r: Regex) -> Result<Link> {
        unimplemented!()
    }

    pub fn remove_link(&self, l: Link) -> Result<()> {
        unimplemented!()
    }

}

<|endoftext|>


<commit_before>use std::env;
use std::process::Command;

#[cfg(not(feature = "rustc-dep-of-std"))]
fn build() {
	#[cfg(windows)]
	let out_dir = env::temp_dir().to_str().unwrap().to_owned();
	#[cfg(not(windows))]
	let out_dir = env::var("OUT_DIR").unwrap();
	let profile = env::var("PROFILE").expect("PROFILE was not set");

	let _output = Command::new("cargo")
		.current_dir(out_dir.clone())
		.arg("download")
		.arg("--output")
		.arg(out_dir.clone() + "/rusty-hermit")
		.arg("--extract")
		.arg("rusty-hermit")
		.output()
		.expect("Unable to download rusty-hermit. Please install `cargo-download`.");

	let mut cmd = Command::new("cargo")
	cmd.current_dir(out_dir.clone() + "/rusty-hermit")
		.arg("build")
		.arg("-Z")
		.arg("build-std=core,alloc")
		.arg("--target")
		.arg("x86_64-unknown-hermit-kernel");

	if profile == "release" {
		cmd.arg("--release");
	}

	#[cfg(feature = "instrument")]
	cmd.env("RUSTFLAGS", "-Z instrument-mcount");
	// if instrument is not set, ensure that instrument is not in environment variables!
	#[cfg(not(feature = "instrument"))]
	cmd.env(
		"RUSTFLAGS",
		env::var("RUSTFLAGS")
			.unwrap_or("".into())
			.replace("-Z instrument-mcount", ""),
	);

	cmd.output().expect("Unable to build kernel");

	println!(
		"cargo:rustc-link-search=native={}/rusty-hermit/target/x86_64-unknown-hermit-kernel/{}",
		out_dir.clone(),
		profile
	);
	println!("cargo:rustc-link-lib=static=hermit");
}

fn main() {
	#[cfg(not(feature = "rustc-dep-of-std"))]
	build();
}
<commit_msg>fix syntax error<commit_after>use std::env;
use std::process::Command;

#[cfg(not(feature = "rustc-dep-of-std"))]
fn build() {
	#[cfg(windows)]
	let out_dir = env::temp_dir().to_str().unwrap().to_owned();
	#[cfg(not(windows))]
	let out_dir = env::var("OUT_DIR").unwrap();
	let profile = env::var("PROFILE").expect("PROFILE was not set");

	let _output = Command::new("cargo")
		.current_dir(out_dir.clone())
		.arg("download")
		.arg("--output")
		.arg(out_dir.clone() + "/rusty-hermit")
		.arg("--extract")
		.arg("rusty-hermit")
		.output()
		.expect("Unable to download rusty-hermit. Please install `cargo-download`.");

	let mut cmd = Command::new("cargo");
	cmd.current_dir(out_dir.clone() + "/rusty-hermit")
		.arg("build")
		.arg("-Z")
		.arg("build-std=core,alloc")
		.arg("--target")
		.arg("x86_64-unknown-hermit-kernel");

	if profile == "release" {
		cmd.arg("--release");
	}

	#[cfg(feature = "instrument")]
	cmd.env("RUSTFLAGS", "-Z instrument-mcount");
	// if instrument is not set, ensure that instrument is not in environment variables!
	#[cfg(not(feature = "instrument"))]
	cmd.env(
		"RUSTFLAGS",
		env::var("RUSTFLAGS")
			.unwrap_or("".into())
			.replace("-Z instrument-mcount", ""),
	);

	cmd.output().expect("Unable to build kernel");

	println!(
		"cargo:rustc-link-search=native={}/rusty-hermit/target/x86_64-unknown-hermit-kernel/{}",
		out_dir.clone(),
		profile
	);
	println!("cargo:rustc-link-lib=static=hermit");
}

fn main() {
	#[cfg(not(feature = "rustc-dep-of-std"))]
	build();
}
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Local state for known snapshots.

use process;

use sqlite3::database::{Database};
use sqlite3::types::{SQLITE_DONE, SQLITE_OK, Blob};
use sqlite3::{open};

use hash_index;

pub type SnapshotIndexProcess = process::Process<Msg, Reply, SnapshotIndex>;

pub enum Msg {
  /// Register a new snapshot by its hash and persistent reference.
  Add(String, hash_index::Hash, Vec<u8>),

  /// Flush the hash index to clear internal buffers and commit the underlying database.
  Flush,
}

pub enum Reply {
  AddOK,
  FlushOK,
}

pub struct SnapshotIndex {
  dbh: Database,
}

impl SnapshotIndex {

  pub fn new(path: String) -> SnapshotIndex {
    let mut si = match open(path.as_slice()) {
      Ok(dbh) => { SnapshotIndex{dbh: dbh} },
      Err(err) => fail!(err.to_string()),
    };
    si.exec_or_die("CREATE TABLE IF NOT EXISTS
                    snapshot_index (id        INTEGER PRIMARY KEY,
                                    family    BLOB,
                                    hash      BLOB,
                                    tree_ref  BLOB)");
    si.exec_or_die("BEGIN");
    si
  }

  #[cfg(test)]
  pub fn new_for_testing() -> HashIndex {
    SnapshotIndex::new(":memory:".to_string())
  }

  fn exec_or_die(&mut self, sql: &str) {
    match self.dbh.exec(sql) {
      Ok(true) => (),
      Ok(false) => fail!("exec: {}", self.dbh.get_errmsg()),
      Err(msg) => fail!(format!("exec: {}, {}\nIn sql: '{}'\n",
                                msg.to_string(), self.dbh.get_errmsg(), sql))
    }
  }

  fn add_snapshot(&mut self, family: String, hash: hash_index::Hash, tree_ref: Vec<u8>) {
    let mut insert_stm = self.dbh.prepare(
      "INSERT INTO snapshot_index (family, hash, tree_ref) VALUES (?, ?, ?)", &None).unwrap();

    assert_eq!(SQLITE_OK, insert_stm.bind_param(1, &Blob(family.as_bytes().into_vec())));
    assert_eq!(SQLITE_OK, insert_stm.bind_param(2, &Blob(hash.bytes.clone())));
    assert_eq!(SQLITE_OK, insert_stm.bind_param(3, &Blob(tree_ref)));

    assert_eq!(SQLITE_DONE, insert_stm.step());
  }

  fn flush(&mut self) {
    // Callbacks assume their data is safe, so commit before calling them
    self.exec_or_die("COMMIT; BEGIN");
  }
}

impl process::MsgHandler<Msg, Reply> for SnapshotIndex {
  fn handle(&mut self, msg: Msg, reply: |Reply|) {
    match msg {

      Add(name, hash, tree_ref) => {
        self.add_snapshot(name, hash, tree_ref);
        return reply(AddOK);
      },

      Flush => {
        self.flush();
        return reply(FlushOK);
      }
    }
  }
}
<commit_msg>Correct type for SnapshotIndex's new_for_testing(). Fixes compile failure for tests.<commit_after>// Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Local state for known snapshots.

use process;

use sqlite3::database::{Database};
use sqlite3::types::{SQLITE_DONE, SQLITE_OK, Blob};
use sqlite3::{open};

use hash_index;

pub type SnapshotIndexProcess = process::Process<Msg, Reply, SnapshotIndex>;

pub enum Msg {
  /// Register a new snapshot by its hash and persistent reference.
  Add(String, hash_index::Hash, Vec<u8>),

  /// Flush the hash index to clear internal buffers and commit the underlying database.
  Flush,
}

pub enum Reply {
  AddOK,
  FlushOK,
}

pub struct SnapshotIndex {
  dbh: Database,
}

impl SnapshotIndex {

  pub fn new(path: String) -> SnapshotIndex {
    let mut si = match open(path.as_slice()) {
      Ok(dbh) => { SnapshotIndex{dbh: dbh} },
      Err(err) => fail!(err.to_string()),
    };
    si.exec_or_die("CREATE TABLE IF NOT EXISTS
                    snapshot_index (id        INTEGER PRIMARY KEY,
                                    family    BLOB,
                                    hash      BLOB,
                                    tree_ref  BLOB)");
    si.exec_or_die("BEGIN");
    si
  }

  #[cfg(test)]
  pub fn new_for_testing() -> SnapshotIndex {
    SnapshotIndex::new(":memory:".to_string())
  }

  fn exec_or_die(&mut self, sql: &str) {
    match self.dbh.exec(sql) {
      Ok(true) => (),
      Ok(false) => fail!("exec: {}", self.dbh.get_errmsg()),
      Err(msg) => fail!(format!("exec: {}, {}\nIn sql: '{}'\n",
                                msg.to_string(), self.dbh.get_errmsg(), sql))
    }
  }

  fn add_snapshot(&mut self, family: String, hash: hash_index::Hash, tree_ref: Vec<u8>) {
    let mut insert_stm = self.dbh.prepare(
      "INSERT INTO snapshot_index (family, hash, tree_ref) VALUES (?, ?, ?)", &None).unwrap();

    assert_eq!(SQLITE_OK, insert_stm.bind_param(1, &Blob(family.as_bytes().into_vec())));
    assert_eq!(SQLITE_OK, insert_stm.bind_param(2, &Blob(hash.bytes.clone())));
    assert_eq!(SQLITE_OK, insert_stm.bind_param(3, &Blob(tree_ref)));

    assert_eq!(SQLITE_DONE, insert_stm.step());
  }

  fn flush(&mut self) {
    // Callbacks assume their data is safe, so commit before calling them
    self.exec_or_die("COMMIT; BEGIN");
  }
}

impl process::MsgHandler<Msg, Reply> for SnapshotIndex {
  fn handle(&mut self, msg: Msg, reply: |Reply|) {
    match msg {

      Add(name, hash, tree_ref) => {
        self.add_snapshot(name, hash, tree_ref);
        return reply(AddOK);
      },

      Flush => {
        self.flush();
        return reply(FlushOK);
      }
    }
  }
}
<|endoftext|>


<commit_before>macro_rules! w {
    ($buf:expr, $to_w:expr) => {
        match $buf.write_all($to_w) {
            Ok(..) => (),
            Err(..) => panic!("Failed to write to generated file"),
        }
    };
}

#[cfg(feature = "debug")]
macro_rules! debug {
    ($($arg:tt)*) => {
        print!("[{:>w$}] \t", module_path!(), w = 28);
        println!($($arg)*)
    }
}

#[cfg(not(feature = "debug"))]
macro_rules! debug {
    ($($arg:tt)*) => {};
}
<commit_msg>fix(complete): Send debug statements to stderr<commit_after>macro_rules! w {
    ($buf:expr, $to_w:expr) => {
        match $buf.write_all($to_w) {
            Ok(..) => (),
            Err(..) => panic!("Failed to write to generated file"),
        }
    };
}

#[cfg(feature = "debug")]
macro_rules! debug {
    ($($arg:tt)*) => {
        eprint!("[{:>w$}] \t", module_path!(), w = 28);
        eprintln!($($arg)*)
    }
}

#[cfg(not(feature = "debug"))]
macro_rules! debug {
    ($($arg:tt)*) => {};
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

#[derive(Debug)]
pub struct ParamMetadata {
    name: &'static str,
    is_optional: bool,
    help: &'static str,
}

impl ParamMetadata {
    pub fn new(name: &'static str, is_optional: bool, help: &'static str) -> ParamMetadata {
        ParamMetadata {
            name,
            is_optional,
            help
        }
    }

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

    pub fn is_optional(&self) -> bool {
        self.is_optional
    }

    pub fn help(&self) -> &'static str {
        self.help
    }
}

#[derive(Debug)]
pub struct CommandMetadata {
    name: &'static str,
    help: &'static str,
    main_param: Option<ParamMetadata>,
    params: Vec<ParamMetadata>,
}

impl CommandMetadata {
    pub fn build(name: &'static str, help: &'static str) -> CommandMetadataBuilder {
        CommandMetadataBuilder {
            name,
            help,
            main_param: None,
            params: Vec::new(),
        }
    }

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

    pub fn help(&self) -> &'static str {
        self.help
    }

    pub fn main_param(&self) -> Option<&ParamMetadata> {
        self.main_param.as_ref()
    }

    pub fn params(&self) -> &[ParamMetadata] {
        self.params.as_slice()
    }
}

pub struct CommandMetadataBuilder {
    help: &'static str,
    name: &'static str,
    main_param: Option<ParamMetadata>,
    params: Vec<ParamMetadata>,
}

impl CommandMetadataBuilder {
    pub fn add_main_param(mut self,
                          name: &'static str,
                          help: &'static str) -> CommandMetadataBuilder {
        self.main_param = Some(ParamMetadata::new(name, false, help));
        self
    }

    pub fn add_param(mut self,
                     name: &'static str,
                     is_optional: bool,
                     help: &'static str) -> CommandMetadataBuilder {
        self.params.push(ParamMetadata::new(name, is_optional, help));
        self
    }

    pub fn finalize(self) -> CommandMetadata {
        CommandMetadata {
            name: self.name,
            help: self.help,
            main_param: self.main_param,
            params: self.params,
        }
    }
}

pub trait Command {
    fn metadata(&self) -> &CommandMetadata;
    fn execute(&self, params: &HashMap<&'static str, &str>) -> Result<(), ()>;
}

#[derive(Debug)]
pub struct GroupMetadata {
    name: &'static str,
    help: &'static str,
}

impl GroupMetadata {
    pub fn new(name: &'static str, help: &'static str) -> GroupMetadata {
        GroupMetadata {
            name,
            help
        }
    }
}

impl GroupMetadata {
    pub fn name(&self) -> &'static str {
        self.name
    }
    pub fn help(&self) -> &'static str {
        self.help
    }
}

pub trait Group {
    fn metadata(&self) -> &GroupMetadata;
}

pub struct CommandExecutor {
    commands: HashMap<&'static str, Box<Command>>,
    grouped_commands: HashMap<&'static str, (Box<Group>, HashMap<&'static str, Box<Command>>)>,
}

impl CommandExecutor {
    pub fn build() -> CommandExecutorBuilder {
        CommandExecutorBuilder {
            commands: HashMap::new(),
            grouped_commands: HashMap::new(),
        }
    }

    pub fn execute(&self, line: &str) -> Result<(), ()> {
        let (cmd, params) = CommandExecutor::_split_first_word(line);

        if cmd == "help" {
            self._print_help();
            return Ok(());
        }

        if let Some(&(ref group, ref commands)) = self.grouped_commands.get(cmd) {
            return self._execute_group_command(group, commands, params);
        }

        if let Some(ref command) = self.commands.get(cmd) {
            return self._execute_command(None, command, params);
        }

        println_err!("Unknown group or command \"{}\"", cmd);
        println!("Type \"help\" to display the help");
        Err(())
    }

    fn _execute_group_command(&self, group: &Box<Group>, commands: &HashMap<&'static str, Box<Command>>, line: &str) -> Result<(), ()> {
        let (cmd, params) = CommandExecutor::_split_first_word(line);

        if cmd == "help" {
            self._print_group_help(group, commands);
            return Ok(());
        }

        if let Some(ref command) = commands.get(cmd) {
            return self._execute_command(Some(group), command, params);
        }

        println_err!("Unknown command \"{} {}\"", group.metadata().name(), cmd);
        println!("Type \"{} help\" to display the help for \"{}\" group", group.metadata().name(), group.metadata().name());
        Err(())
    }

    fn _execute_command(&self, group: Option<&Box<Group>>, command: &Box<Command>, params: &str) -> Result<(), ()> {
        let (main_param, _) = CommandExecutor::_split_first_word(params);

        if main_param == "help" {
            self._print_command_help(group, command);
            return Ok(());
        }

        match CommandExecutor::_parse_params(command.metadata(), params) {
            Ok(ref params) => command.execute(params),
            Err(ref err) => {
                println_err!("{}", err);
                if group.is_some() {
                    println!("Type \"{} {} help\" to display the help for \"{} {}\" command",
                             group.unwrap().metadata().name(), command.metadata().name(),
                             group.unwrap().metadata().name(), command.metadata().name());
                } else {
                    println!("Type \"{} help\" to display the help for \"{}\" command",
                             command.metadata().name(),
                             command.metadata().name());
                }
                Err(())
            }
        }
    }

    fn _print_help(&self) {
        println_acc!("Hyperledger Indy CLI");
        println!();
        println_acc!("Usage:");
        println!("\t[<command-group>] <command> [[<main-param-name>=]<main-param-value>] [<param_name-1>=<param_value-1>]...[<param_name-n>=<param_value-n>]");
        println!();
        println_acc!("Getting help:");
        println!("\thelp - Display this help");
        println!("\t<command-group> help - Display the help for the specific command group");
        println!("\t[<command-group>] <command> help - Display the help for the specific command");
        println!();
        println_acc!("Command groups are:");

        for (_, &(ref group, _)) in &self.grouped_commands {
            println!("\t{} - {}", group.metadata().name(), group.metadata().help())
        }

        println!();
        println_acc!("Top level commands are:");

        for (_, ref command) in &self.commands {
            println!("\t{} - {}", command.metadata().name(), command.metadata().help())
        }

        println!();
    }

    fn _print_group_help(&self, group: &Box<Group>, commands: &HashMap<&'static str, Box<Command>>) {
        println_acc!("Group:");
        println!("\t{} - {}", group.metadata().name(), group.metadata().help());
        println!();
        println_acc!("Usage:");
        println!("\t{} <command> [[<main-param-name>=]<main-param-value>] [<param_name-1>=<param_value-1>]...[<param_name-n>=<param_value-n>]", group.metadata().name());
        println!();
        println_acc!("Getting help:");
        println!("\t{} <command> help - Display the help for the specific command", group.metadata().name());
        println!();
        println_acc!("Group commands are:");

        for (_, ref command) in commands {
            println!("\t{} - {}", command.metadata().name(), command.metadata().help())
        }

        println!();
    }

    fn _print_command_help(&self, group: Option<&Box<Group>>, command: &Box<Command>) {
        println_acc!("Command:");

        if let Some(group) = group {
            println!("\t{} {} - {}", group.metadata().name(), command.metadata().name(), command.metadata().help());
        } else {
            println!("\t{} - {}", command.metadata().name(), command.metadata().help());
        }

        println!();
        println!();
        println_acc!("Usage:");

        if let Some(group) = group {
            print!("\t{} {}", group.metadata().name(), command.metadata().name());
        } else {
            print!("\t{}", command.metadata().name());
        }

        if let Some(ref main_param) = command.metadata().main_param() {
            print!(" [{}=]<{}-value>", main_param.name(), main_param.name())
        }

        for param in command.metadata().params() {
            if param.is_optional() {
                print!(" [{}=<{}-value>]", param.name(), param.name())
            } else {
                print!(" {}=<{}-value>", param.name(), param.name())
            }
        }

        println!();
        println!();
        println_acc!("Parameters are:");

        if let Some(ref main_param) = command.metadata().main_param() {
            println!("\t{} - {}", main_param.name(), main_param.help())
        }

        for param in command.metadata().params() {
            print!("\t{} - ", param.name());

            if param.is_optional() {
                print!("(optional) ")
            }

            println!("{}", param.help());
        }

        println!();
    }

    fn _parse_params<'a>(command: &CommandMetadata, params: &'a str) -> Result<HashMap<&'static str, &'a str>, String> {
        let mut res: HashMap<&'static str, &str> = HashMap::new();
        let mut params = params;

        // Read main param
        if let Some(param_metadata) = command.main_param() {
            let (param_value, tail) = CommandExecutor::_split_first_word(params);
            params = tail;

            if param_value.is_empty() {
                return Err(format!("No main \"{}\" parameter present", param_metadata.name()));
            }

            res.insert(param_metadata.name(), param_value);
        }

        // Read rest params
        loop {
            let (param, tail) = CommandExecutor::_split_first_word(params);
            params = tail;

            if param.is_empty() {
                break;
            }

            let mut split = param.splitn(2, '=');
            let param_name = split.next().unwrap();
            let param_value = split.next();
            let param_metadata = command.params().iter().find(|p| p.name() == param_name);

            if let Some(param_metadata) = param_metadata {
                if let Some(param_value) = param_value {
                    res.insert(param_metadata.name(), param_value);
                } else {
                    return Err(format!("No value for \"{}\" parameter present", param_name));
                }
            } else {
                return Err(format!("Unknown \"{}\" parameter present", param_name));
            }
        }

        Ok(res)
    }

    fn _split_first_word(s: &str) -> (&str, &str) {
        let mut is_whitespace_escape = false;
        let s = s.trim();

        for (pos, ch) in s.char_indices() {
            if ch.is_whitespace() && !is_whitespace_escape {
                return (&s[..pos], s[pos..].trim_left());
            }

            if ch == '"' {
                is_whitespace_escape = !is_whitespace_escape;
            }
        }

        (s, "")
    }
}

pub struct CommandExecutorBuilder {
    commands: HashMap<&'static str, Box<Command>>,
    grouped_commands: HashMap<&'static str, (Box<Group>, HashMap<&'static str, Box<Command>>)>,
}

impl CommandExecutorBuilder {
    pub fn add_group(self, group: Box<Group>) -> CommandExecutorGroupBuilder {
        CommandExecutorGroupBuilder {
            commands: self.commands,
            grouped_commands: self.grouped_commands,
            group,
            group_commands: HashMap::new(),
        }
    }

    pub fn add_command(mut self, command: Box<Command>) -> CommandExecutorBuilder {
        self.commands.insert(command.metadata().name, command);
        self
    }

    pub fn finalize(self) -> CommandExecutor {
        CommandExecutor {
            commands: self.commands,
            grouped_commands: self.grouped_commands,
        }
    }
}

pub struct CommandExecutorGroupBuilder {
    commands: HashMap<&'static str, Box<Command>>,
    grouped_commands: HashMap<&'static str, (Box<Group>, HashMap<&'static str, Box<Command>>)>,
    group: Box<Group>,
    group_commands: HashMap<&'static str, Box<Command>>,
}

impl CommandExecutorGroupBuilder {
    pub fn add_command(mut self, command: Box<Command>) -> CommandExecutorGroupBuilder {
        self.group_commands.insert(command.metadata().name(), command);
        self
    }

    pub fn finalize_group(mut self) -> CommandExecutorBuilder {
        self.grouped_commands.insert(self.group.metadata().name(), (self.group, self.group_commands));
        CommandExecutorBuilder {
            commands: self.commands,
            grouped_commands: self.grouped_commands,
        }
    }
}

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

    struct TestGroup {
        metadata: GroupMetadata
    }

    impl TestGroup {
        pub fn new() -> TestGroup {
            TestGroup {
                metadata: GroupMetadata::new("test_group", "Test group help")
            }
        }
    }

    impl Group for TestGroup {
        fn metadata(&self) -> &GroupMetadata {
            &self.metadata
        }
    }

    struct TestCommand {
        metadata: CommandMetadata
    }

    impl TestCommand {
        pub fn new() -> TestCommand {
            TestCommand {
                metadata: CommandMetadata::build("test_command", "Test command help")
                    .add_main_param("main_param", "Main param help")
                    .add_param("param1", false, "Param1 help")
                    .add_param("param2", true, "Param2 help")
                    .finalize()
            }
        }
    }

    impl Command for TestCommand {
        fn metadata(&self) -> &CommandMetadata {
            &self.metadata
        }

        fn execute(&self, params: &HashMap<&'static str, &str>) -> Result<(), ()> {
            println!("Test comamnd params: {:?}", params);
            Ok(())
        }
    }

    #[test]
    pub fn execute_works() {
        let cmd_executor = CommandExecutor::build()
            .add_group(Box::new(TestGroup::new()))
            .add_command(Box::new(TestCommand::new()))
            .finalize_group()
            .add_command(Box::new(TestCommand::new()))
            .finalize();
        cmd_executor.execute("test_group test_command \"main param\" param1=\"param1 value\" param2=param2-value").unwrap();
    }
}

<commit_msg>* More correct handling of quotes<commit_after>use std::collections::HashMap;

#[derive(Debug)]
pub struct ParamMetadata {
    name: &'static str,
    is_optional: bool,
    help: &'static str,
}

impl ParamMetadata {
    pub fn new(name: &'static str, is_optional: bool, help: &'static str) -> ParamMetadata {
        ParamMetadata {
            name,
            is_optional,
            help
        }
    }

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

    pub fn is_optional(&self) -> bool {
        self.is_optional
    }

    pub fn help(&self) -> &'static str {
        self.help
    }
}

#[derive(Debug)]
pub struct CommandMetadata {
    name: &'static str,
    help: &'static str,
    main_param: Option<ParamMetadata>,
    params: Vec<ParamMetadata>,
}

impl CommandMetadata {
    pub fn build(name: &'static str, help: &'static str) -> CommandMetadataBuilder {
        CommandMetadataBuilder {
            name,
            help,
            main_param: None,
            params: Vec::new(),
        }
    }

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

    pub fn help(&self) -> &'static str {
        self.help
    }

    pub fn main_param(&self) -> Option<&ParamMetadata> {
        self.main_param.as_ref()
    }

    pub fn params(&self) -> &[ParamMetadata] {
        self.params.as_slice()
    }
}

pub struct CommandMetadataBuilder {
    help: &'static str,
    name: &'static str,
    main_param: Option<ParamMetadata>,
    params: Vec<ParamMetadata>,
}

impl CommandMetadataBuilder {
    pub fn add_main_param(mut self,
                          name: &'static str,
                          help: &'static str) -> CommandMetadataBuilder {
        self.main_param = Some(ParamMetadata::new(name, false, help));
        self
    }

    pub fn add_param(mut self,
                     name: &'static str,
                     is_optional: bool,
                     help: &'static str) -> CommandMetadataBuilder {
        self.params.push(ParamMetadata::new(name, is_optional, help));
        self
    }

    pub fn finalize(self) -> CommandMetadata {
        CommandMetadata {
            name: self.name,
            help: self.help,
            main_param: self.main_param,
            params: self.params,
        }
    }
}

pub trait Command {
    fn metadata(&self) -> &CommandMetadata;
    fn execute(&self, params: &HashMap<&'static str, &str>) -> Result<(), ()>;
}

#[derive(Debug)]
pub struct GroupMetadata {
    name: &'static str,
    help: &'static str,
}

impl GroupMetadata {
    pub fn new(name: &'static str, help: &'static str) -> GroupMetadata {
        GroupMetadata {
            name,
            help
        }
    }
}

impl GroupMetadata {
    pub fn name(&self) -> &'static str {
        self.name
    }
    pub fn help(&self) -> &'static str {
        self.help
    }
}

pub trait Group {
    fn metadata(&self) -> &GroupMetadata;
}

pub struct CommandExecutor {
    commands: HashMap<&'static str, Box<Command>>,
    grouped_commands: HashMap<&'static str, (Box<Group>, HashMap<&'static str, Box<Command>>)>,
}

impl CommandExecutor {
    pub fn build() -> CommandExecutorBuilder {
        CommandExecutorBuilder {
            commands: HashMap::new(),
            grouped_commands: HashMap::new(),
        }
    }

    pub fn execute(&self, line: &str) -> Result<(), ()> {
        let (cmd, params) = CommandExecutor::_split_first_word(line);

        if cmd == "help" {
            self._print_help();
            return Ok(());
        }

        if let Some(&(ref group, ref commands)) = self.grouped_commands.get(cmd) {
            return self._execute_group_command(group, commands, params);
        }

        if let Some(ref command) = self.commands.get(cmd) {
            return self._execute_command(None, command, params);
        }

        println_err!("Unknown group or command \"{}\"", cmd);
        println!("Type \"help\" to display the help");
        Err(())
    }

    fn _execute_group_command(&self, group: &Box<Group>, commands: &HashMap<&'static str, Box<Command>>, line: &str) -> Result<(), ()> {
        let (cmd, params) = CommandExecutor::_split_first_word(line);

        if cmd == "help" {
            self._print_group_help(group, commands);
            return Ok(());
        }

        if let Some(ref command) = commands.get(cmd) {
            return self._execute_command(Some(group), command, params);
        }

        println_err!("Unknown command \"{} {}\"", group.metadata().name(), cmd);
        println!("Type \"{} help\" to display the help for \"{}\" group", group.metadata().name(), group.metadata().name());
        Err(())
    }

    fn _execute_command(&self, group: Option<&Box<Group>>, command: &Box<Command>, params: &str) -> Result<(), ()> {
        let (main_param, _) = CommandExecutor::_split_first_word(params);

        if main_param == "help" {
            self._print_command_help(group, command);
            return Ok(());
        }

        match CommandExecutor::_parse_params(command.metadata(), params) {
            Ok(ref params) => command.execute(params),
            Err(ref err) => {
                println_err!("{}", err);
                if group.is_some() {
                    println!("Type \"{} {} help\" to display the help for \"{} {}\" command",
                             group.unwrap().metadata().name(), command.metadata().name(),
                             group.unwrap().metadata().name(), command.metadata().name());
                } else {
                    println!("Type \"{} help\" to display the help for \"{}\" command",
                             command.metadata().name(),
                             command.metadata().name());
                }
                Err(())
            }
        }
    }

    fn _print_help(&self) {
        println_acc!("Hyperledger Indy CLI");
        println!();
        println_acc!("Usage:");
        println!("\t[<command-group>] <command> [[<main-param-name>=]<main-param-value>] [<param_name-1>=<param_value-1>]...[<param_name-n>=<param_value-n>]");
        println!();
        println_acc!("Getting help:");
        println!("\thelp - Display this help");
        println!("\t<command-group> help - Display the help for the specific command group");
        println!("\t[<command-group>] <command> help - Display the help for the specific command");
        println!();
        println_acc!("Command groups are:");

        for (_, &(ref group, _)) in &self.grouped_commands {
            println!("\t{} - {}", group.metadata().name(), group.metadata().help())
        }

        println!();
        println_acc!("Top level commands are:");

        for (_, ref command) in &self.commands {
            println!("\t{} - {}", command.metadata().name(), command.metadata().help())
        }

        println!();
    }

    fn _print_group_help(&self, group: &Box<Group>, commands: &HashMap<&'static str, Box<Command>>) {
        println_acc!("Group:");
        println!("\t{} - {}", group.metadata().name(), group.metadata().help());
        println!();
        println_acc!("Usage:");
        println!("\t{} <command> [[<main-param-name>=]<main-param-value>] [<param_name-1>=<param_value-1>]...[<param_name-n>=<param_value-n>]", group.metadata().name());
        println!();
        println_acc!("Getting help:");
        println!("\t{} <command> help - Display the help for the specific command", group.metadata().name());
        println!();
        println_acc!("Group commands are:");

        for (_, ref command) in commands {
            println!("\t{} - {}", command.metadata().name(), command.metadata().help())
        }

        println!();
    }

    fn _print_command_help(&self, group: Option<&Box<Group>>, command: &Box<Command>) {
        println_acc!("Command:");

        if let Some(group) = group {
            println!("\t{} {} - {}", group.metadata().name(), command.metadata().name(), command.metadata().help());
        } else {
            println!("\t{} - {}", command.metadata().name(), command.metadata().help());
        }

        println!();
        println!();
        println_acc!("Usage:");

        if let Some(group) = group {
            print!("\t{} {}", group.metadata().name(), command.metadata().name());
        } else {
            print!("\t{}", command.metadata().name());
        }

        if let Some(ref main_param) = command.metadata().main_param() {
            print!(" [{}=]<{}-value>", main_param.name(), main_param.name())
        }

        for param in command.metadata().params() {
            if param.is_optional() {
                print!(" [{}=<{}-value>]", param.name(), param.name())
            } else {
                print!(" {}=<{}-value>", param.name(), param.name())
            }
        }

        println!();
        println!();
        println_acc!("Parameters are:");

        if let Some(ref main_param) = command.metadata().main_param() {
            println!("\t{} - {}", main_param.name(), main_param.help())
        }

        for param in command.metadata().params() {
            print!("\t{} - ", param.name());

            if param.is_optional() {
                print!("(optional) ")
            }

            println!("{}", param.help());
        }

        println!();
    }

    fn _parse_params<'a>(command: &CommandMetadata, params: &'a str) -> Result<HashMap<&'static str, &'a str>, String> {
        let mut res: HashMap<&'static str, &str> = HashMap::new();
        let mut params = params;

        // Read main param
        if let Some(param_metadata) = command.main_param() {
            let (param_value, tail) = CommandExecutor::_split_first_word(params);
            params = tail;

            if param_value.is_empty() {
                return Err(format!("No main \"{}\" parameter present", param_metadata.name()));
            }

            res.insert(param_metadata.name(), CommandExecutor::_trim_quotes(param_value));
        }

        // Read rest params
        loop {
            let (param, tail) = CommandExecutor::_split_first_word(params);
            params = tail;

            if param.is_empty() {
                break;
            }

            let mut split = param.splitn(2, '=');
            let param_name = split.next().unwrap();
            let param_value = split.next();
            let param_metadata = command.params().iter().find(|p| p.name() == param_name);

            if let Some(param_metadata) = param_metadata {
                if let Some(param_value) = param_value {
                    res.insert(param_metadata.name(), CommandExecutor::_trim_quotes(param_value));
                } else {
                    return Err(format!("No value for \"{}\" parameter present", param_name));
                }
            } else {
                return Err(format!("Unknown \"{}\" parameter present", param_name));
            }
        }

        Ok(res)
    }

    fn _split_first_word(s: &str) -> (&str, &str) {
        let mut is_quote_escape = false;
        let mut is_whitespace_escape = false;
        let s = s.trim();

        for (pos, ch) in s.char_indices() {
            if ch.is_whitespace() && !is_whitespace_escape {
                return (&s[..pos], s[pos..].trim_left());
            }

            if !is_quote_escape && ch == '"' {
                is_whitespace_escape = !is_whitespace_escape;
            }

            is_quote_escape = ch == '\\';
        }

        (s, "")
    }

    fn _trim_quotes(s: &str) -> &str {
        if s.len() > 1 && s.starts_with("\"") && s.ends_with("\"") {
            &s[1..s.len() - 1]
        } else {
            s
        }
    }
}

pub struct CommandExecutorBuilder {
    commands: HashMap<&'static str, Box<Command>>,
    grouped_commands: HashMap<&'static str, (Box<Group>, HashMap<&'static str, Box<Command>>)>,
}

impl CommandExecutorBuilder {
    pub fn add_group(self, group: Box<Group>) -> CommandExecutorGroupBuilder {
        CommandExecutorGroupBuilder {
            commands: self.commands,
            grouped_commands: self.grouped_commands,
            group,
            group_commands: HashMap::new(),
        }
    }

    pub fn add_command(mut self, command: Box<Command>) -> CommandExecutorBuilder {
        self.commands.insert(command.metadata().name, command);
        self
    }

    pub fn finalize(self) -> CommandExecutor {
        CommandExecutor {
            commands: self.commands,
            grouped_commands: self.grouped_commands,
        }
    }
}

pub struct CommandExecutorGroupBuilder {
    commands: HashMap<&'static str, Box<Command>>,
    grouped_commands: HashMap<&'static str, (Box<Group>, HashMap<&'static str, Box<Command>>)>,
    group: Box<Group>,
    group_commands: HashMap<&'static str, Box<Command>>,
}

impl CommandExecutorGroupBuilder {
    pub fn add_command(mut self, command: Box<Command>) -> CommandExecutorGroupBuilder {
        self.group_commands.insert(command.metadata().name(), command);
        self
    }

    pub fn finalize_group(mut self) -> CommandExecutorBuilder {
        self.grouped_commands.insert(self.group.metadata().name(), (self.group, self.group_commands));
        CommandExecutorBuilder {
            commands: self.commands,
            grouped_commands: self.grouped_commands,
        }
    }
}

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

    struct TestGroup {
        metadata: GroupMetadata
    }

    impl TestGroup {
        pub fn new() -> TestGroup {
            TestGroup {
                metadata: GroupMetadata::new("test_group", "Test group help")
            }
        }
    }

    impl Group for TestGroup {
        fn metadata(&self) -> &GroupMetadata {
            &self.metadata
        }
    }

    struct TestCommand {
        metadata: CommandMetadata
    }

    impl TestCommand {
        pub fn new() -> TestCommand {
            TestCommand {
                metadata: CommandMetadata::build("test_command", "Test command help")
                    .add_main_param("main_param", "Main param help")
                    .add_param("param1", false, "Param1 help")
                    .add_param("param2", true, "Param2 help")
                    .finalize()
            }
        }
    }

    impl Command for TestCommand {
        fn metadata(&self) -> &CommandMetadata {
            &self.metadata
        }

        fn execute(&self, params: &HashMap<&'static str, &str>) -> Result<(), ()> {
            println!("Test comamnd params: {:?}", params);
            Ok(())
        }
    }

    #[test]
    pub fn execute_works() {
        let cmd_executor = CommandExecutor::build()
            .add_group(Box::new(TestGroup::new()))
            .add_command(Box::new(TestCommand::new()))
            .finalize_group()
            .add_command(Box::new(TestCommand::new()))
            .finalize();
        cmd_executor.execute("test_group test_command \"main param\" param1=\"param1 value\" param2=param2-value").unwrap();
    }

    #[test]
    pub fn _trim_quites_works() {
        assert_eq!(CommandExecutor::_trim_quotes(""), "");
        assert_eq!(CommandExecutor::_trim_quotes("\""), "\"");
        assert_eq!(CommandExecutor::_trim_quotes("\"\""), "");
        assert_eq!(CommandExecutor::_trim_quotes("\"123 456\""), "123 456");
    }
}

<|endoftext|>


<commit_before>use uuid::{Builder, Uuid, Variant, Version};

use crate::{Dummy, Faker};
use crate::faker::uuid::raw::*;
use crate::locales::Data;

impl<L: Data> Dummy<UuidV1<L>> for uuid::Uuid {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidV1<L>, rng: &mut R) -> Self {
      let bytes: [u8;8] = rng.gen();
      let (ticks, _) = config.1.to_rfc4122();
      let time_low = (ticks & 0xFFFF_FFFF) as u32;
      let time_mid = ((ticks >> 32) & 0xFFFF) as u16;
      let time_high_and_version = (((ticks >> 48) & 0x0FFF) as u16) | (1 << 12);
      Uuid::from_fields(time_low, time_mid, time_high_and_version, &bytes).expect("generate uuid::Uuid::from_fields")
    }

    fn dummy(UuidV1(_, timestamp, node_id): &UuidV1<L>) -> Self {
        Self::new_v1(*timestamp, node_id).expect("generate uuid::Uuid::new_v1")
    }
}

impl<L: Data> Dummy<UuidV1<L>> for String {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidV1<L>, rng: &mut R) -> Self {
        Uuid::dummy_with_rng(config, rng).to_hyphenated().to_string()
    }

    fn dummy(config: &UuidV1<L>) -> Self {
        Uuid::dummy(config).to_hyphenated().to_string()
    }
}

impl<L: Data> Dummy<UuidV3<L>> for Uuid {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidV3<L>, rng: &mut R) -> Self {
        Builder::from_bytes(rng.gen())
        .set_variant(Variant::RFC4122)
        .set_version(Version::Md5)
        .build()
    }

    fn dummy(UuidV3(_, namespace, name): &UuidV3<L>) -> Self {
        Self::new_v3(namespace, name)
    }
}

impl<L: Data> Dummy<UuidV3<L>> for String {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidV3<L>, rng: &mut R) -> Self {
        Uuid::dummy_with_rng(config, rng).to_hyphenated().to_string()
    }

    fn dummy(config: &UuidV3<L>) -> Self {
        Uuid::dummy(config).to_hyphenated().to_string()
    }
}

#[allow(unused_variables)]
impl<L: Data> Dummy<UuidV4<L>> for uuid::Uuid {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidV4<L>, rng: &mut R) -> Self {
        todo!()
    }

    fn dummy(_: &UuidV4<L>) -> Self {
        Self::new_v4()
    }
}

#[allow(unused_variables)]
impl<L: Data> Dummy<UuidV5<L>> for uuid::Uuid {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidV5<L>, rng: &mut R) -> Self {
        todo!()
    }

    fn dummy(UuidV5(_, namespace, name): &UuidV5<L>) -> Self {
        Self::new_v5(namespace, name)
    }
}

#[allow(unused_variables)]
impl<L: Data> Dummy<UuidSeed<L>> for uuid::Uuid {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidSeed<L>, rng: &mut R) -> Self {
        todo!()
    }

    fn dummy(UuidSeed(_, seed): &UuidSeed<L>) -> Self {
        Self::from_slice(&seed).expect("generate uuid::Uuid::from_slice")
    }
}

#[allow(unused_variables)]
impl Dummy<Faker> for uuid::Uuid {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &Faker, rng: &mut R) -> Self {
        todo!()
    }

    fn dummy(config: &Faker) -> Self {
        Self::new_v4()
    }
}<commit_msg>minor refactoring<commit_after>use uuid::{Builder, Uuid, Variant, Version};

use crate::{Dummy, Faker};
use crate::faker::uuid::raw::*;
use crate::locales::Data;

impl<L: Data> Dummy<UuidV1<L>> for Uuid {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidV1<L>, rng: &mut R) -> Self {
      let bytes: [u8;8] = rng.gen();
      let (ticks, _) = config.1.to_rfc4122();
      let time_low = (ticks & 0xFFFF_FFFF) as u32;
      let time_mid = ((ticks >> 32) & 0xFFFF) as u16;
      let time_high_and_version = (((ticks >> 48) & 0x0FFF) as u16) | (1 << 12);
      Uuid::from_fields(time_low, time_mid, time_high_and_version, &bytes).expect("generate uuid::Uuid::from_fields")
    }

    fn dummy(UuidV1(_, timestamp, node_id): &UuidV1<L>) -> Self {
        Self::new_v1(*timestamp, node_id).expect("generate uuid::Uuid::new_v1")
    }
}

impl<L: Data> Dummy<UuidV1<L>> for String {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidV1<L>, rng: &mut R) -> Self {
        Uuid::dummy_with_rng(config, rng).to_hyphenated().to_string()
    }

    fn dummy(config: &UuidV1<L>) -> Self {
        Uuid::dummy(config).to_hyphenated().to_string()
    }
}

impl<L: Data> Dummy<UuidV3<L>> for Uuid {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidV3<L>, rng: &mut R) -> Self {
        Builder::from_bytes(rng.gen())
        .set_variant(Variant::RFC4122)
        .set_version(Version::Md5)
        .build()
    }

    fn dummy(UuidV3(_, namespace, name): &UuidV3<L>) -> Self {
        Self::new_v3(namespace, name)
    }
}

impl<L: Data> Dummy<UuidV3<L>> for String {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidV3<L>, rng: &mut R) -> Self {
        Uuid::dummy_with_rng(config, rng).to_hyphenated().to_string()
    }

    fn dummy(config: &UuidV3<L>) -> Self {
        Uuid::dummy(config).to_hyphenated().to_string()
    }
}

#[allow(unused_variables)]
impl<L: Data> Dummy<UuidV4<L>> for Uuid {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidV4<L>, rng: &mut R) -> Self {
        todo!()
    }

    fn dummy(_: &UuidV4<L>) -> Self {
        Self::new_v4()
    }
}

#[allow(unused_variables)]
impl<L: Data> Dummy<UuidV5<L>> for Uuid {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidV5<L>, rng: &mut R) -> Self {
        todo!()
    }

    fn dummy(UuidV5(_, namespace, name): &UuidV5<L>) -> Self {
        Self::new_v5(namespace, name)
    }
}

#[allow(unused_variables)]
impl<L: Data> Dummy<UuidSeed<L>> for Uuid {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UuidSeed<L>, rng: &mut R) -> Self {
        todo!()
    }

    fn dummy(UuidSeed(_, seed): &UuidSeed<L>) -> Self {
        Self::from_slice(&seed).expect("generate uuid::Uuid::from_slice")
    }
}

#[allow(unused_variables)]
impl Dummy<Faker> for Uuid {
    fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &Faker, rng: &mut R) -> Self {
        todo!()
    }

    fn dummy(config: &Faker) -> Self {
        Self::new_v4()
    }
}<|endoftext|>


<commit_before>extern crate rcalc;

use std::io;
use std::io::{ BufWriter, Write };
use rcalc::{ Calculator, RuntimeItem, Value };

fn main() {
    let mut calculator = Calculator::new();
    let mut precision = None;
    let mut parallel_srcs = None;

    loop {
        print!("> ");
        io::stdout().flush().expect("stdout error");

        match read_line().trim() {
            "" => (),
            "#q" => break,
            "#:" => {
                parallel_srcs = match parallel_srcs {
                    Some(..) => None,
                    None => Some(vec![]),
                }
            },
            "#!" => {
                if let Some(ref srcs) = parallel_srcs {
                    let item = calculator.calc_parallel(srcs.clone());
                    print_item(item, &precision);
                };
                parallel_srcs = None;
            },
            "#j" => {
                let mut buf = Vec::new();
                let _ = {
                    let mut writer = BufWriter::new(&mut buf);
                    calculator.write_json(&mut writer).expect("json output error");
                };
                println!("{}", String::from_utf8(buf).unwrap());
            },
            "?" => {
                println!("#q - quit rcalc");
                println!("#: - enter or leave parallel mode");
                println!("#! - leave parallel mode and evaluate all input concurrently");
                println!("#j - print a JSON representation of the current values");
            },
            line if line.starts_with("#precision ") => {
                if let Result::Ok(p) = line.split_whitespace().last().unwrap().parse::<usize>() {
                    precision = Some(p);
                } else {
                    precision = None;
                }
            },
            line => {
                match parallel_srcs {
                    Some(ref mut srcs) => srcs.push(line.to_string()),
                    None => {
                        match calculator.calc(line) {
                            Ok(item) => print_item(item, &precision),
                            Err(msg) => println!("{}", msg),
                        }
                    }
                }
            }
        }
    }
}

fn read_line() -> String {
    let mut buf = String::new();
    match io::stdin().read_line(&mut buf) {
        Ok(_) => buf,
        Err(e) => {
            println!("{:?}", e);
            "".to_string()
        },
    }
}

fn print_item(item: &RuntimeItem, precision: &Option<usize>) {
    if let &RuntimeItem::Value(ref v) = item {
        print_value(v, precision);
    } else {
        println!("Function OK");
    };
}

fn print_value(v: &Value, precision: &Option<usize>) {
    match v {
        &Value::Integer(n) => {
            println!("= {}", n);
            println!("  {:#x}", n);
            println!("  {:#b}", n);
        },
        _ => {
            match *precision {
                Some(n) => println!("= {val:.prec$}", val = v, prec = n),
                None => println!("= {}", v),
            }
        },
    }
}
<commit_msg>resolved #15 (JSON file output)<commit_after>extern crate rcalc;

use std::io;
use std::io::{ BufWriter, Write };
use std::path::PathBuf;
use std::fs::File;
use std::env;
use rcalc::{ Calculator, RuntimeItem, Value };

fn main() {
    let mut calculator = Calculator::new();
    let mut precision = None;
    let mut parallel_srcs = None;

    loop {
        print!("> ");
        io::stdout().flush().expect("stdout error");

        match read_line().trim() {
            "" => (),
            "#q" => break,
            "#:" => {
                parallel_srcs = match parallel_srcs {
                    Some(..) => None,
                    None => Some(vec![]),
                }
            },
            "#!" => {
                if let Some(ref srcs) = parallel_srcs {
                    let item = calculator.calc_parallel(srcs.clone());
                    print_item(item, &precision);
                };
                parallel_srcs = None;
            },
            "#j" => {
                let mut buf = Vec::new();
                let _ = {
                    let mut writer = BufWriter::new(&mut buf);
                    calculator.write_json(&mut writer).expect("json output error");
                };
                println!("{}", String::from_utf8(buf).unwrap());
            },
            "#w" => {
                match write_json(&calculator) {
                    Result::Ok(ref path) => println!("Context written to '{}'", path),
                    Result::Err((ref path, ref error)) => println!("Error writing context to '{}': {:?}", path, error),
                };
            },
            "?" => {
                println!("#q - quit rcalc");
                println!("#: - enter or leave parallel mode");
                println!("#! - leave parallel mode and evaluate all input concurrently");
                println!("#j - print a JSON representation of the current values");
                println!("#w - write a JSON representation of the current values to a file");
            },
            line if line.starts_with("#precision ") => {
                if let Result::Ok(p) = line.split_whitespace().last().unwrap().parse::<usize>() {
                    precision = Some(p);
                } else {
                    precision = None;
                }
            },
            line => {
                match parallel_srcs {
                    Some(ref mut srcs) => srcs.push(line.to_string()),
                    None => {
                        match calculator.calc(line) {
                            Ok(item) => print_item(item, &precision),
                            Err(msg) => println!("{}", msg),
                        }
                    }
                }
            }
        }
    }
}

fn read_line() -> String {
    let mut buf = String::new();
    match io::stdin().read_line(&mut buf) {
        Ok(_) => buf,
        Err(e) => {
            println!("{:?}", e);
            "".to_string()
        },
    }
}

fn print_item(item: &RuntimeItem, precision: &Option<usize>) {
    if let &RuntimeItem::Value(ref v) = item {
        print_value(v, precision);
    } else {
        println!("Function OK");
    };
}

fn print_value(v: &Value, precision: &Option<usize>) {
    match v {
        &Value::Integer(n) => {
            println!("= {}", n);
            println!("  {:#x}", n);
            println!("  {:#b}", n);
        },
        _ => {
            match *precision {
                Some(n) => println!("= {val:.prec$}", val = v, prec = n),
                None => println!("= {}", v),
            }
        },
    }
}

fn write_json(calculator: &Calculator) -> Result<String, (String, ::std::io::Error)> {
    fn inner_write(calculator: &Calculator, path: &str) -> ::std::io::Result<()> {
        let mut writer = BufWriter::new(try!(File::create(&path)));
        calculator.write_json(&mut writer)
    }
    let path = get_json_path();
    match inner_write(calculator, &path) {
        Result::Ok(()) => Result::Ok(path),
        Result::Err(error) => Result::Err((path, error)),
    }
}

fn get_json_path() -> String {
    let mut pathbuf: PathBuf = match env::home_dir() {
        Some(path) => PathBuf::from(path),
        None => PathBuf::from(""),
    };
    pathbuf.push("rcalc.json");
    pathbuf.to_str().unwrap().to_string()
}
<|endoftext|>