<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

//! Utilities for providing the hover feature
use crate::{
    lsp::{HoverContents, LanguageString, MarkedString},
    lsp_runtime_error::{LSPRuntimeError, LSPRuntimeResult},
    node_resolution_info::{NodeKind, NodeResolutionInfo},
    server::LSPState,
};
use crate::{server::SourcePrograms, LSPExtraDataProvider};
use common::PerfLogger;
use graphql_ir::Value;
use graphql_text_printer::print_value;
use lsp_types::{request::HoverRequest, request::Request, Hover};
use schema::{SDLSchema, Schema};
use schema_documentation::SchemaDocumentation;
use schema_print::print_directive;
use std::sync::Arc;

fn graphql_marked_string(value: String) -> MarkedString {
    MarkedString::LanguageString(LanguageString {
        language: "graphql".to_string(),
        value,
    })
}

fn hover_content_wrapper(value: String) -> HoverContents {
    HoverContents::Scalar(graphql_marked_string(value))
}

/// This will provide a more accurate information about some of the specific Relay directives
/// that cannot be expressed via SDL
fn argument_definition_hover_info(directive_name: &str) -> Option<HoverContents> {
    let content = match directive_name {
        "argumentDefinitions" => Some(
            r#"
`@argumentDefinitions` is a directive used to specify arguments taken by a fragment.

---
@see: https://relay.dev/docs/en/graphql-in-relay.html#argumentdefinitions
"#,
        ),
        "arguments" => Some(
            r#"
`@arguments` is a directive used to pass arguments to a fragment that was defined using `@argumentDefinitions`.

---
@see: https://relay.dev/docs/en/graphql-in-relay.html#arguments
"#,
        ),
        "uncheckedArguments_DEPRECATED" => Some(
            r#"
DEPRECATED version of `@arguments` directive.
`@arguments` is a directive used to pass arguments to a fragment that was defined using `@argumentDefinitions`.

---
@see: https://relay.dev/docs/en/graphql-in-relay.html#arguments
"#,
        ),
        _ => None,
    };

    content.map(|value| HoverContents::Scalar(MarkedString::String(value.to_string())))
}

fn get_hover_response_contents(
    node_resolution_info: NodeResolutionInfo,
    schema: &SDLSchema,
    schema_documentation: &Arc<SchemaDocumentation>,
    source_programs: &SourcePrograms,
    extra_data_provider: &dyn LSPExtraDataProvider,
) -> Option<HoverContents> {
    let kind = node_resolution_info.kind;

    match kind {
        NodeKind::Variable(type_name) => Some(hover_content_wrapper(type_name)),
        NodeKind::Directive(directive_name, argument_name) => {
            if let Some(argument_definition_hover_info) =
                argument_definition_hover_info(directive_name.lookup())
            {
                return Some(argument_definition_hover_info);
            }

            let schema_directive = schema.get_directive(directive_name)?;

            if let Some(argument_name) = argument_name {
                let argument = schema_directive.arguments.named(argument_name)?;
                let content = format!(
                    "{}: {}",
                    argument_name,
                    schema.get_type_string(&argument.type_)
                );
                Some(hover_content_wrapper(content))
            } else {
                let directive_text = print_directive(schema, &schema_directive);
                Some(hover_content_wrapper(directive_text))
            }
        }
        NodeKind::FieldName => {
            let (parent_type, field) = node_resolution_info
                .type_path
                .resolve_current_field(schema)?;

            let type_name = schema.get_type_string(&field.type_);
            let parent_type_name = schema.get_type_name(parent_type).to_string();

            let mut hover_contents: Vec<MarkedString> =
                vec![MarkedString::String(format!("Field: **{}**", field.name))];

            if let Some(field_description) =
                schema_documentation.get_field_description(&parent_type_name, field.name.lookup())
            {
                hover_contents.push(MarkedString::String(field_description.to_string()));
            }

            hover_contents.push(MarkedString::String(format!("Type: **{}**", type_name)));

            if let Some(type_description) = schema_documentation.get_type_description(&type_name) {
                hover_contents.push(MarkedString::String(type_description.to_string()));
            }

            if !field.arguments.is_empty() {
                hover_contents.push(MarkedString::String(
                    "This field accepts following arguments".to_string(),
                ));

                for arg in field.arguments.iter() {
                    hover_contents.push(MarkedString::from_markdown(format!(
                        "`{}: {}{}`\n\n{}",
                        arg.name,
                        schema.get_type_string(&arg.type_),
                        if let Some(default_value) = &arg.default_value {
                            format!(" = {}", default_value)
                        } else {
                            "".to_string()
                        },
                        if let Some(description) = schema_documentation
                            .get_field_argument_description(
                                &parent_type_name,
                                field.name.lookup(),
                                arg.name.lookup(),
                            )
                        {
                            description.to_string()
                        } else {
                            "".to_string()
                        }
                    )));
                }
            }
            Some(HoverContents::Array(hover_contents))
        }
        NodeKind::FieldArgument(field_name, argument_name) => {
            let type_ref = node_resolution_info
                .type_path
                .resolve_current_type_reference(schema)?;

            if type_ref.inner().is_object() || type_ref.inner().is_interface() {
                let field_id = schema.named_field(type_ref.inner(), field_name)?;
                let field = schema.field(field_id);
                let argument = field.arguments.named(argument_name)?;
                let content = format!(
                    "{}: {}",
                    argument_name,
                    schema.get_type_string(&argument.type_)
                );
                Some(hover_content_wrapper(content))
            } else {
                None
            }
        }
        NodeKind::FragmentSpread(fragment_name) => {
            let project_name = node_resolution_info.project_name;
            if let Some(source_program) = source_programs.get(&project_name) {
                let fragment = source_program.fragment(fragment_name)?;
                let mut hover_contents: Vec<MarkedString> = vec![];
                hover_contents.push(graphql_marked_string(format!(
                    "fragment {} on {} {{ ... }}",
                    fragment.name.item,
                    schema.get_type_name(fragment.type_condition),
                )));

                if !fragment.variable_definitions.is_empty() {
                    let mut variables_string: Vec<String> =
                        vec!["This fragment accepts following arguments:".to_string()];
                    variables_string.push("```".to_string());
                    for var in &fragment.variable_definitions {
                        let default_value = match var.default_value.clone() {
                            Some(default_value) => format!(
                                ", default_value = {}",
                                print_value(schema, &Value::Constant(default_value))
                            ),
                            None => "".to_string(),
                        };
                        variables_string.push(format!(
                            "- {}: {}{}",
                            var.name.item,
                            schema.get_type_string(&var.type_),
                            default_value,
                        ));
                    }
                    variables_string.push("```".to_string());
                    hover_contents.push(MarkedString::String(variables_string.join("\n")))
                }

                let fragment_name_details: Vec<&str> = fragment_name.lookup().split('_').collect();
                // We expect the fragment name to be `ComponentName_propName`
                if fragment_name_details.len() == 2 {
                    hover_contents.push(MarkedString::from_markdown(format!(
                        r#"
To consume this fragment spread,
pass it to the component that defined it.

For example:
```js
    <{} {}={{data.{}}} />
```
"#,
                        fragment_name_details[0],
                        fragment_name_details[1],
                        fragment_name_details[1],
                    )));
                } // We may log an error (later), if that is not the case.

                hover_contents.push(MarkedString::String(
                    "@see: https://relay.dev/docs/en/thinking-in-relay#data-masking".to_string(),
                ));
                Some(HoverContents::Array(hover_contents))
            } else {
                None
            }
        }
        NodeKind::OperationDefinition(operation) => {
            let search_token = if let Some(operation_name) = operation.name {
                operation_name.value.lookup().to_string()
            } else {
                return None;
            };

            let extra_data = extra_data_provider.fetch_query_stats(search_token);
            if !extra_data.is_empty() {
                Some(HoverContents::Array(
                    extra_data
                        .iter()
                        .map(|str| MarkedString::String(str.to_string()))
                        .collect::<_>(),
                ))
            } else {
                None
            }
        }
        NodeKind::FragmentDefinition(fragment) => {
            let type_ = node_resolution_info
                .type_path
                .resolve_current_type_reference(schema)?;
            let title = graphql_marked_string(format!(
                "fragment {} on {} {{ .. }}",
                fragment.name.value,
                schema.get_type_name(type_.inner())
            ));

            let hover_contents = vec![
                title,
                MarkedString::String(
                    r#"Fragments let you construct sets of fields,
and then include them in queries where you need to.

---
@see: https://graphql.org/learn/queries/#fragments
"#
                    .to_string(),
                ),
            ];

            Some(HoverContents::Array(hover_contents))
        }
        NodeKind::InlineFragment => None,
        NodeKind::TypeCondition(_) => None,
    }
}

pub(crate) fn on_hover<TPerfLogger: PerfLogger + 'static>(
    state: &mut LSPState<TPerfLogger>,
    params: <HoverRequest as Request>::Params,
) -> LSPRuntimeResult<<HoverRequest as Request>::Result> {
    let node_resolution_info = state.resolve_node(params.text_document_position_params)?;

    log::debug!("Hovering over {:?}", node_resolution_info);
    if let Some(schema) = state.get_schemas().get(&node_resolution_info.project_name) {
        let schema_documentation = state
            .extra_data_provider
            .get_schema_documentation(&node_resolution_info.project_name.to_string());

        let contents = get_hover_response_contents(
            node_resolution_info,
            &schema,
            &schema_documentation,
            state.get_source_programs_ref(),
            state.extra_data_provider.as_ref(),
        )
        .ok_or_else(|| {
            LSPRuntimeError::UnexpectedError("Unable to get hover contents".to_string())
        })?;
        Ok(Some(Hover {
            contents,
            range: None,
        }))
    } else {
        Err(LSPRuntimeError::ExpectedError)
    }
}
<commit_msg>Use schema description in LSP hover<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

//! Utilities for providing the hover feature
use crate::{
    lsp::{HoverContents, LanguageString, MarkedString},
    lsp_runtime_error::{LSPRuntimeError, LSPRuntimeResult},
    node_resolution_info::{NodeKind, NodeResolutionInfo},
    server::LSPState,
};
use crate::{server::SourcePrograms, LSPExtraDataProvider};
use common::PerfLogger;
use graphql_ir::Value;
use graphql_text_printer::print_value;
use lsp_types::{request::HoverRequest, request::Request, Hover};
use schema::{SDLSchema, Schema};
use schema_documentation::SchemaDocumentation;
use schema_print::print_directive;
use std::sync::Arc;

fn graphql_marked_string(value: String) -> MarkedString {
    MarkedString::LanguageString(LanguageString {
        language: "graphql".to_string(),
        value,
    })
}

fn hover_content_wrapper(value: String) -> HoverContents {
    HoverContents::Scalar(graphql_marked_string(value))
}

/// This will provide a more accurate information about some of the specific Relay directives
/// that cannot be expressed via SDL
fn argument_definition_hover_info(directive_name: &str) -> Option<HoverContents> {
    let content = match directive_name {
        "argumentDefinitions" => Some(
            r#"
`@argumentDefinitions` is a directive used to specify arguments taken by a fragment.

---
@see: https://relay.dev/docs/en/graphql-in-relay.html#argumentdefinitions
"#,
        ),
        "arguments" => Some(
            r#"
`@arguments` is a directive used to pass arguments to a fragment that was defined using `@argumentDefinitions`.

---
@see: https://relay.dev/docs/en/graphql-in-relay.html#arguments
"#,
        ),
        "uncheckedArguments_DEPRECATED" => Some(
            r#"
DEPRECATED version of `@arguments` directive.
`@arguments` is a directive used to pass arguments to a fragment that was defined using `@argumentDefinitions`.

---
@see: https://relay.dev/docs/en/graphql-in-relay.html#arguments
"#,
        ),
        _ => None,
    };

    content.map(|value| HoverContents::Scalar(MarkedString::String(value.to_string())))
}

fn get_hover_response_contents(
    node_resolution_info: NodeResolutionInfo,
    schema: &SDLSchema,
    schema_documentation: &Arc<SchemaDocumentation>,
    source_programs: &SourcePrograms,
    extra_data_provider: &dyn LSPExtraDataProvider,
) -> Option<HoverContents> {
    let kind = node_resolution_info.kind;

    match kind {
        NodeKind::Variable(type_name) => Some(hover_content_wrapper(type_name)),
        NodeKind::Directive(directive_name, argument_name) => {
            if let Some(argument_definition_hover_info) =
                argument_definition_hover_info(directive_name.lookup())
            {
                return Some(argument_definition_hover_info);
            }

            let schema_directive = schema.get_directive(directive_name)?;

            if let Some(argument_name) = argument_name {
                let argument = schema_directive.arguments.named(argument_name)?;
                let content = format!(
                    "{}: {}",
                    argument_name,
                    schema.get_type_string(&argument.type_)
                );
                Some(hover_content_wrapper(content))
            } else {
                let directive_text = print_directive(schema, &schema_directive);
                Some(hover_content_wrapper(directive_text))
            }
        }
        NodeKind::FieldName => {
            let (parent_type, field) = node_resolution_info
                .type_path
                .resolve_current_field(schema)?;

            let type_name = schema.get_type_string(&field.type_);
            let parent_type_name = schema.get_type_name(parent_type).to_string();

            let mut hover_contents: Vec<MarkedString> =
                vec![MarkedString::String(format!("Field: **{}**", field.name))];

            if let Some(schema_description) = field.description {
                hover_contents.push(MarkedString::String(schema_description.to_string()));
            } else if let Some(field_description) =
                schema_documentation.get_field_description(&parent_type_name, field.name.lookup())
            {
                hover_contents.push(MarkedString::String(field_description.to_string()));
            }

            hover_contents.push(MarkedString::String(format!("Type: **{}**", type_name)));

            if let Some(type_description) = schema_documentation.get_type_description(&type_name) {
                hover_contents.push(MarkedString::String(type_description.to_string()));
            }

            if !field.arguments.is_empty() {
                hover_contents.push(MarkedString::String(
                    "This field accepts following arguments".to_string(),
                ));

                for arg in field.arguments.iter() {
                    hover_contents.push(MarkedString::from_markdown(format!(
                        "`{}: {}{}`\n\n{}",
                        arg.name,
                        schema.get_type_string(&arg.type_),
                        if let Some(default_value) = &arg.default_value {
                            format!(" = {}", default_value)
                        } else {
                            "".to_string()
                        },
                        if let Some(description) = schema_documentation
                            .get_field_argument_description(
                                &parent_type_name,
                                field.name.lookup(),
                                arg.name.lookup(),
                            )
                        {
                            description.to_string()
                        } else {
                            "".to_string()
                        }
                    )));
                }
            }
            Some(HoverContents::Array(hover_contents))
        }
        NodeKind::FieldArgument(field_name, argument_name) => {
            let type_ref = node_resolution_info
                .type_path
                .resolve_current_type_reference(schema)?;

            if type_ref.inner().is_object() || type_ref.inner().is_interface() {
                let field_id = schema.named_field(type_ref.inner(), field_name)?;
                let field = schema.field(field_id);
                let argument = field.arguments.named(argument_name)?;
                let content = format!(
                    "{}: {}",
                    argument_name,
                    schema.get_type_string(&argument.type_)
                );
                Some(hover_content_wrapper(content))
            } else {
                None
            }
        }
        NodeKind::FragmentSpread(fragment_name) => {
            let project_name = node_resolution_info.project_name;
            if let Some(source_program) = source_programs.get(&project_name) {
                let fragment = source_program.fragment(fragment_name)?;
                let mut hover_contents: Vec<MarkedString> = vec![];
                hover_contents.push(graphql_marked_string(format!(
                    "fragment {} on {} {{ ... }}",
                    fragment.name.item,
                    schema.get_type_name(fragment.type_condition),
                )));

                if !fragment.variable_definitions.is_empty() {
                    let mut variables_string: Vec<String> =
                        vec!["This fragment accepts following arguments:".to_string()];
                    variables_string.push("```".to_string());
                    for var in &fragment.variable_definitions {
                        let default_value = match var.default_value.clone() {
                            Some(default_value) => format!(
                                ", default_value = {}",
                                print_value(schema, &Value::Constant(default_value))
                            ),
                            None => "".to_string(),
                        };
                        variables_string.push(format!(
                            "- {}: {}{}",
                            var.name.item,
                            schema.get_type_string(&var.type_),
                            default_value,
                        ));
                    }
                    variables_string.push("```".to_string());
                    hover_contents.push(MarkedString::String(variables_string.join("\n")))
                }

                let fragment_name_details: Vec<&str> = fragment_name.lookup().split('_').collect();
                // We expect the fragment name to be `ComponentName_propName`
                if fragment_name_details.len() == 2 {
                    hover_contents.push(MarkedString::from_markdown(format!(
                        r#"
To consume this fragment spread,
pass it to the component that defined it.

For example:
```js
    <{} {}={{data.{}}} />
```
"#,
                        fragment_name_details[0],
                        fragment_name_details[1],
                        fragment_name_details[1],
                    )));
                } // We may log an error (later), if that is not the case.

                hover_contents.push(MarkedString::String(
                    "@see: https://relay.dev/docs/en/thinking-in-relay#data-masking".to_string(),
                ));
                Some(HoverContents::Array(hover_contents))
            } else {
                None
            }
        }
        NodeKind::OperationDefinition(operation) => {
            let search_token = if let Some(operation_name) = operation.name {
                operation_name.value.lookup().to_string()
            } else {
                return None;
            };

            let extra_data = extra_data_provider.fetch_query_stats(search_token);
            if !extra_data.is_empty() {
                Some(HoverContents::Array(
                    extra_data
                        .iter()
                        .map(|str| MarkedString::String(str.to_string()))
                        .collect::<_>(),
                ))
            } else {
                None
            }
        }
        NodeKind::FragmentDefinition(fragment) => {
            let type_ = node_resolution_info
                .type_path
                .resolve_current_type_reference(schema)?;
            let title = graphql_marked_string(format!(
                "fragment {} on {} {{ .. }}",
                fragment.name.value,
                schema.get_type_name(type_.inner())
            ));

            let hover_contents = vec![
                title,
                MarkedString::String(
                    r#"Fragments let you construct sets of fields,
and then include them in queries where you need to.

---
@see: https://graphql.org/learn/queries/#fragments
"#
                    .to_string(),
                ),
            ];

            Some(HoverContents::Array(hover_contents))
        }
        NodeKind::InlineFragment => None,
        NodeKind::TypeCondition(_) => None,
    }
}

pub(crate) fn on_hover<TPerfLogger: PerfLogger + 'static>(
    state: &mut LSPState<TPerfLogger>,
    params: <HoverRequest as Request>::Params,
) -> LSPRuntimeResult<<HoverRequest as Request>::Result> {
    let node_resolution_info = state.resolve_node(params.text_document_position_params)?;

    log::debug!("Hovering over {:?}", node_resolution_info);
    if let Some(schema) = state.get_schemas().get(&node_resolution_info.project_name) {
        let schema_documentation = state
            .extra_data_provider
            .get_schema_documentation(&node_resolution_info.project_name.to_string());

        let contents = get_hover_response_contents(
            node_resolution_info,
            &schema,
            &schema_documentation,
            state.get_source_programs_ref(),
            state.extra_data_provider.as_ref(),
        )
        .ok_or_else(|| {
            LSPRuntimeError::UnexpectedError("Unable to get hover contents".to_string())
        })?;
        Ok(Some(Hover {
            contents,
            range: None,
        }))
    } else {
        Err(LSPRuntimeError::ExpectedError)
    }
}
<|endoftext|>


<commit_before>//! # Tree Model Sort example
//!
//! This sample demonstrates how to use the `TreeModelSort` widget.

extern crate gdk;
extern crate gio;
extern crate gtk;

use gio::ApplicationExt;
use gio::ApplicationExtManual;
use gtk::prelude::*;
use std::env::args;

fn build_ui(application: &gtk::Application) {
    let window = gtk::ApplicationWindow::new(application);

    window.set_title("Tree Model Sort Window");
    window.set_border_width(10);
    window.set_position(gtk::WindowPosition::Center);
    window.set_default_size(350, 70);

    let store = gtk::TreeStore::new(&[gtk::Type::String]);
    store.insert_with_values(None, None, &[0], &[&"One"]);
    store.insert_with_values(None, None, &[0], &[&"Two"]);
    store.insert_with_values(None, None, &[0], &[&"Three"]);
    store.insert_with_values(None, None, &[0], &[&"Four"]);

    // We create the `TreeModelSort` and we give it the `TreeStore` as
    // parameter.
    let sortable_store = gtk::TreeModelSort::new(&store);

    // Then we create the `TreeView` from the `TreeModelSort`.
    let treeview = gtk::TreeView::new_with_model(&sortable_store);

    let column = gtk::TreeViewColumn::new();
    column.set_title("Value");
    column.set_clickable(true);
    column.set_sort_indicator(true);
    column.set_sort_column_id(0);

    let renderer = gtk::CellRendererText::new();
    column.pack_end(&renderer, true);
    column.add_attribute(&renderer, "text", 0);

    treeview.append_column(&column);

    treeview.connect_row_activated(move |_, path, _column| {
        let real_path = sortable_store
            .convert_path_to_child_path(&path)
            .expect("Sorted path does not correspond to real path");
        println!(
            "Clicked on sorted: {:?}, real: {:?}",
            path.get_indices(),
            real_path.get_indices()
        );
    });

    // We finally add the `TreeView` to the window.
    window.add(&treeview);
    window.show_all();
}

fn main() {
    let application =
        gtk::Application::new(Some("com.github.basic"), gio::ApplicationFlags::empty())
            .expect("Initialization failed...");

    application.connect_activate(|app| {
        build_ui(app);
    });
    application.run(&args().collect::<Vec<_>>());
}
<commit_msg>use prelude instead of direct import<commit_after>//! # Tree Model Sort example
//!
//! This sample demonstrates how to use the `TreeModelSort` widget.

extern crate gdk;
extern crate gio;
extern crate gtk;

use gio::prelude::*;
use gtk::prelude::*;
use std::env::args;

fn build_ui(application: &gtk::Application) {
    let window = gtk::ApplicationWindow::new(application);

    window.set_title("Tree Model Sort Window");
    window.set_border_width(10);
    window.set_position(gtk::WindowPosition::Center);
    window.set_default_size(350, 70);

    let store = gtk::TreeStore::new(&[gtk::Type::String]);
    store.insert_with_values(None, None, &[0], &[&"One"]);
    store.insert_with_values(None, None, &[0], &[&"Two"]);
    store.insert_with_values(None, None, &[0], &[&"Three"]);
    store.insert_with_values(None, None, &[0], &[&"Four"]);

    // We create the `TreeModelSort` and we give it the `TreeStore` as
    // parameter.
    let sortable_store = gtk::TreeModelSort::new(&store);

    // Then we create the `TreeView` from the `TreeModelSort`.
    let treeview = gtk::TreeView::new_with_model(&sortable_store);

    let column = gtk::TreeViewColumn::new();
    column.set_title("Value");
    column.set_clickable(true);
    column.set_sort_indicator(true);
    column.set_sort_column_id(0);

    let renderer = gtk::CellRendererText::new();
    column.pack_end(&renderer, true);
    column.add_attribute(&renderer, "text", 0);

    treeview.append_column(&column);

    treeview.connect_row_activated(move |_, path, _column| {
        let real_path = sortable_store
            .convert_path_to_child_path(&path)
            .expect("Sorted path does not correspond to real path");
        println!(
            "Clicked on sorted: {:?}, real: {:?}",
            path.get_indices(),
            real_path.get_indices()
        );
    });

    // We finally add the `TreeView` to the window.
    window.add(&treeview);
    window.show_all();
}

fn main() {
    let application =
        gtk::Application::new(Some("com.github.basic"), gio::ApplicationFlags::empty())
            .expect("Initialization failed...");

    application.connect_activate(|app| {
        build_ui(app);
    });
    application.run(&args().collect::<Vec<_>>());
}
<|endoftext|>


<commit_before>use test_data_generator::profile::pattern::{Pattern};
use test_data_generator::profile::fact::{Fact};
use std::collections::BTreeMap;
use std::ops::AddAssign;
//use std::iter::Sum;
use std::mem;

type PatternMap = BTreeMap<String, u32>;
type PatternRankMap  = BTreeMap<String, f64>;
type SizeMap = BTreeMap<u32, u32>;
type SizeRankMap  = BTreeMap<u32, f64>;

pub struct Profile{
	pub patterns: PatternMap,
	pub pattern_total: u32,
	pub pattern_ranks: PatternRankMap,
	pub sizes: SizeMap,
	pub size_total: u32,
	pub size_ranks: SizeRankMap,
	pub facts: Vec<Vec<Fact>>,
}

impl Profile {
	//constructor
	pub fn new() -> Profile {
		Profile{
			patterns: PatternMap::new(),
			pattern_total: 0,
			pattern_ranks: PatternRankMap::new(),
			sizes: SizeMap::new(),
			size_total: 0,
			size_ranks: SizeRankMap::new(),
			facts: Profile::new_facts(10),
		}
	}

	pub fn new_with(p: u8) -> Profile {
		Profile{
			patterns: PatternMap::new(),
			pattern_total: 0,
			pattern_ranks: PatternRankMap::new(),
			sizes: SizeMap::new(),
			size_total: 0,
			size_ranks: SizeRankMap::new(),
			facts: Profile::new_facts(p),
		}
	}

	// methods
	pub fn analyze(&mut self, entity: &str) {
		let mut pattrn =  Pattern::new();

		// analyze patterns
		let rslt = pattrn.analyze(entity);

		// store the facts
		for f in rslt.1.into_iter() {
			self.facts[0].push(f);
		}

		// store the pattern
		AddAssign::add_assign(self.patterns.entry(rslt.0.to_string()).or_insert(0), 1);

		// store the total number of patterns generated so far
		self.pattern_total = self.patterns.values().sum::<u32>();
		//println!("{:?}",&self.patterns);
		//println!("{:?}",self.pattern_total);

		// analyze sizes
		AddAssign::add_assign(self.sizes.entry(pattrn.size).or_insert(0), 1);
		self.size_total = self.sizes.values().sum::<u32>();
	}

	fn new_facts(p: u8) -> Vec<Vec<Fact>> {
		let mut vec_main = Vec::new();

		for i in 0..p {
			vec_main.push(Vec::new());
		}

		vec_main
	}

	pub fn rank_patterns(&mut self) -> PatternRankMap{
		self.pattern_ranks = PatternRankMap::new();

		for key in self.patterns.keys(){
			self.pattern_ranks.insert(key.to_string(), (*self.patterns.get(key).unwrap() as f64 / self.pattern_total as f64)*100.0);
		}

		//println!("{:?}",&self.pattern_ranks);
		self.pattern_ranks.clone()
	}

	pub fn reset_analyze(&mut self) {
		self.patterns = PatternMap::new();
	}

	pub fn rank_sizes(&mut self) -> SizeRankMap{
		self.size_ranks = SizeRankMap::new();

		for key in self.sizes.keys(){
			self.size_ranks.insert(*key, (*self.sizes.get(key).unwrap() as f64 / self.size_total as f64)*100.0);
		}

		//println!("{:?}",&self.size_ranks);
		self.size_ranks.clone()
	}
}<commit_msg>working on moving Facts to profile<commit_after>use test_data_generator::profile::pattern::{Pattern};
use test_data_generator::profile::fact::{Fact};
use std::collections::BTreeMap;
use std::ops::AddAssign;

type PatternMap = BTreeMap<String, u32>;
type PatternRankMap  = BTreeMap<String, f64>;
type SizeMap = BTreeMap<u32, u32>;
type SizeRankMap  = BTreeMap<u32, f64>;

pub struct Profile{
	pub patterns: PatternMap,
	pub pattern_total: u32,
	pub pattern_ranks: PatternRankMap,
	pub sizes: SizeMap,
	pub size_total: u32,
	pub size_ranks: SizeRankMap,
	pub processors: u8,
	pub facts: Vec<Vec<Fact>>,
}

impl Profile {
	//constructor
	pub fn new() -> Profile {
		Profile{
			patterns: PatternMap::new(),
			pattern_total: 0,
			pattern_ranks: PatternRankMap::new(),
			sizes: SizeMap::new(),
			size_total: 0,
			size_ranks: SizeRankMap::new(),
			processors: 10,
			facts: Profile::new_facts(10),
		}
	}

	pub fn new_with(p: u8) -> Profile {
		Profile{
			patterns: PatternMap::new(),
			pattern_total: 0,
			pattern_ranks: PatternRankMap::new(),
			sizes: SizeMap::new(),
			size_total: 0,
			size_ranks: SizeRankMap::new(),
			processors: p,
			facts: Profile::new_facts(p),
		}
	}

	// methods
	pub fn analyze(&mut self, entity: &str) {
		let mut pattrn =  Pattern::new();

		// analyze patterns
		let rslt = pattrn.analyze(entity);

		// store the facts
		for f in rslt.1.into_iter() {
			self.facts[0].push(f);
		}

		// store the pattern
		AddAssign::add_assign(self.patterns.entry(rslt.0.to_string()).or_insert(0), 1);

		// store the total number of patterns generated so far
		self.pattern_total = self.patterns.values().sum::<u32>();
		//println!("{:?}",&self.patterns);
		//println!("{:?}",self.pattern_total);

		// analyze sizes
		AddAssign::add_assign(self.sizes.entry(pattrn.size).or_insert(0), 1);
		self.size_total = self.sizes.values().sum::<u32>();
	}

	fn new_facts(p: u8) -> Vec<Vec<Fact>> {
		let mut vec_main = Vec::new();

		for _ in 1..p {
			vec_main.push(Vec::new());
		}

		vec_main
	}

	pub fn rank_patterns(&mut self) -> PatternRankMap{
		self.pattern_ranks = PatternRankMap::new();

		for key in self.patterns.keys(){
			self.pattern_ranks.insert(key.to_string(), (*self.patterns.get(key).unwrap() as f64 / self.pattern_total as f64)*100.0);
		}

		//println!("{:?}",&self.pattern_ranks);
		self.pattern_ranks.clone()
	}

	pub fn reset_analyze(&mut self) {
		self.patterns = PatternMap::new();
	}

	pub fn rank_sizes(&mut self) -> SizeRankMap{
		self.size_ranks = SizeRankMap::new();

		for key in self.sizes.keys(){
			self.size_ranks.insert(*key, (*self.sizes.get(key).unwrap() as f64 / self.size_total as f64)*100.0);
		}

		//println!("{:?}",&self.size_ranks);
		self.size_ranks.clone()
	}
}<|endoftext|>


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

use std::env;
use std::ffi::OsString;
use std::path::{Path, PathBuf};

use hcore::os::process;
use hcore::package::{PackageIdent, PackageInstall};
use hcore::fs::{find_command, FS_ROOT_PATH};

use error::{Error, Result};

pub fn start<T>(ident: &PackageIdent, command: T, args: Vec<OsString>) -> Result<()>
where
    T: Into<PathBuf>,
{
    let command = command.into();
    let pkg_install = PackageInstall::load(&ident, Some(&*FS_ROOT_PATH))?;
    let mut run_env = pkg_install.environment_for_command()?;

    let mut paths: Vec<PathBuf> = match run_env.get("PATH") {
        Some(path) => env::split_paths(&path).collect(),
        None => vec![],
    };
    for i in 0..paths.len() {
        if paths[i].starts_with("/") {
            paths[i] = Path::new(&*FS_ROOT_PATH).join(paths[i].strip_prefix("/").unwrap());
        }
    }
    let joined = env::join_paths(paths)?;
    run_env.insert(
        String::from("PATH"),
        joined
            .into_string()
            .expect("Unable to convert OsStr path to string!"),
    );

    for (key, value) in run_env.into_iter() {
        debug!("Setting: {}='{}'", key, value);
        env::set_var(key, value);
    }
    let command = match find_command(&command) {
        Some(path) => path,
        None => return Err(Error::ExecCommandNotFound(command)),
    };
    let mut display_args = command.to_string_lossy().into_owned();
    for arg in &args {
        display_args.push(' ');
        display_args.push_str(arg.to_string_lossy().as_ref());
    }
    debug!("Running: {}", display_args);
    Ok(process::become_command(command, args)?)
}
<commit_msg>[hab,sup] Update to call `PackageInstall#environment_for_command()`.<commit_after>// Copyright (c) 2016 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::env;
use std::ffi::OsString;
use std::path::{Path, PathBuf};

use hcore::os::process;
use hcore::package::{PackageIdent, PackageInstall};
use hcore::fs::{find_command, FS_ROOT_PATH};

use error::{Error, Result};

pub fn start<T>(ident: &PackageIdent, command: T, args: Vec<OsString>) -> Result<()>
where
    T: Into<PathBuf>,
{
    let command = command.into();
    let pkg_install = PackageInstall::load(&ident, Some(&*FS_ROOT_PATH))?;
    let mut cmd_env = pkg_install.environment_for_command()?;

    let mut paths: Vec<PathBuf> = match cmd_env.get("PATH") {
        Some(path) => env::split_paths(&path).collect(),
        None => vec![],
    };
    for i in 0..paths.len() {
        if paths[i].starts_with("/") {
            paths[i] = Path::new(&*FS_ROOT_PATH).join(paths[i].strip_prefix("/").unwrap());
        }
    }
    let joined = env::join_paths(paths)?;
    cmd_env.insert(
        String::from("PATH"),
        joined
            .into_string()
            .expect("Unable to convert OsStr path to string!"),
    );

    for (key, value) in cmd_env.into_iter() {
        debug!("Setting: {}='{}'", key, value);
        env::set_var(key, value);
    }
    let command = match find_command(&command) {
        Some(path) => path,
        None => return Err(Error::ExecCommandNotFound(command)),
    };
    let mut display_args = command.to_string_lossy().into_owned();
    for arg in &args {
        display_args.push(' ');
        display_args.push_str(arg.to_string_lossy().as_ref());
    }
    debug!("Running: {}", display_args);
    Ok(process::become_command(command, args)?)
}
<|endoftext|>


<commit_before>/**
    The layout task. Performs layout on the DOM, builds display lists and sends them to be
    rendered.
*/

use au = gfx::geometry;
use au::au;
use content::content_task;
use core::dvec::DVec;
use css::resolve::apply::apply_style;
use css::values::Stylesheet;
use dl = gfx::display_list;
use dom::event::{Event, ReflowEvent};
use dom::node::{Node, LayoutData};
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::render_task;
use gfx::render_layers::RenderLayer;
use layout::box::RenderBox;
use layout::box_builder::LayoutTreeBuilder;
use layout::context::LayoutContext;
use opt = core::option;
use render_task::RenderTask;
use resource::image_cache_task::{ImageCacheTask, ImageResponseMsg};
use resource::local_image_cache::LocalImageCache;
use servo_text::font_cache::FontCache;
use std::arc::ARC;
use std::net::url::Url;
use core::util::replace;

use layout::traverse::*;
use comm::*;
use task::*;

pub type LayoutTask = comm::Chan<Msg>;

pub enum LayoutQuery {
    ContentBox(Node)
}

pub type LayoutQueryResponse = Result<LayoutQueryResponse_, ()>;

enum LayoutQueryResponse_ {
    ContentSize(Size2D<int>)
}

pub enum Msg {
    BuildMsg(Node, ARC<Stylesheet>, Url, comm::Chan<Event>, Size2D<uint>, pipes::Chan<()>),
    QueryMsg(LayoutQuery, comm::Chan<LayoutQueryResponse>),
    ExitMsg
}

fn LayoutTask(render_task: RenderTask,
              img_cache_task: ImageCacheTask) -> LayoutTask {
    do spawn_listener::<Msg> |from_content| {
        Layout(render_task, img_cache_task.clone(), from_content).start();
    }
}

struct Layout {
    render_task: RenderTask,
    image_cache_task: ImageCacheTask,
    local_image_cache: @LocalImageCache,
    from_content: comm::Port<Msg>,

    font_cache: @FontCache,
    // This is used to root auxilliary RCU reader data
    layout_refs: DVec<@LayoutData>
}

fn Layout(render_task: RenderTask,
         image_cache_task: ImageCacheTask,
         from_content: comm::Port<Msg>) -> Layout {

    Layout {
        render_task: render_task,
        image_cache_task: image_cache_task.clone(),
        local_image_cache: @LocalImageCache(move image_cache_task),
        from_content: from_content,
        font_cache: FontCache(),
        layout_refs: DVec()
    }
}

impl Layout {

    fn start() {
        while self.handle_request() {
            // loop indefinitely
        }
    }

    fn handle_request() -> bool {

        match self.from_content.recv() {
            BuildMsg(move node, move styles, move doc_url,
                     move to_content, move window_size, move join_chan) => {
                self.handle_build(node, styles, doc_url, to_content, window_size, join_chan);
            }
            QueryMsg(query, chan) => self.handle_query(query, chan),
            ExitMsg => {
                debug!("layout: ExitMsg received");
                return false
            }
        }

        true
    }

    fn handle_build(node: Node, styles: ARC<Stylesheet>, doc_url: Url,
                    to_content: comm::Chan<Event>, window_size: Size2D<uint>,
                    join_chan: pipes::Chan<()>) {
        debug!("layout: received layout request for: %s", doc_url.to_str());
        debug!("layout: parsed Node tree");
        debug!("%?", node.dump());

        // Reset the image cache
        self.local_image_cache.next_round(self.make_on_image_available_cb(to_content));

        let screen_size = Size2D(au::from_px(window_size.width as int),
                                 au::from_px(window_size.height as int));

        let layout_ctx = LayoutContext {
            image_cache: self.local_image_cache,
            font_cache: self.font_cache,
            doc_url: doc_url,
            screen_size: Rect(Point2D(au(0), au(0)), screen_size)
        };

        let layout_root: @FlowContext = do util::time::time("layout: tree construction") {
            // TODO: this is dumb. we don't need 3 separate traversals.
            node.initialize_style_for_subtree(&layout_ctx, &self.layout_refs);
            node.recompute_style_for_subtree(&layout_ctx, &styles);
            /* resolve styles (convert relative values) down the node tree */
            apply_style(&layout_ctx, node);

            let builder = LayoutTreeBuilder();
            let layout_root: @FlowContext = match builder.construct_trees(&layout_ctx,
                                                                          node) {
                Ok(root) => root,
                Err(*) => fail ~"Root flow should always exist"
            };

            debug!("layout: constructed Flow tree");
            debug!("%?", layout_root.dump());

            layout_root
        };

        do util::time::time("layout: main layout") {
            /* perform layout passes over the flow tree */
            do layout_root.traverse_postorder |f| { f.bubble_widths(&layout_ctx) }
            do layout_root.traverse_preorder  |f| { f.assign_widths(&layout_ctx) }
            do layout_root.traverse_postorder |f| { f.assign_height(&layout_ctx) }
        }

        do util::time::time("layout: display list building") {
            let dlist = DVec();
            let builder = dl::DisplayListBuilder {
                ctx: &layout_ctx,
            };
            let render_layer = RenderLayer {
                display_list: move dlist,
                size: Size2D(au::to_px(screen_size.width) as uint,
                             au::to_px(screen_size.height) as uint)
            };

            // TODO: set options on the builder before building
            // TODO: be smarter about what needs painting
            layout_root.build_display_list(&builder, &copy layout_root.d().position,
                                           &render_layer.display_list);
            self.render_task.send(render_task::RenderMsg(move render_layer));
        } // time(layout: display list building)

        // Tell content we're done
        join_chan.send(());

    }

    fn handle_query(query: LayoutQuery,
                    reply_chan: comm::Chan<LayoutQueryResponse>) {
        match query {
            ContentBox(node) => {
                // TODO: extract me to a method when I get sibling arms
                let response = match node.aux(|a| copy *a).flow {
                    None => Err(()),
                    Some(flow) => {
                        let start_val : Option<Rect<au>> = None;
                        let rect = do flow.foldl_boxes_for_node(node, start_val) |acc, box| {
                            match acc {
                                Some(acc) => Some(acc.union(&box.content_box())),
                                None => Some(box.content_box())
                            }
                        };

                        match rect {
                            None => Err(()),
                            Some(rect) => {
                                let size = Size2D(au::to_px(rect.size.width),
                                                  au::to_px(rect.size.height));
                                Ok(ContentSize(move size))
                            }
                        }
                    }
                };

                reply_chan.send(response)
            }
        }
    }

    // When images can't be loaded in time to display they trigger
    // this callback in some task somewhere. This w
    fn make_on_image_available_cb(to_content: comm::Chan<Event>) -> ~fn(ImageResponseMsg) {
        let f: ~fn(ImageResponseMsg) = |_msg| {
            to_content.send(ReflowEvent)
        };
        return f;
    }
}

<commit_msg>Add more timing to layout_task<commit_after>/**
    The layout task. Performs layout on the DOM, builds display lists and sends them to be
    rendered.
*/

use au = gfx::geometry;
use au::au;
use content::content_task;
use core::dvec::DVec;
use css::resolve::apply::apply_style;
use css::values::Stylesheet;
use dl = gfx::display_list;
use dom::event::{Event, ReflowEvent};
use dom::node::{Node, LayoutData};
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::render_task;
use gfx::render_layers::RenderLayer;
use layout::box::RenderBox;
use layout::box_builder::LayoutTreeBuilder;
use layout::context::LayoutContext;
use opt = core::option;
use render_task::RenderTask;
use resource::image_cache_task::{ImageCacheTask, ImageResponseMsg};
use resource::local_image_cache::LocalImageCache;
use servo_text::font_cache::FontCache;
use std::arc::ARC;
use std::net::url::Url;
use core::util::replace;
use util::time::time;
use std::cell::Cell;
use layout::traverse::*;
use comm::*;
use task::*;

pub type LayoutTask = comm::Chan<Msg>;

pub enum LayoutQuery {
    ContentBox(Node)
}

pub type LayoutQueryResponse = Result<LayoutQueryResponse_, ()>;

enum LayoutQueryResponse_ {
    ContentSize(Size2D<int>)
}

pub enum Msg {
    BuildMsg(Node, ARC<Stylesheet>, Url, comm::Chan<Event>, Size2D<uint>, pipes::Chan<()>),
    QueryMsg(LayoutQuery, comm::Chan<LayoutQueryResponse>),
    ExitMsg
}

fn LayoutTask(render_task: RenderTask,
              img_cache_task: ImageCacheTask) -> LayoutTask {
    do spawn_listener::<Msg> |from_content| {
        Layout(render_task, img_cache_task.clone(), from_content).start();
    }
}

struct Layout {
    render_task: RenderTask,
    image_cache_task: ImageCacheTask,
    local_image_cache: @LocalImageCache,
    from_content: comm::Port<Msg>,

    font_cache: @FontCache,
    // This is used to root auxilliary RCU reader data
    layout_refs: DVec<@LayoutData>
}

fn Layout(render_task: RenderTask,
         image_cache_task: ImageCacheTask,
         from_content: comm::Port<Msg>) -> Layout {

    Layout {
        render_task: render_task,
        image_cache_task: image_cache_task.clone(),
        local_image_cache: @LocalImageCache(move image_cache_task),
        from_content: from_content,
        font_cache: FontCache(),
        layout_refs: DVec()
    }
}

impl Layout {

    fn start() {
        while self.handle_request() {
            // loop indefinitely
        }
    }

    fn handle_request() -> bool {

        match self.from_content.recv() {
            BuildMsg(move node, move styles, move doc_url,
                     move to_content, move window_size, move join_chan) => {

                let styles = Cell(styles);
                let doc_url = Cell(doc_url);
                let join_chan = Cell(join_chan);

                do time("layout: performing layout") {
                    self.handle_build(node, styles.take(), doc_url.take(), to_content, window_size, join_chan.take());
                }

            }
            QueryMsg(query, chan) => {
                do time("layout: querying layout") {
                    self.handle_query(query, chan)
                }
            }
            ExitMsg => {
                debug!("layout: ExitMsg received");
                return false
            }
        }

        true
    }

    fn handle_build(node: Node, styles: ARC<Stylesheet>, doc_url: Url,
                    to_content: comm::Chan<Event>, window_size: Size2D<uint>,
                    join_chan: pipes::Chan<()>) {
        debug!("layout: received layout request for: %s", doc_url.to_str());
        debug!("layout: parsed Node tree");
        debug!("%?", node.dump());

        // Reset the image cache
        self.local_image_cache.next_round(self.make_on_image_available_cb(to_content));

        let screen_size = Size2D(au::from_px(window_size.width as int),
                                 au::from_px(window_size.height as int));

        let layout_ctx = LayoutContext {
            image_cache: self.local_image_cache,
            font_cache: self.font_cache,
            doc_url: doc_url,
            screen_size: Rect(Point2D(au(0), au(0)), screen_size)
        };

        let layout_root: @FlowContext = do time("layout: tree construction") {
            // TODO: this is dumb. we don't need 3 separate traversals.
            node.initialize_style_for_subtree(&layout_ctx, &self.layout_refs);
            node.recompute_style_for_subtree(&layout_ctx, &styles);
            /* resolve styles (convert relative values) down the node tree */
            apply_style(&layout_ctx, node);

            let builder = LayoutTreeBuilder();
            let layout_root: @FlowContext = match builder.construct_trees(&layout_ctx,
                                                                          node) {
                Ok(root) => root,
                Err(*) => fail ~"Root flow should always exist"
            };

            debug!("layout: constructed Flow tree");
            debug!("%?", layout_root.dump());

            layout_root
        };

        do time("layout: main layout") {
            /* perform layout passes over the flow tree */
            do layout_root.traverse_postorder |f| { f.bubble_widths(&layout_ctx) }
            do layout_root.traverse_preorder  |f| { f.assign_widths(&layout_ctx) }
            do layout_root.traverse_postorder |f| { f.assign_height(&layout_ctx) }
        }

        do time("layout: display list building") {
            let dlist = DVec();
            let builder = dl::DisplayListBuilder {
                ctx: &layout_ctx,
            };
            let render_layer = RenderLayer {
                display_list: move dlist,
                size: Size2D(au::to_px(screen_size.width) as uint,
                             au::to_px(screen_size.height) as uint)
            };

            // TODO: set options on the builder before building
            // TODO: be smarter about what needs painting
            layout_root.build_display_list(&builder, &copy layout_root.d().position,
                                           &render_layer.display_list);
            self.render_task.send(render_task::RenderMsg(move render_layer));
        } // time(layout: display list building)

        // Tell content we're done
        join_chan.send(());

    }

    fn handle_query(query: LayoutQuery,
                    reply_chan: comm::Chan<LayoutQueryResponse>) {
        match query {
            ContentBox(node) => {
                // TODO: extract me to a method when I get sibling arms
                let response = match node.aux(|a| copy *a).flow {
                    None => Err(()),
                    Some(flow) => {
                        let start_val : Option<Rect<au>> = None;
                        let rect = do flow.foldl_boxes_for_node(node, start_val) |acc, box| {
                            match acc {
                                Some(acc) => Some(acc.union(&box.content_box())),
                                None => Some(box.content_box())
                            }
                        };

                        match rect {
                            None => Err(()),
                            Some(rect) => {
                                let size = Size2D(au::to_px(rect.size.width),
                                                  au::to_px(rect.size.height));
                                Ok(ContentSize(move size))
                            }
                        }
                    }
                };

                reply_chan.send(response)
            }
        }
    }

    // When images can't be loaded in time to display they trigger
    // this callback in some task somewhere. This w
    fn make_on_image_available_cb(to_content: comm::Chan<Event>) -> ~fn(ImageResponseMsg) {
        let f: ~fn(ImageResponseMsg) = |_msg| {
            to_content.send(ReflowEvent)
        };
        return f;
    }
}

<|endoftext|>


<commit_before>//! # Basic Subclass example
//!
//! This file creates a `GtkApplication` and a `GtkApplicationWindow` subclass
//! and showcases how you can override virtual funcitons such as `startup`
//! and `activate` and how to interact with the GObjects and their private
//! structs.

#[macro_use]
extern crate glib;
extern crate gio;
extern crate gtk;

extern crate once_cell;

use gio::prelude::*;
use gtk::prelude::*;

use gio::subclass::application::ApplicationImplExt;
use gio::ApplicationFlags;
use glib::subclass;
use glib::subclass::prelude::*;
use glib::translate::*;
use gtk::subclass::prelude::*;

use once_cell::unsync::OnceCell;
use std::cell::Cell;

#[derive(Debug)]
struct WindowWidgets {
    headerbar: gtk::HeaderBar,
    increment: gtk::Button,
    label: gtk::Label,
}

// This is the private part of our `SimpleWindow` object.
// Its where state and widgets are stored when they don't
// need to be publicly accesible.
#[derive(Debug)]
pub struct SimpleWindowPrivate {
    widgets: OnceCell<WindowWidgets>,
    counter: Cell<u64>,
}

impl ObjectSubclass for SimpleWindowPrivate {
    const NAME: &'static str = "SimpleWindowPrivate";
    type ParentType = gtk::ApplicationWindow;
    type Instance = subclass::simple::InstanceStruct<Self>;
    type Class = subclass::simple::ClassStruct<Self>;

    glib_object_subclass!();

    fn new() -> Self {
        Self {
            widgets: OnceCell::new(),
            counter: Cell::new(0),
        }
    }
}

impl ObjectImpl for SimpleWindowPrivate {
    glib_object_impl!();

    // Here we are overriding the glib::Objcet::contructed
    // method. Its what gets called when we create our Object
    // and where we can initialize things.
    fn constructed(&self, obj: &glib::Object) {
        self.parent_constructed(obj);

        let self_ = obj.downcast_ref::<SimpleWindow>().unwrap();

        let headerbar = gtk::HeaderBar::new();
        let increment = gtk::Button::new_with_label("Increment!");
        let label = gtk::Label::new(Some("Press the Increment Button!"));

        headerbar.set_title(Some("Hello World!"));
        headerbar.set_show_close_button(true);
        headerbar.pack_start(&increment);

        // Connect our method `on_increment_clicked` to be called
        // when the increment button is clicked.
        increment.connect_clicked(clone!(@weak self_ => move |_| {
            let priv_ = SimpleWindowPrivate::from_instance(&self_);
            priv_.on_increment_clicked();
        }));

        self_.add(&label);
        self_.set_titlebar(Some(&headerbar));
        self_.set_default_size(640, 480);

        self.widgets
            .set(WindowWidgets {
                headerbar,
                label,
                increment,
            })
            .expect("Failed to initialize window state");
    }
}

impl SimpleWindowPrivate {
    fn on_increment_clicked(&self) {
        self.counter.set(self.counter.get() + 1);
        let w = self.widgets.get().unwrap();
        w.label
            .set_text(&format!("Counter is {}", self.counter.get()));
    }
}

impl WidgetImpl for SimpleWindowPrivate {}
impl ContainerImpl for SimpleWindowPrivate {}
impl BinImpl for SimpleWindowPrivate {}
impl WindowImpl for SimpleWindowPrivate {}
impl ApplicationWindowImpl for SimpleWindowPrivate {}

glib_wrapper! {
    pub struct SimpleWindow(
        Object<subclass::simple::InstanceStruct<SimpleWindowPrivate>,
        subclass::simple::ClassStruct<SimpleWindowPrivate>,
        SimpleAppWindowClass>)
        @extends gtk::Widget, gtk::Container, gtk::Bin, gtk::Window, gtk::ApplicationWindow;

    match fn {
        get_type => || SimpleWindowPrivate::get_type().to_glib(),
    }
}

impl SimpleWindow {
    pub fn new(app: &gtk::Application) -> Self {
        glib::Object::new(Self::static_type(), &[("application", app)])
            .expect("Failed to create SimpleWindow")
            .downcast::<SimpleWindow>()
            .expect("Created SimpleWindow is of wrong type")
    }
}

#[derive(Debug)]
pub struct SimpleApplicationPrivate {
    window: OnceCell<SimpleWindow>,
}

impl ObjectSubclass for SimpleApplicationPrivate {
    const NAME: &'static str = "SimpleApplicationPrivate";
    type ParentType = gtk::Application;
    type Instance = subclass::simple::InstanceStruct<Self>;
    type Class = subclass::simple::ClassStruct<Self>;

    glib_object_subclass!();

    fn new() -> Self {
        Self {
            window: OnceCell::new(),
        }
    }
}

impl ObjectImpl for SimpleApplicationPrivate {
    glib_object_impl!();
}

// When our application starts, the `startup` signal will be fired.
// This gives us a chance to perform initialisation tasks that are not directly
// related to showing a new window. After this, depending on how
// the application is started, either `activate` or `open` will be called next.
impl ApplicationImpl for SimpleApplicationPrivate {
    // `gio::Application::activate` is what gets called when the
    // application is launched by the desktop environment and
    // aksed to present itself.
    fn activate(&self, app: &gio::Application) {
        let app = app.downcast_ref::<gtk::Application>().unwrap();
        let priv_ = SimpleApplicationPrivate::from_instance(app);
        let window = priv_
            .window
            .get()
            .expect("Should always be initiliazed in gio_application_startup");
        window.show_all();
        window.present();
    }

    // `gio::Application` is bit special. It does not get initialized
    // when `new` is called and the object created, but rather
    // once the `startup` signal is emitted and the `gio::Application::startup`
    // is called.
    //
    // Due to this, we create and initialize the `SimpleWindow` widget
    // here. Widgets can't be created before `startup` has been called.
    fn startup(&self, app: &gio::Application) {
        self.parent_startup(app);

        let app = app.downcast_ref::<gtk::Application>().unwrap();
        let priv_ = SimpleApplicationPrivate::from_instance(app);
        let window = SimpleWindow::new(&app);
        priv_
            .window
            .set(window)
            .expect("Failed to initialize application window");
    }
}

impl GtkApplicationImpl for SimpleApplicationPrivate {}

glib_wrapper! {
    pub struct SimpleApplication(
        Object<subclass::simple::InstanceStruct<SimpleApplicationPrivate>,
        subclass::simple::ClassStruct<SimpleApplicationPrivate>,
        SimpleApplicationClass>)
        @extends gio::Application, gtk::Application;

    match fn {
        get_type => || SimpleApplicationPrivate::get_type().to_glib(),
    }
}

impl SimpleApplication {
    pub fn new() -> Self {
        glib::Object::new(
            Self::static_type(),
            &[
                ("application-id", &"org.gtk-rs.SimpleApplication"),
                ("flags", &ApplicationFlags::empty()),
            ],
        )
        .expect("Failed to create SimpleApp")
        .downcast()
        .expect("Created simpleapp is of wrong type")
    }
}

fn main() {
    gtk::init().expect("Failed to initialize gtk");

    let app = SimpleApplication::new();

    let args: Vec<String> = std::env::args().collect();
    app.run(&args);
}
<commit_msg>basic_subclass: fix name of our GObject subclasss type<commit_after>//! # Basic Subclass example
//!
//! This file creates a `GtkApplication` and a `GtkApplicationWindow` subclass
//! and showcases how you can override virtual funcitons such as `startup`
//! and `activate` and how to interact with the GObjects and their private
//! structs.

#[macro_use]
extern crate glib;
extern crate gio;
extern crate gtk;

extern crate once_cell;

use gio::prelude::*;
use gtk::prelude::*;

use gio::subclass::application::ApplicationImplExt;
use gio::ApplicationFlags;
use glib::subclass;
use glib::subclass::prelude::*;
use glib::translate::*;
use gtk::subclass::prelude::*;

use once_cell::unsync::OnceCell;
use std::cell::Cell;

#[derive(Debug)]
struct WindowWidgets {
    headerbar: gtk::HeaderBar,
    increment: gtk::Button,
    label: gtk::Label,
}

// This is the private part of our `SimpleWindow` object.
// Its where state and widgets are stored when they don't
// need to be publicly accesible.
#[derive(Debug)]
pub struct SimpleWindowPrivate {
    widgets: OnceCell<WindowWidgets>,
    counter: Cell<u64>,
}

impl ObjectSubclass for SimpleWindowPrivate {
    const NAME: &'static str = "SimpleWindow";
    type ParentType = gtk::ApplicationWindow;
    type Instance = subclass::simple::InstanceStruct<Self>;
    type Class = subclass::simple::ClassStruct<Self>;

    glib_object_subclass!();

    fn new() -> Self {
        Self {
            widgets: OnceCell::new(),
            counter: Cell::new(0),
        }
    }
}

impl ObjectImpl for SimpleWindowPrivate {
    glib_object_impl!();

    // Here we are overriding the glib::Objcet::contructed
    // method. Its what gets called when we create our Object
    // and where we can initialize things.
    fn constructed(&self, obj: &glib::Object) {
        self.parent_constructed(obj);

        let self_ = obj.downcast_ref::<SimpleWindow>().unwrap();

        let headerbar = gtk::HeaderBar::new();
        let increment = gtk::Button::new_with_label("Increment!");
        let label = gtk::Label::new(Some("Press the Increment Button!"));

        headerbar.set_title(Some("Hello World!"));
        headerbar.set_show_close_button(true);
        headerbar.pack_start(&increment);

        // Connect our method `on_increment_clicked` to be called
        // when the increment button is clicked.
        increment.connect_clicked(clone!(@weak self_ => move |_| {
            let priv_ = SimpleWindowPrivate::from_instance(&self_);
            priv_.on_increment_clicked();
        }));

        self_.add(&label);
        self_.set_titlebar(Some(&headerbar));
        self_.set_default_size(640, 480);

        self.widgets
            .set(WindowWidgets {
                headerbar,
                label,
                increment,
            })
            .expect("Failed to initialize window state");
    }
}

impl SimpleWindowPrivate {
    fn on_increment_clicked(&self) {
        self.counter.set(self.counter.get() + 1);
        let w = self.widgets.get().unwrap();
        w.label
            .set_text(&format!("Counter is {}", self.counter.get()));
    }
}

impl WidgetImpl for SimpleWindowPrivate {}
impl ContainerImpl for SimpleWindowPrivate {}
impl BinImpl for SimpleWindowPrivate {}
impl WindowImpl for SimpleWindowPrivate {}
impl ApplicationWindowImpl for SimpleWindowPrivate {}

glib_wrapper! {
    pub struct SimpleWindow(
        Object<subclass::simple::InstanceStruct<SimpleWindowPrivate>,
        subclass::simple::ClassStruct<SimpleWindowPrivate>,
        SimpleAppWindowClass>)
        @extends gtk::Widget, gtk::Container, gtk::Bin, gtk::Window, gtk::ApplicationWindow;

    match fn {
        get_type => || SimpleWindowPrivate::get_type().to_glib(),
    }
}

impl SimpleWindow {
    pub fn new(app: &gtk::Application) -> Self {
        glib::Object::new(Self::static_type(), &[("application", app)])
            .expect("Failed to create SimpleWindow")
            .downcast::<SimpleWindow>()
            .expect("Created SimpleWindow is of wrong type")
    }
}

#[derive(Debug)]
pub struct SimpleApplicationPrivate {
    window: OnceCell<SimpleWindow>,
}

impl ObjectSubclass for SimpleApplicationPrivate {
    const NAME: &'static str = "SimpleApplication";
    type ParentType = gtk::Application;
    type Instance = subclass::simple::InstanceStruct<Self>;
    type Class = subclass::simple::ClassStruct<Self>;

    glib_object_subclass!();

    fn new() -> Self {
        Self {
            window: OnceCell::new(),
        }
    }
}

impl ObjectImpl for SimpleApplicationPrivate {
    glib_object_impl!();
}

// When our application starts, the `startup` signal will be fired.
// This gives us a chance to perform initialisation tasks that are not directly
// related to showing a new window. After this, depending on how
// the application is started, either `activate` or `open` will be called next.
impl ApplicationImpl for SimpleApplicationPrivate {
    // `gio::Application::activate` is what gets called when the
    // application is launched by the desktop environment and
    // aksed to present itself.
    fn activate(&self, app: &gio::Application) {
        let app = app.downcast_ref::<gtk::Application>().unwrap();
        let priv_ = SimpleApplicationPrivate::from_instance(app);
        let window = priv_
            .window
            .get()
            .expect("Should always be initiliazed in gio_application_startup");
        window.show_all();
        window.present();
    }

    // `gio::Application` is bit special. It does not get initialized
    // when `new` is called and the object created, but rather
    // once the `startup` signal is emitted and the `gio::Application::startup`
    // is called.
    //
    // Due to this, we create and initialize the `SimpleWindow` widget
    // here. Widgets can't be created before `startup` has been called.
    fn startup(&self, app: &gio::Application) {
        self.parent_startup(app);

        let app = app.downcast_ref::<gtk::Application>().unwrap();
        let priv_ = SimpleApplicationPrivate::from_instance(app);
        let window = SimpleWindow::new(&app);
        priv_
            .window
            .set(window)
            .expect("Failed to initialize application window");
    }
}

impl GtkApplicationImpl for SimpleApplicationPrivate {}

glib_wrapper! {
    pub struct SimpleApplication(
        Object<subclass::simple::InstanceStruct<SimpleApplicationPrivate>,
        subclass::simple::ClassStruct<SimpleApplicationPrivate>,
        SimpleApplicationClass>)
        @extends gio::Application, gtk::Application;

    match fn {
        get_type => || SimpleApplicationPrivate::get_type().to_glib(),
    }
}

impl SimpleApplication {
    pub fn new() -> Self {
        glib::Object::new(
            Self::static_type(),
            &[
                ("application-id", &"org.gtk-rs.SimpleApplication"),
                ("flags", &ApplicationFlags::empty()),
            ],
        )
        .expect("Failed to create SimpleApp")
        .downcast()
        .expect("Created simpleapp is of wrong type")
    }
}

fn main() {
    gtk::init().expect("Failed to initialize gtk");

    let app = SimpleApplication::new();

    let args: Vec<String> = std::env::args().collect();
    app.run(&args);
}
<|endoftext|>


<commit_before>extern crate gcc;
extern crate semver;

use semver::{Version, VersionReq};
use semver::ParseError::IncorrectParse;
use std::process::Command;

/// Get the output from running `llvm-config` with the given argument.
fn llvm_config(arg: &str) -> String {
    let stdout = Command::new("llvm-config")
        .arg(arg)
        .output()
        .ok().expect("llvm-config not found. Install LLVM before attempting to build.")
        .stdout;

    String::from_utf8(stdout).ok().expect("llvm-config output was not UTF-8.")
}

/// Get the LLVM version using llvm-config.
fn llvm_version() -> Version {
    match Version::parse(&llvm_config("--version")) {
        // Ignore partial error; particularly constructs like '3.8.0svn' should be accepted,
        // despite being invalid semver.
        Err(IncorrectParse(v, _)) | Ok(v) => v,
        _ => panic!("Could not determine LLVM version from llvm-config."),
    }
}

fn main() {
    // Check for LLVM 3.6 or greater.
    let minimum_llvm_version = VersionReq::parse(">=3.6").unwrap();
    let version = llvm_version();
    if minimum_llvm_version.matches(&version) {
        println!("Found LLVM version {}", version);
    } else {
        panic!("LLVM version 3.6 or higher is required. (Found {})", version);
    };

    // Parse library linking flags from llvm-config.
    for arg in llvm_config("--ldflags").split_whitespace() {
        if arg.starts_with("-L") {
            println!("cargo:rustc-link-search=native={}", &arg[2..]);
        }
    }

    for arg in llvm_config("--libs").split_whitespace() {
        if arg.starts_with("-l") {
            println!("cargo:rustc-link-lib=static={}", &arg[2..]);
        }
    }

    for arg in llvm_config("--system-libs").split_whitespace() {
        if arg.starts_with("-l") {
            println!("cargo:rustc-link-lib=dylib={}", &arg[2..]);
        }
    }

    // Determine which C++ standard library to use: LLVM's or GCC's.
    let cxxflags = llvm_config("--cxxflags");
    let libcpp = if cxxflags.contains("stdlib=libc++") { "c++" } else { "stdc++" };
    println!("cargo:rustc-link-lib={}", libcpp);

    // Build the extra wrapper functions.
    std::env::set_var("CFLAGS", llvm_config("--cflags").trim());
    gcc::compile_library("libtargetwrappers.a", &["wrappers/target.c"]);
}
<commit_msg>Don't try to link stdc++ on Windows.<commit_after>extern crate gcc;
extern crate semver;

use semver::{Version, VersionReq};
use semver::ParseError::IncorrectParse;
use std::process::Command;

/// Get the output from running `llvm-config` with the given argument.
fn llvm_config(arg: &str) -> String {
    let stdout = Command::new("llvm-config")
        .arg(arg)
        .output()
        .ok().expect("llvm-config not found. Install LLVM before attempting to build.")
        .stdout;

    String::from_utf8(stdout).ok().expect("llvm-config output was not UTF-8.")
}

/// Get the LLVM version using llvm-config.
fn llvm_version() -> Version {
    match Version::parse(&llvm_config("--version")) {
        // Ignore partial error; particularly constructs like '3.8.0svn' should be accepted,
        // despite being invalid semver.
        Err(IncorrectParse(v, _)) | Ok(v) => v,
        _ => panic!("Could not determine LLVM version from llvm-config."),
    }
}

fn main() {
    // Check for LLVM 3.6 or greater.
    let minimum_llvm_version = VersionReq::parse(">=3.6").unwrap();
    let version = llvm_version();
    if minimum_llvm_version.matches(&version) {
        println!("Found LLVM version {}", version);
    } else {
        panic!("LLVM version 3.6 or higher is required. (Found {})", version);
    };

    // Parse library linking flags from llvm-config.
    for arg in llvm_config("--ldflags").split_whitespace() {
        if arg.starts_with("-L") {
            println!("cargo:rustc-link-search=native={}", &arg[2..]);
        }
    }

    for arg in llvm_config("--libs").split_whitespace() {
        if arg.starts_with("-l") {
            println!("cargo:rustc-link-lib=static={}", &arg[2..]);
        }
    }

    for arg in llvm_config("--system-libs").split_whitespace() {
        if arg.starts_with("-l") {
            println!("cargo:rustc-link-lib=dylib={}", &arg[2..]);
        }
    }

    // This breaks the link step on Windows with MSVC.
    if !cfg!(windows) {
        // Determine which C++ standard library to use: LLVM's or GCC's.
        let cxxflags = llvm_config("--cxxflags");
        let libcpp = if cxxflags.contains("stdlib=libc++") { "c++" } else { "stdc++" };
        println!("cargo:rustc-link-lib={}", libcpp);
    }

    // Build the extra wrapper functions.
    std::env::set_var("CFLAGS", llvm_config("--cflags").trim());
    gcc::compile_library("libtargetwrappers.a", &["wrappers/target.c"]);
}
<|endoftext|>


<commit_before>fn main() {
    println!("cargo:rerun-if-changed=build.rs");

    #[cfg(all(feature = "external_asm", windows))]
    compile_error!("\"external_asm\" feature is not available on windows!");

    #[cfg(all(feature = "instructions", not(target_arch = "x86_64")))]
    compile_error!("\"instructions\" feature is only available for x86_64 targets!");

    #[cfg(all(
        feature = "instructions",
        not(feature = "inline_asm"),
        not(feature = "external_asm")
    ))]
    compile_error!("\"instructions\" feature is enabled, but neither feature \"external_asm\" nor \"inline_asm\" was set!");

    #[cfg(all(feature = "inline_asm", feature = "external_asm"))]
    compile_error!(
        "\"inline_asm\" and \"external_asm\" features can not be enabled at the same time!"
    );

    #[cfg(all(feature = "instructions", feature = "external_asm"))]
    {
        use std::ffi::OsString;
        use std::fs;

        let entries = fs::read_dir("src/asm")
            .unwrap()
            .filter_map(|f| {
                f.ok().and_then(|e| {
                    let path = e.path();
                    match path.extension() {
                        Some(ext) if ext.eq(&OsString::from("s")) => Some(path),
                        _ => None,
                    }
                })
            })
            .collect::<Vec<_>>();

        cc::Build::new()
            .no_default_flags(true)
            .files(&entries)
            .pic(true)
            .static_flag(true)
            .shared_flag(false)
            .compile("x86_64_asm");

        for e in entries {
            println!("cargo:rerun-if-changed={}", e.to_str().unwrap());
        }
    }
}
<commit_msg>Fix build script architecture check<commit_after>fn main() {
    println!("cargo:rerun-if-changed=build.rs");

    #[cfg(all(feature = "external_asm", windows))]
    compile_error!("\"external_asm\" feature is not available on windows toolchain!");

    #[cfg(feature = "instructions")]
    if std::env::var("CARGO_CFG_TARGET_ARCH").unwrap() != "x86_64" {
        panic!("\"instructions\" feature is only available for x86_64 targets!");
    }

    #[cfg(all(
        feature = "instructions",
        not(feature = "inline_asm"),
        not(feature = "external_asm")
    ))]
    compile_error!("\"instructions\" feature is enabled, but neither feature \"external_asm\" nor \"inline_asm\" was set!");

    #[cfg(all(feature = "inline_asm", feature = "external_asm"))]
    compile_error!(
        "\"inline_asm\" and \"external_asm\" features can not be enabled at the same time!"
    );

    #[cfg(all(feature = "instructions", feature = "external_asm"))]
    {
        use std::ffi::OsString;
        use std::fs;

        let entries = fs::read_dir("src/asm")
            .unwrap()
            .filter_map(|f| {
                f.ok().and_then(|e| {
                    let path = e.path();
                    match path.extension() {
                        Some(ext) if ext.eq(&OsString::from("s")) => Some(path),
                        _ => None,
                    }
                })
            })
            .collect::<Vec<_>>();

        cc::Build::new()
            .no_default_flags(true)
            .files(&entries)
            .pic(true)
            .static_flag(true)
            .shared_flag(false)
            .compile("x86_64_asm");

        for e in entries {
            println!("cargo:rerun-if-changed={}", e.to_str().unwrap());
        }
    }
}
<|endoftext|>


<commit_before>extern crate bindgen;

use std::env;
use std::path::PathBuf;

fn main() {
    // Tell cargo to tell rustc to link the system cups
    // shared library.
    println!("cargo:rustc-link-lib=cups");

    // The bindgen::Builder is the main entry point
    // to bindgen, and lets you build up options for
    // the resulting bindings.
    let bindings = bindgen::Builder::default()
        // The input header we would like to generate
        // bindings for.
        .header("wrapper.h")
        // These fail with size issues.
        .opaque_type("__msfilterreq")
        .opaque_type("group_req")
        .opaque_type("group_source_req")
        // Finish the builder and generate the bindings.
        .generate()
        // Unwrap the Result and panic on failure.
        .expect("Unable to generate bindings");

    // Write the bindings to the $OUT_DIR/bindings.rs file.
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}
<commit_msg>Fix Linux.<commit_after>extern crate bindgen;

use std::env;
use std::path::PathBuf;

fn main() {
    // Tell cargo to tell rustc to link the system cups
    // shared library.
    println!("cargo:rustc-link-lib=cups");

    // The bindgen::Builder is the main entry point
    // to bindgen, and lets you build up options for
    // the resulting bindings.
    let bindings = bindgen::Builder::default()
        // The input header we would like to generate
        // bindings for.
        .header("wrapper.h")
        // These fail with size issues.
        .opaque_type("__msfilterreq")
        .opaque_type("group_req")
        .opaque_type("group_source_req")
        // This fails with "`IPPORT_RESERVED` already defined" on Linux.
        .hide_type("IPPORT_RESERVED")
        // Finish the builder and generate the bindings.
        .generate()
        // Unwrap the Result and panic on failure.
        .expect("Unable to generate bindings");

    // Write the bindings to the $OUT_DIR/bindings.rs file.
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

use std::process::Command;

fn main() {
  // Set Parquet version, build hash and "created by" string.
  let version = env!("CARGO_PKG_VERSION");
  let git_hash = run(Command::new("git").arg("rev-parse").arg("HEAD")).unwrap();
  let created_by = format!("parquet-rs version {} (build {})", version, git_hash);
  println!("cargo:rustc-env=PARQUET_VERSION={}", version);
  println!("cargo:rustc-env=PARQUET_BUILD={}", git_hash);
  println!("cargo:rustc-env=PARQUET_CREATED_BY={}", created_by);
}

/// Runs command and returns either content of stdout for successful execution,
/// or an error message otherwise.
fn run(command: &mut Command) -> Result<String, String> {
  println!("Running: `{:?}`", command);
  match command.output() {
    Ok(ref output) if output.status.success() => {
      Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
    },
    Ok(ref output) => {
      Err(format!("Failed: `{:?}` ({})", command, output.status))
    },
    Err(error) => {
      Err(format!("Failed: `{:?}` ({})", command, error))
    }
  }
}
<commit_msg>Fix build error when fetching git hash (#171)<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

use std::process::Command;

fn main() {
  // Set Parquet version, build hash and "created by" string.
  let version = env!("CARGO_PKG_VERSION");
  let mut created_by = format!("parquet-rs version {}", version);
  if let Ok(git_hash) = run(Command::new("git").arg("rev-parse").arg("HEAD")) {
    created_by.push_str(format!(" (build {})", git_hash).as_str());
    println!("cargo:rustc-env=PARQUET_BUILD={}", git_hash);
  }
  println!("cargo:rustc-env=PARQUET_VERSION={}", version);
  println!("cargo:rustc-env=PARQUET_CREATED_BY={}", created_by);
}

/// Runs command and returns either content of stdout for successful execution,
/// or an error message otherwise.
fn run(command: &mut Command) -> Result<String, String> {
  println!("Running: `{:?}`", command);
  match command.output() {
    Ok(ref output) if output.status.success() => {
      Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
    },
    Ok(ref output) => {
      Err(format!("Failed: `{:?}` ({})", command, output.status))
    },
    Err(error) => {
      Err(format!("Failed: `{:?}` ({})", command, error))
    }
  }
}
<|endoftext|>


<commit_before>extern mod rsfml;

mod cpu;

#[test]
fn set_V_to_NN() {
	let mut test = ::cpu::Cpu::new();
	let rom = [0x61, 0x11];
	test.load_vec(rom);
	test.cycle();
	assert!(test.V[0x1] == 0x11);
}

#[test]
fn skip_next_instruction() {
	let mut test = ::cpu::Cpu::new();
	let rom = [0x91, 0x20];
	test.V[0x1] = 1;
	test.V[0x2] = 2;
	test.load_vec(rom);
	test.cycle();
	assert!(test.pc == 0x204);

	test = ::cpu::Cpu::new();
	test.V[0x1] = 1;
	test.V[0x2] = 1;
	test.load_vec(rom);
	test.cycle();
	assert!(test.pc == 0x202);
}<commit_msg>Added more tests for opcodes<commit_after>extern mod rsfml;

mod cpu;

#[test]
fn skip_if_Vx_is_NN() {
	// 0x3xNN
	let mut test = ::cpu::Cpu::new();
	let rom = [0x31, 0x20];
	test.V[0x1] = 0x20;
	test.load_vec(rom);
	test.cycle();
	assert!(test.pc == 0x204);

	test = ::cpu::Cpu::new();
	test.V[0x1] = 0x21;
	test.load_vec(rom);
	test.cycle();
	assert!(test.pc == 0x202);
}

#[test]
fn set_V_to_NN() {
	//0x6xNN
	let mut test = ::cpu::Cpu::new();
	let rom = [0x61, 0x11];
	test.load_vec(rom);
	test.cycle();
	assert!(test.V[0x1] == 0x11);
}

#[test]
fn skip_if_Vx_isnt_Vy() {
	// 0x9xy0
	let mut test = ::cpu::Cpu::new();
	let rom = [0x91, 0x20];
	test.V[0x1] = 1;
	test.V[0x2] = 2;
	test.load_vec(rom);
	test.cycle();
	assert!(test.pc == 0x204);

	test = ::cpu::Cpu::new();
	test.V[0x1] = 1;
	test.V[0x2] = 1;
	test.load_vec(rom);
	test.cycle();
	assert!(test.pc == 0x202);
}

#[test]
fn set_I_to_NNN() {
	// 0xANNN
	let mut test = ::cpu::Cpu::new();
	let rom = [0xA1, 0x23];
	test.load_vec(rom);
	test.cycle();
	assert!(test.I == 0x123);
}

#[test]
fn fill_V0_to_Vx_from_memory() {
	// 0xFx65
	let mut test = ::cpu::Cpu::new();
	let rom = [0xF3, 0x65, 0x12, 0x34, 0x56, 0x78];
	test.load_vec(rom);
	test.I = 0x202;
	test.cycle();
	assert!(test.V[0] == 0x12);
	assert!(test.V[1] == 0x34);
	assert!(test.V[2] == 0x56);
	assert!(test.V[3] == 0x78);
}

#[test]
fn skip_if_key_is_pressed() {
	// 0xEx9E
	let mut test = ::cpu::Cpu::new();
	let rom = [0xE1, 0x9E];
	test.V[1] = 0xA;
	test.keys[0xA] = 1;
	test.load_vec(rom);
	test.cycle();
	assert!(test.pc == 0x204);

	test = ::cpu::Cpu::new();
	test.V[1] = 0xA;
	test.keys[0xA] = 0;
	test.load_vec(rom);
	test.cycle();
	assert!(test.pc == 0x202);
}

#[test]
fn skip_if_key_isnt_pressed() {
	// 0xExA1
	let mut test = ::cpu::Cpu::new();
	let rom = [0xE1, 0xA1];
	test.V[1] = 0xA;
	test.keys[0xA] = 0;
	test.load_vec(rom);
	test.cycle();
	assert!(test.pc == 0x204);

	test = ::cpu::Cpu::new();
	test.V[1] = 0xA;
	test.keys[0xA] = 1;
	test.load_vec(rom);
	test.cycle();
	assert!(test.pc == 0x202);
}<|endoftext|>