<commit_before>// P_1_2_2_01
//
// Generative Gestaltung – Creative Coding im Web
// ISBN: 978-3-87439-902-9, First Edition, Hermann Schmidt, Mainz, 2018
// Benedikt Groß, Hartmut Bohnacker, Julia Laub, Claudius Lazzeroni
// with contributions by Joey Lee and Niels Poldervaart
// Copyright 2018
//
// http://www.generative-gestaltung.de
//
// 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.

/**
 * extract and sort the color palette of an image
 *
 * MOUSE
 * position x          : resolution
 *
 * KEYS
 * Q/W/E/R             : load different images
 * 1                   : no color sorting
 * 2                   : sort colors on hue
 * 3                   : sort colors on saturation
 * 4                   : sort colors on brightness
 * 5                   : sort colors on greyscale (luminance)
 * 6                   : sort colors on red
 * 7                   : sort colors on green
 * 8                   : sort colors on blue
 * 9                   : sort colors on alpha
 * s                   : save png
 * c                   : save color palette
 */
use nannou::image;
use nannou::image::GenericImageView;
use nannou::prelude::*;
use nannou::ui::color::rgb_to_hsl;

fn main() {
    nannou::app(model).run();
}

enum SortMode {
    Red,
    Green,
    Blue,
    Hue,
    Saturation,
    Brightness,
    Grayscale,
    Alpha,
}

struct Model {
    image: image::DynamicImage,
    sort_mode: Option<SortMode>,
}

fn model(app: &App) -> Model {
    app.new_window()
        .size(600, 600)
        .view(view)
        .key_released(key_released)
        .build()
        .unwrap();

    let assets = app.assets_path().unwrap();
    let img_path = assets
        .join("images")
        .join("generative_examples")
        .join("pic1.jpg");

    let image = image::open(img_path).unwrap();
    Model {
        image,
        sort_mode: None,
    }
}

fn view(app: &App, model: &Model, frame: Frame) {
    let draw = app.draw();
    draw.background().color(WHITE);
    let win = app.window_rect();
    let tile_count = clamp(
        map_range(app.mouse.x, win.left(), win.right(), 120, 1),
        120,
        1,
    );
    let rect_size = win.w() / tile_count as f32;

    let mut colors = Vec::new();

    for grid_y in 0..tile_count as usize {
        for grid_x in 0..tile_count as usize {
            let px = grid_x as f32 * rect_size + (rect_size / 2.0);
            let py = grid_y as f32 * rect_size + (rect_size / 2.0);
            // get current color
            let c = model.image.get_pixel(px as u32, py as u32);
            let red = c[0] as f32 / 255.0;
            let green = c[1] as f32 / 255.0;
            let blue = c[2] as f32 / 255.0;
            let alpha = c[3] as f32 / 255.0;

            colors.push(rgba(red, green, blue, alpha));
        }
    }

    // sort
    if let Some(ref mode) = model.sort_mode {
        sort_colors(&mut colors, mode);
    }

    let mut i = 0;
    for grid_y in 0..tile_count as usize {
        for grid_x in 0..tile_count as usize {
            let pos_x = win.left() + grid_x as f32 * rect_size + (rect_size / 2.0);
            let pos_y = win.top() - grid_y as f32 * rect_size - (rect_size / 2.0);
            draw.rect()
                .x_y(pos_x, pos_y)
                .w_h(rect_size, rect_size)
                .color(colors[i]);
            i += 1;
        }
    }
    draw.to_frame(app, &frame).unwrap();
}

fn key_released(app: &App, model: &mut Model, key: Key) {
    let assets = app.assets_path().unwrap();
    let img_path = assets.join("images").join("generative_examples");

    match key {
        Key::Q => {
            model.image = image::open(img_path.join("pic1.jpg")).unwrap();
        }
        Key::W => {
            model.image = image::open(img_path.join("pic2.jpg")).unwrap();
        }
        Key::E => {
            model.image = image::open(img_path.join("pic3.jpg")).unwrap();
        }
        Key::R => {
            model.image = image::open(img_path.join("pic4.jpg")).unwrap();
        }
        Key::Key1 => {
            model.sort_mode = None;
        }
        Key::Key2 => {
            model.sort_mode = Some(SortMode::Hue);
        }
        Key::Key3 => {
            model.sort_mode = Some(SortMode::Saturation);
        }
        Key::Key4 => {
            model.sort_mode = Some(SortMode::Brightness);
        }
        Key::Key5 => {
            model.sort_mode = Some(SortMode::Grayscale);
        }
        Key::Key6 => {
            model.sort_mode = Some(SortMode::Red);
        }
        Key::Key7 => {
            model.sort_mode = Some(SortMode::Green);
        }
        Key::Key8 => {
            model.sort_mode = Some(SortMode::Blue);
        }
        Key::Key9 => {
            model.sort_mode = Some(SortMode::Alpha);
        }
        Key::S => {
            app.main_window()
                .capture_frame(app.exe_name().unwrap() + ".png");
        }
        _otherkey => (),
    }
}

fn sort_colors(colors: &mut Vec<Rgba>, mode: &SortMode) {
    match mode {
        SortMode::Red => {
            colors.sort_by(|a, b| a.red.partial_cmp(&b.red).unwrap());
        }
        SortMode::Green => {
            colors.sort_by(|a, b| a.green.partial_cmp(&b.green).unwrap());
        }
        SortMode::Blue => {
            colors.sort_by(|a, b| a.blue.partial_cmp(&b.blue).unwrap());
        }
        SortMode::Hue => {
            colors.sort_by(|a, b| {
                let (a_hue, _, _) = rgb_to_hsl(a.red, a.green, a.blue);
                let (b_hue, _, _) = rgb_to_hsl(b.red, b.green, b.blue);
                a_hue.partial_cmp(&b_hue).unwrap()
            });
        }
        SortMode::Saturation => {
            colors.sort_by(|a, b| {
                let (_, a_sat, _) = rgb_to_hsl(a.red, a.green, a.blue);
                let (_, b_sat, _) = rgb_to_hsl(b.red, b.green, b.blue);
                a_sat.partial_cmp(&b_sat).unwrap()
            });
        }
        SortMode::Brightness => {
            colors.sort_by(|a, b| {
                let (_, _, a_bright) = rgb_to_hsl(a.red, a.green, a.blue);
                let (_, _, b_bright) = rgb_to_hsl(b.red, b.green, b.blue);
                a_bright.partial_cmp(&b_bright).unwrap()
            });
        }
        SortMode::Alpha => {
            colors.sort_by(|a, b| a.alpha.partial_cmp(&b.alpha).unwrap());
        }
        _ => (),
    }
}
<commit_msg>Add guard for NaN when calculating saturation<commit_after>// P_1_2_2_01
//
// Generative Gestaltung – Creative Coding im Web
// ISBN: 978-3-87439-902-9, First Edition, Hermann Schmidt, Mainz, 2018
// Benedikt Groß, Hartmut Bohnacker, Julia Laub, Claudius Lazzeroni
// with contributions by Joey Lee and Niels Poldervaart
// Copyright 2018
//
// http://www.generative-gestaltung.de
//
// 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.

/**
 * extract and sort the color palette of an image
 *
 * MOUSE
 * position x          : resolution
 *
 * KEYS
 * Q/W/E/R             : load different images
 * 1                   : no color sorting
 * 2                   : sort colors on hue
 * 3                   : sort colors on saturation
 * 4                   : sort colors on brightness
 * 5                   : sort colors on greyscale (luminance)
 * 6                   : sort colors on red
 * 7                   : sort colors on green
 * 8                   : sort colors on blue
 * 9                   : sort colors on alpha
 * s                   : save png
 * c                   : save color palette
 */
use nannou::image;
use nannou::image::GenericImageView;
use nannou::prelude::*;
use nannou::ui::color::rgb_to_hsl;

fn main() {
    nannou::app(model).run();
}

enum SortMode {
    Red,
    Green,
    Blue,
    Hue,
    Saturation,
    Brightness,
    Grayscale,
    Alpha,
}

struct Model {
    image: image::DynamicImage,
    sort_mode: Option<SortMode>,
}

fn model(app: &App) -> Model {
    app.new_window()
        .size(600, 600)
        .view(view)
        .key_released(key_released)
        .build()
        .unwrap();

    let assets = app.assets_path().unwrap();
    let img_path = assets
        .join("images")
        .join("generative_examples")
        .join("pic1.jpg");

    let image = image::open(img_path).unwrap();
    Model {
        image,
        sort_mode: None,
    }
}

fn view(app: &App, model: &Model, frame: Frame) {
    let draw = app.draw();
    draw.background().color(WHITE);
    let win = app.window_rect();
    let tile_count = clamp(
        map_range(app.mouse.x, win.left(), win.right(), 120, 1),
        120,
        1,
    );
    let rect_size = win.w() / tile_count as f32;

    let mut colors = Vec::new();

    for grid_y in 0..tile_count as usize {
        for grid_x in 0..tile_count as usize {
            let px = grid_x as f32 * rect_size + (rect_size / 2.0);
            let py = grid_y as f32 * rect_size + (rect_size / 2.0);
            // get current color
            let c = model.image.get_pixel(px as u32, py as u32);
            let red = c[0] as f32 / 255.0;
            let green = c[1] as f32 / 255.0;
            let blue = c[2] as f32 / 255.0;
            let alpha = c[3] as f32 / 255.0;

            colors.push(rgba(red, green, blue, alpha));
        }
    }

    // sort
    if let Some(ref mode) = model.sort_mode {
        sort_colors(&mut colors, mode);
    }

    let mut i = 0;
    for grid_y in 0..tile_count as usize {
        for grid_x in 0..tile_count as usize {
            let pos_x = win.left() + grid_x as f32 * rect_size + (rect_size / 2.0);
            let pos_y = win.top() - grid_y as f32 * rect_size - (rect_size / 2.0);
            draw.rect()
                .x_y(pos_x, pos_y)
                .w_h(rect_size, rect_size)
                .color(colors[i]);
            i += 1;
        }
    }
    draw.to_frame(app, &frame).unwrap();
}

fn key_released(app: &App, model: &mut Model, key: Key) {
    let assets = app.assets_path().unwrap();
    let img_path = assets.join("images").join("generative_examples");

    match key {
        Key::Q => {
            model.image = image::open(img_path.join("pic1.jpg")).unwrap();
        }
        Key::W => {
            model.image = image::open(img_path.join("pic2.jpg")).unwrap();
        }
        Key::E => {
            model.image = image::open(img_path.join("pic3.jpg")).unwrap();
        }
        Key::R => {
            model.image = image::open(img_path.join("pic4.jpg")).unwrap();
        }
        Key::Key1 => {
            model.sort_mode = None;
        }
        Key::Key2 => {
            model.sort_mode = Some(SortMode::Hue);
        }
        Key::Key3 => {
            model.sort_mode = Some(SortMode::Saturation);
        }
        Key::Key4 => {
            model.sort_mode = Some(SortMode::Brightness);
        }
        Key::Key5 => {
            model.sort_mode = Some(SortMode::Grayscale);
        }
        Key::Key6 => {
            model.sort_mode = Some(SortMode::Red);
        }
        Key::Key7 => {
            model.sort_mode = Some(SortMode::Green);
        }
        Key::Key8 => {
            model.sort_mode = Some(SortMode::Blue);
        }
        Key::Key9 => {
            model.sort_mode = Some(SortMode::Alpha);
        }
        Key::S => {
            app.main_window()
                .capture_frame(app.exe_name().unwrap() + ".png");
        }
        _otherkey => (),
    }
}

fn sort_colors(colors: &mut Vec<Rgba>, mode: &SortMode) {
    match mode {
        SortMode::Red => {
            colors.sort_by(|a, b| a.red.partial_cmp(&b.red).unwrap());
        }
        SortMode::Green => {
            colors.sort_by(|a, b| a.green.partial_cmp(&b.green).unwrap());
        }
        SortMode::Blue => {
            colors.sort_by(|a, b| a.blue.partial_cmp(&b.blue).unwrap());
        }
        SortMode::Hue => {
            colors.sort_by(|a, b| {
                let (a_hue, _, _) = rgb_to_hsl(a.red, a.green, a.blue);
                let (b_hue, _, _) = rgb_to_hsl(b.red, b.green, b.blue);
                a_hue.partial_cmp(&b_hue).unwrap()
            });
        }
        SortMode::Saturation => {
            colors.sort_by(|a, b| {
                let (_, a_sat, _) = rgb_to_hsl(a.red, a.green, a.blue);
                let (_, b_sat, _) = rgb_to_hsl(b.red, b.green, b.blue);

                // temporary fix until conrod bug with saturation is resolved
                if a_sat.is_nan() && b_sat.is_nan() {
                    0.0.partial_cmp(&0.0).unwrap()
                } else if a_sat.is_nan() {
                    0.0.partial_cmp(&b_sat).unwrap()
                } else if b_sat.is_nan() {
                    a_sat.partial_cmp(&0.0).unwrap()
                } else {
                    a_sat.partial_cmp(&b_sat).unwrap()
                }
            });
        }
        SortMode::Brightness => {
            colors.sort_by(|a, b| {
                let (_, _, a_bright) = rgb_to_hsl(a.red, a.green, a.blue);
                let (_, _, b_bright) = rgb_to_hsl(b.red, b.green, b.blue);
                a_bright.partial_cmp(&b_bright).unwrap()
            });
        }
        SortMode::Alpha => {
            colors.sort_by(|a, b| a.alpha.partial_cmp(&b.alpha).unwrap());
        }
        _ => (),
    }
}
<|endoftext|>


<commit_before>/*!

# GraphQL

[GraphQL][graphql] is a data query language developed by Facebook intended to
serve mobile and web application frontends.

*Juniper* makes it possible to write GraphQL servers in Rust that are
type-safe and blazingly fast. We also try to make declaring and resolving
GraphQL schemas as convenient as possible as Rust will allow.

Juniper does not include a web server - instead it provides building blocks to
make integration with existing servers straightforward. It optionally provides a
pre-built integration for the [Iron][iron] and [Rocket] frameworks, including
embedded [Graphiql][graphiql] for easy debugging.

* [Cargo crate](https://crates.io/crates/juniper)
* [API Reference][docsrs]
* [Book][book]: Guides and Examples

## Getting Started

The best place to get started is the [Juniper Book][book], which contains
guides with plenty of examples, covering all features of Juniper.

To get started quickly and get a feel for Juniper, check out the
[Quickstart][book_quickstart] section.

For specific information about macros, types and the Juniper api, the
[API Reference][docsrs] is the best place to look.

You can also check out [src/tests/schema.rs][test_schema_rs] to see a complex
schema including polymorphism with traits and interfaces.
For an example of web framework integration,
see the [rocket][rocket_examples] and [iron][iron_examples] examples folders.

## Features

Juniper supports the full GraphQL query language according to the
[specification][graphql_spec], including interfaces, unions, schema
introspection, and validations.
It does not, however, support the schema language.

As an exception to other GraphQL libraries for other languages, Juniper builds
non-null types by default. A field of type `Vec<Episode>` will be converted into
`[Episode!]!`. The corresponding Rust type for e.g. `[Episode]` would be
`Option<Vec<Option<Episode>>>`.

## Integrations

### Data types

Juniper has automatic integration with some very common Rust crates to make
building schemas a breeze. The types from these crates will be usable in
your Schemas automatically.

* [uuid][uuid]
* [url][url]
* [chrono][chrono]

### Web Frameworks

* [rocket][rocket]
* [iron][iron]

## API Stability

Juniper has not reached 1.0 yet, thus some API instability should be expected.

[graphql]: http://graphql.org
[graphiql]: https://github.com/graphql/graphiql
[iron]: http://ironframework.io
[graphql_spec]: http://facebook.github.io/graphql
[test_schema_rs]: https://github.com/graphql-rust/juniper/blob/master/juniper/src/tests/schema.rs
[tokio]: https://github.com/tokio-rs/tokio
[rocket_examples]: https://github.com/graphql-rust/juniper/tree/master/juniper_rocket/examples
[iron_examples]: https://github.com/graphql-rust/juniper/tree/master/juniper_iron/examples
[Rocket]: https://rocket.rs
[book]: https://graphql-rust.github.io/
[book_quickstart]: https://graphql-rust.github.io/quickstart.html
[docsrs]: https://docs.rs/juniper

[uuid]: https://crates.io/crates/uuid
[url]: https://crates.io/crates/url
[chrono]: https://crates.io/crates/chrono

*/
#![doc(html_root_url = "https://docs.rs/juniper/0.14.2")]
#![warn(missing_docs)]

#[doc(hidden)]
pub extern crate serde;

#[cfg(any(test, feature = "expose-test-schema"))]
extern crate serde_json;

#[cfg(any(test, feature = "chrono"))]
extern crate chrono;

#[cfg(any(test, feature = "url"))]
extern crate url;

#[cfg(any(test, feature = "uuid"))]
extern crate uuid;

// Depend on juniper_codegen and re-export everything in it.
// This allows users to just depend on juniper and get the derive
// functionality automatically.
pub use juniper_codegen::{
    graphql_object, graphql_union, GraphQLEnum, GraphQLInputObject, GraphQLObject,
    GraphQLScalarValue,
};
// Internal macros are not exported,
// but declared at the root to make them easier to use.
#[allow(unused_imports)]
use juniper_codegen::{
    graphql_object_internal, graphql_union_internal, GraphQLEnumInternal,
    GraphQLInputObjectInternal, GraphQLScalarValueInternal,
};

#[macro_use]
mod value;
#[macro_use]
mod macros;
mod ast;
mod executor;
mod introspection;
pub mod parser;
pub(crate) mod schema;
mod types;
mod util;
mod validation;
// This needs to be public until docs have support for private modules:
// https://github.com/rust-lang/cargo/issues/1520
pub mod http;
pub mod integrations;
// TODO: remove this alias export in 0.10. (breaking change)
pub use crate::http::graphiql;

#[cfg(all(test, not(feature = "expose-test-schema")))]
mod tests;
#[cfg(feature = "expose-test-schema")]
pub mod tests;

#[cfg(test)]
mod executor_tests;

// Needs to be public because macros use it.
pub use crate::util::to_camel_case;

use crate::{
    executor::{execute_validated_query, get_operation},
    introspection::{INTROSPECTION_QUERY, INTROSPECTION_QUERY_WITHOUT_DESCRIPTIONS},
    parser::{parse_document_source, ParseError, Spanning},
    validation::{validate_input_values, visit_all_rules, ValidatorContext},
};

pub use crate::{
    ast::{FromInputValue, InputValue, Selection, ToInputValue, Type},
    executor::{
        Applies, Context, ExecutionError, ExecutionResult, Executor, FieldError, FieldResult,
        FromContext, IntoFieldError, IntoResolvable, LookAheadArgument, LookAheadMethods,
        LookAheadSelection, LookAheadValue, Registry, Variables,
    },
    introspection::IntrospectionFormat,
    schema::{meta, model::RootNode},
    types::{
        base::{Arguments, GraphQLType, TypeKind},
        scalars::{EmptyMutation, ID},
    },
    validation::RuleError,
    value::{DefaultScalarValue, Object, ParseScalarResult, ParseScalarValue, ScalarValue, Value},
};

/// A pinned, boxed future that can be polled.
pub type BoxFuture<'a, T> = std::pin::Pin<Box<dyn std::future::Future<Output = T> + 'a + Send>>;

#[cfg(feature = "async")]
pub use crate::types::async_await::GraphQLTypeAsync;

/// An error that prevented query execution
#[derive(Debug, PartialEq)]
#[allow(missing_docs)]
pub enum GraphQLError<'a> {
    ParseError(Spanning<ParseError<'a>>),
    ValidationError(Vec<RuleError>),
    NoOperationProvided,
    MultipleOperationsProvided,
    UnknownOperationName,
    IsSubscription,
}

/// Execute a query in a provided schema
pub fn execute<'a, S, CtxT, QueryT, MutationT>(
    document_source: &'a str,
    operation_name: Option<&str>,
    root_node: &'a RootNode<QueryT, MutationT, S>,
    variables: &Variables<S>,
    context: &CtxT,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>
where
    S: ScalarValue,
    QueryT: GraphQLType<S, Context = CtxT>,
    MutationT: GraphQLType<S, Context = CtxT>,
{
    let document = parse_document_source(document_source, &root_node.schema)?;

    {
        let mut ctx = ValidatorContext::new(&root_node.schema, &document);
        visit_all_rules(&mut ctx, &document);

        let errors = ctx.into_errors();
        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    let operation = get_operation(&document, operation_name)?;

    {
        let errors = validate_input_values(variables, operation, &root_node.schema);

        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    execute_validated_query(&document, operation, root_node, variables, context)
}

/// Execute a query in a provided schema
#[cfg(feature = "async")]
pub async fn execute_async<'a, S, CtxT, QueryT, MutationT>(
    document_source: &'a str,
    operation_name: Option<&str>,
    root_node: &'a RootNode<'a, QueryT, MutationT, S>,
    variables: &Variables<S>,
    context: &CtxT,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>
where
    S: ScalarValue + Send + Sync,
    QueryT: GraphQLTypeAsync<S, Context = CtxT> + Send + Sync,
    QueryT::TypeInfo: Send + Sync,
    MutationT: GraphQLTypeAsync<S, Context = CtxT> + Send + Sync,
    MutationT::TypeInfo: Send + Sync,
    CtxT: Send + Sync,
{
    let document = parse_document_source(document_source, &root_node.schema)?;

    let operation = get_operation(&document, operation_name)?;

    {
        let errors = validate_input_values(variables, operation, &root_node.schema);

        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    executor::execute_validated_query_async(&document, operation, root_node, variables, context)
        .await
}

/// Execute the reference introspection query in the provided schema
pub fn introspect<'a, S, CtxT, QueryT, MutationT>(
    root_node: &'a RootNode<QueryT, MutationT, S>,
    context: &CtxT,
    format: IntrospectionFormat,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>
where
    S: ScalarValue,
    QueryT: GraphQLType<S, Context = CtxT>,
    MutationT: GraphQLType<S, Context = CtxT>,
{
    execute(
        match format {
            IntrospectionFormat::All => INTROSPECTION_QUERY,
            IntrospectionFormat::WithoutDescriptions => INTROSPECTION_QUERY_WITHOUT_DESCRIPTIONS,
        },
        None,
        root_node,
        &Variables::new(),
        context,
    )
}

impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
    fn from(f: Spanning<ParseError<'a>>) -> GraphQLError<'a> {
        GraphQLError::ParseError(f)
    }
}
<commit_msg>Added usage of context validator in the async executor<commit_after>/*!

# GraphQL

[GraphQL][graphql] is a data query language developed by Facebook intended to
serve mobile and web application frontends.

*Juniper* makes it possible to write GraphQL servers in Rust that are
type-safe and blazingly fast. We also try to make declaring and resolving
GraphQL schemas as convenient as possible as Rust will allow.

Juniper does not include a web server - instead it provides building blocks to
make integration with existing servers straightforward. It optionally provides a
pre-built integration for the [Iron][iron] and [Rocket] frameworks, including
embedded [Graphiql][graphiql] for easy debugging.

* [Cargo crate](https://crates.io/crates/juniper)
* [API Reference][docsrs]
* [Book][book]: Guides and Examples

## Getting Started

The best place to get started is the [Juniper Book][book], which contains
guides with plenty of examples, covering all features of Juniper.

To get started quickly and get a feel for Juniper, check out the
[Quickstart][book_quickstart] section.

For specific information about macros, types and the Juniper api, the
[API Reference][docsrs] is the best place to look.

You can also check out [src/tests/schema.rs][test_schema_rs] to see a complex
schema including polymorphism with traits and interfaces.
For an example of web framework integration,
see the [rocket][rocket_examples] and [iron][iron_examples] examples folders.

## Features

Juniper supports the full GraphQL query language according to the
[specification][graphql_spec], including interfaces, unions, schema
introspection, and validations.
It does not, however, support the schema language.

As an exception to other GraphQL libraries for other languages, Juniper builds
non-null types by default. A field of type `Vec<Episode>` will be converted into
`[Episode!]!`. The corresponding Rust type for e.g. `[Episode]` would be
`Option<Vec<Option<Episode>>>`.

## Integrations

### Data types

Juniper has automatic integration with some very common Rust crates to make
building schemas a breeze. The types from these crates will be usable in
your Schemas automatically.

* [uuid][uuid]
* [url][url]
* [chrono][chrono]

### Web Frameworks

* [rocket][rocket]
* [iron][iron]

## API Stability

Juniper has not reached 1.0 yet, thus some API instability should be expected.

[graphql]: http://graphql.org
[graphiql]: https://github.com/graphql/graphiql
[iron]: http://ironframework.io
[graphql_spec]: http://facebook.github.io/graphql
[test_schema_rs]: https://github.com/graphql-rust/juniper/blob/master/juniper/src/tests/schema.rs
[tokio]: https://github.com/tokio-rs/tokio
[rocket_examples]: https://github.com/graphql-rust/juniper/tree/master/juniper_rocket/examples
[iron_examples]: https://github.com/graphql-rust/juniper/tree/master/juniper_iron/examples
[Rocket]: https://rocket.rs
[book]: https://graphql-rust.github.io/
[book_quickstart]: https://graphql-rust.github.io/quickstart.html
[docsrs]: https://docs.rs/juniper

[uuid]: https://crates.io/crates/uuid
[url]: https://crates.io/crates/url
[chrono]: https://crates.io/crates/chrono

*/
#![doc(html_root_url = "https://docs.rs/juniper/0.14.2")]
#![warn(missing_docs)]

#[doc(hidden)]
pub extern crate serde;

#[cfg(any(test, feature = "expose-test-schema"))]
extern crate serde_json;

#[cfg(any(test, feature = "chrono"))]
extern crate chrono;

#[cfg(any(test, feature = "url"))]
extern crate url;

#[cfg(any(test, feature = "uuid"))]
extern crate uuid;

// Depend on juniper_codegen and re-export everything in it.
// This allows users to just depend on juniper and get the derive
// functionality automatically.
pub use juniper_codegen::{
    graphql_object, graphql_union, GraphQLEnum, GraphQLInputObject, GraphQLObject,
    GraphQLScalarValue,
};
// Internal macros are not exported,
// but declared at the root to make them easier to use.
#[allow(unused_imports)]
use juniper_codegen::{
    graphql_object_internal, graphql_union_internal, GraphQLEnumInternal,
    GraphQLInputObjectInternal, GraphQLScalarValueInternal,
};

#[macro_use]
mod value;
#[macro_use]
mod macros;
mod ast;
mod executor;
mod introspection;
pub mod parser;
pub(crate) mod schema;
mod types;
mod util;
mod validation;
// This needs to be public until docs have support for private modules:
// https://github.com/rust-lang/cargo/issues/1520
pub mod http;
pub mod integrations;
// TODO: remove this alias export in 0.10. (breaking change)
pub use crate::http::graphiql;

#[cfg(all(test, not(feature = "expose-test-schema")))]
mod tests;
#[cfg(feature = "expose-test-schema")]
pub mod tests;

#[cfg(test)]
mod executor_tests;

// Needs to be public because macros use it.
pub use crate::util::to_camel_case;

use crate::{
    executor::{execute_validated_query, get_operation},
    introspection::{INTROSPECTION_QUERY, INTROSPECTION_QUERY_WITHOUT_DESCRIPTIONS},
    parser::{parse_document_source, ParseError, Spanning},
    validation::{validate_input_values, visit_all_rules, ValidatorContext},
};

pub use crate::{
    ast::{FromInputValue, InputValue, Selection, ToInputValue, Type},
    executor::{
        Applies, Context, ExecutionError, ExecutionResult, Executor, FieldError, FieldResult,
        FromContext, IntoFieldError, IntoResolvable, LookAheadArgument, LookAheadMethods,
        LookAheadSelection, LookAheadValue, Registry, Variables,
    },
    introspection::IntrospectionFormat,
    schema::{meta, model::RootNode},
    types::{
        base::{Arguments, GraphQLType, TypeKind},
        scalars::{EmptyMutation, ID},
    },
    validation::RuleError,
    value::{DefaultScalarValue, Object, ParseScalarResult, ParseScalarValue, ScalarValue, Value},
};

/// A pinned, boxed future that can be polled.
pub type BoxFuture<'a, T> = std::pin::Pin<Box<dyn std::future::Future<Output = T> + 'a + Send>>;

#[cfg(feature = "async")]
pub use crate::types::async_await::GraphQLTypeAsync;

/// An error that prevented query execution
#[derive(Debug, PartialEq)]
#[allow(missing_docs)]
pub enum GraphQLError<'a> {
    ParseError(Spanning<ParseError<'a>>),
    ValidationError(Vec<RuleError>),
    NoOperationProvided,
    MultipleOperationsProvided,
    UnknownOperationName,
    IsSubscription,
}

/// Execute a query in a provided schema
pub fn execute<'a, S, CtxT, QueryT, MutationT>(
    document_source: &'a str,
    operation_name: Option<&str>,
    root_node: &'a RootNode<QueryT, MutationT, S>,
    variables: &Variables<S>,
    context: &CtxT,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>
where
    S: ScalarValue,
    QueryT: GraphQLType<S, Context = CtxT>,
    MutationT: GraphQLType<S, Context = CtxT>,
{
    let document = parse_document_source(document_source, &root_node.schema)?;

    {
        let mut ctx = ValidatorContext::new(&root_node.schema, &document);
        visit_all_rules(&mut ctx, &document);

        let errors = ctx.into_errors();
        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    let operation = get_operation(&document, operation_name)?;

    {
        let errors = validate_input_values(variables, operation, &root_node.schema);

        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    execute_validated_query(&document, operation, root_node, variables, context)
}

/// Execute a query in a provided schema
#[cfg(feature = "async")]
pub async fn execute_async<'a, S, CtxT, QueryT, MutationT>(
    document_source: &'a str,
    operation_name: Option<&str>,
    root_node: &'a RootNode<'a, QueryT, MutationT, S>,
    variables: &Variables<S>,
    context: &CtxT,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>
where
    S: ScalarValue + Send + Sync,
    QueryT: GraphQLTypeAsync<S, Context = CtxT> + Send + Sync,
    QueryT::TypeInfo: Send + Sync,
    MutationT: GraphQLTypeAsync<S, Context = CtxT> + Send + Sync,
    MutationT::TypeInfo: Send + Sync,
    CtxT: Send + Sync,
{
    let document = parse_document_source(document_source, &root_node.schema)?;

    {
        let mut ctx = ValidatorContext::new(&root_node.schema, &document);
        visit_all_rules(&mut ctx, &document);

        let errors = ctx.into_errors();
        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    let operation = get_operation(&document, operation_name)?;

    {
        let errors = validate_input_values(variables, operation, &root_node.schema);

        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    executor::execute_validated_query_async(&document, operation, root_node, variables, context)
        .await
}

/// Execute the reference introspection query in the provided schema
pub fn introspect<'a, S, CtxT, QueryT, MutationT>(
    root_node: &'a RootNode<QueryT, MutationT, S>,
    context: &CtxT,
    format: IntrospectionFormat,
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>
where
    S: ScalarValue,
    QueryT: GraphQLType<S, Context = CtxT>,
    MutationT: GraphQLType<S, Context = CtxT>,
{
    execute(
        match format {
            IntrospectionFormat::All => INTROSPECTION_QUERY,
            IntrospectionFormat::WithoutDescriptions => INTROSPECTION_QUERY_WITHOUT_DESCRIPTIONS,
        },
        None,
        root_node,
        &Variables::new(),
        context,
    )
}

impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
    fn from(f: Spanning<ParseError<'a>>) -> GraphQLError<'a> {
        GraphQLError::ParseError(f)
    }
}
<|endoftext|>


<commit_before>//! The "main crate" of the Rust compiler. This crate contains common
//! type definitions that are used by the other crates in the rustc
//! "family". Some prominent examples (note that each of these modules
//! has their own README with further details).
//!
//! - **HIR.** The "high-level (H) intermediate representation (IR)" is
//!   defined in the `hir` module.
//! - **MIR.** The "mid-level (M) intermediate representation (IR)" is
//!   defined in the `mir` module. This module contains only the
//!   *definition* of the MIR; the passes that transform and operate
//!   on MIR are found in `librustc_mir` crate.
//! - **Types.** The internal representation of types used in rustc is
//!   defined in the `ty` module. This includes the **type context**
//!   (or `tcx`), which is the central context during most of
//!   compilation, containing the interners and other things.
//!
//! For more information about how rustc works, see the [rustc dev guide].
//!
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/
//!
//! # Note
//!
//! This API is completely unstable and subject to change.

#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(array_windows)]
#![feature(assoc_char_funcs)]
#![feature(backtrace)]
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cmp_min_max_by)]
#![feature(const_fn)]
#![feature(const_panic)]
#![feature(core_intrinsics)]
#![feature(discriminant_kind)]
#![feature(never_type)]
#![feature(extern_types)]
#![feature(nll)]
#![feature(once_cell)]
#![feature(option_expect_none)]
#![feature(or_patterns)]
#![feature(min_specialization)]
#![feature(trusted_len)]
#![feature(test)]
#![feature(in_band_lifetimes)]
#![feature(crate_visibility_modifier)]
#![feature(associated_type_bounds)]
#![feature(rustc_attrs)]
#![feature(int_error_matching)]
#![feature(half_open_range_patterns)]
#![feature(exclusive_range_pattern)]
#![feature(control_flow_enum)]
#![feature(associated_type_defaults)]
#![recursion_limit = "512"]

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate rustc_macros;
#[macro_use]
extern crate rustc_data_structures;
#[macro_use]
extern crate tracing;
#[macro_use]
extern crate smallvec;

#[cfg(test)]
mod tests;

#[macro_use]
mod macros;

#[macro_use]
pub mod query;

#[macro_use]
pub mod arena;
pub mod dep_graph;
pub mod hir;
pub mod ich;
pub mod infer;
pub mod lint;
pub mod middle;
pub mod mir;
pub mod traits;
pub mod ty;

pub mod util {
    pub mod bug;
    pub mod common;
}

// Allows macros to refer to this crate as `::rustc_middle`
extern crate self as rustc_middle;
<commit_msg>Rollup merge of #80223 - pierwill:patch-10, r=lcnr<commit_after>//! The "main crate" of the Rust compiler. This crate contains common
//! type definitions that are used by the other crates in the rustc
//! "family". Some prominent examples (note that each of these modules
//! has their own README with further details).
//!
//! - **HIR.** The "high-level (H) intermediate representation (IR)" is
//!   defined in the `hir` module.
//! - **MIR.** The "mid-level (M) intermediate representation (IR)" is
//!   defined in the `mir` module. This module contains only the
//!   *definition* of the MIR; the passes that transform and operate
//!   on MIR are found in `rustc_mir` crate.
//! - **Types.** The internal representation of types used in rustc is
//!   defined in the `ty` module. This includes the **type context**
//!   (or `tcx`), which is the central context during most of
//!   compilation, containing the interners and other things.
//!
//! For more information about how rustc works, see the [rustc dev guide].
//!
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/
//!
//! # Note
//!
//! This API is completely unstable and subject to change.

#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(array_windows)]
#![feature(assoc_char_funcs)]
#![feature(backtrace)]
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cmp_min_max_by)]
#![feature(const_fn)]
#![feature(const_panic)]
#![feature(core_intrinsics)]
#![feature(discriminant_kind)]
#![feature(never_type)]
#![feature(extern_types)]
#![feature(nll)]
#![feature(once_cell)]
#![feature(option_expect_none)]
#![feature(or_patterns)]
#![feature(min_specialization)]
#![feature(trusted_len)]
#![feature(test)]
#![feature(in_band_lifetimes)]
#![feature(crate_visibility_modifier)]
#![feature(associated_type_bounds)]
#![feature(rustc_attrs)]
#![feature(int_error_matching)]
#![feature(half_open_range_patterns)]
#![feature(exclusive_range_pattern)]
#![feature(control_flow_enum)]
#![feature(associated_type_defaults)]
#![recursion_limit = "512"]

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate rustc_macros;
#[macro_use]
extern crate rustc_data_structures;
#[macro_use]
extern crate tracing;
#[macro_use]
extern crate smallvec;

#[cfg(test)]
mod tests;

#[macro_use]
mod macros;

#[macro_use]
pub mod query;

#[macro_use]
pub mod arena;
pub mod dep_graph;
pub mod hir;
pub mod ich;
pub mod infer;
pub mod lint;
pub mod middle;
pub mod mir;
pub mod traits;
pub mod ty;

pub mod util {
    pub mod bug;
    pub mod common;
}

// Allows macros to refer to this crate as `::rustc_middle`
extern crate self as rustc_middle;
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Unix-specific extensions to general I/O primitives

#![stable(feature = "rust1", since = "1.0.0")]

use fs;
use net;
use os::raw;
use sys;
use sys_common::{self, AsInner, FromInner, IntoInner};

/// Raw file descriptors.
#[stable(feature = "rust1", since = "1.0.0")]
pub type RawFd = raw::c_int;

/// A trait to extract the raw unix file descriptor from an underlying
/// object.
///
/// This is only available on unix platforms and must be imported in order
/// to call the method. Windows platforms have a corresponding `AsRawHandle`
/// and `AsRawSocket` set of traits.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawFd {
    /// Extracts the raw file descriptor.
    ///
    /// This method does **not** pass ownership of the raw file descriptor
    /// to the caller. The descriptor is only guarantee to be valid while
    /// the original object has not yet been destroyed.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn as_raw_fd(&self) -> RawFd;
}

/// A trait to express the ability to construct an object from a raw file
/// descriptor.
#[stable(feature = "from_raw_os", since = "1.1.0")]
pub trait FromRawFd {
    /// Constructs a new instances of `Self` from the given raw file
    /// descriptor.
    ///
    /// This function **consumes ownership** of the specified file
    /// descriptor. The returned object will take responsibility for closing
    /// it when the object goes out of scope.
    ///
    /// This function is also unsafe as the primitives currently returned
    /// have the contract that they are the sole owner of the file
    /// descriptor they are wrapping. Usage of this function could
    /// accidentally allow violating this contract which can cause memory
    /// unsafety in code that relies on it being true.
    #[stable(feature = "from_raw_os", since = "1.1.0")]
    unsafe fn from_raw_fd(fd: RawFd) -> Self;
}

/// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor.
#[stable(feature = "into_raw_os", since = "1.4.0")]
pub trait IntoRawFd {
    /// Consumes this object, returning the raw underlying file descriptor.
    ///
    /// This function **transfers ownership** of the underlying file descriptor
    /// to the caller. Callers are then the unique owners of the file descriptor
    /// and must close the descriptor once it's no longer needed.
    #[stable(feature = "into_raw_os", since = "1.4.0")]
    fn into_raw_fd(self) -> RawFd;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for fs::File {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().raw()
    }
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for fs::File {
    unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
        fs::File::from_inner(sys::fs::File::from_inner(fd))
    }
}
#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for fs::File {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::TcpStream {
    fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::TcpListener {
    fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::UdpSocket {
    fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
}

#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for net::TcpStream {
    unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
        let socket = sys::net::Socket::from_inner(fd);
        net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(socket))
    }
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for net::TcpListener {
    unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
        let socket = sys::net::Socket::from_inner(fd);
        net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(socket))
    }
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for net::UdpSocket {
    unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
        let socket = sys::net::Socket::from_inner(fd);
        net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(socket))
    }
}

#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for net::TcpStream {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_socket().into_inner()
    }
}
#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for net::TcpListener {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_socket().into_inner()
    }
}
#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for net::UdpSocket {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_socket().into_inner()
    }
}
<commit_msg>doc: fix typo<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Unix-specific extensions to general I/O primitives

#![stable(feature = "rust1", since = "1.0.0")]

use fs;
use net;
use os::raw;
use sys;
use sys_common::{self, AsInner, FromInner, IntoInner};

/// Raw file descriptors.
#[stable(feature = "rust1", since = "1.0.0")]
pub type RawFd = raw::c_int;

/// A trait to extract the raw unix file descriptor from an underlying
/// object.
///
/// This is only available on unix platforms and must be imported in order
/// to call the method. Windows platforms have a corresponding `AsRawHandle`
/// and `AsRawSocket` set of traits.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawFd {
    /// Extracts the raw file descriptor.
    ///
    /// This method does **not** pass ownership of the raw file descriptor
    /// to the caller. The descriptor is only guaranteed to be valid while
    /// the original object has not yet been destroyed.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn as_raw_fd(&self) -> RawFd;
}

/// A trait to express the ability to construct an object from a raw file
/// descriptor.
#[stable(feature = "from_raw_os", since = "1.1.0")]
pub trait FromRawFd {
    /// Constructs a new instances of `Self` from the given raw file
    /// descriptor.
    ///
    /// This function **consumes ownership** of the specified file
    /// descriptor. The returned object will take responsibility for closing
    /// it when the object goes out of scope.
    ///
    /// This function is also unsafe as the primitives currently returned
    /// have the contract that they are the sole owner of the file
    /// descriptor they are wrapping. Usage of this function could
    /// accidentally allow violating this contract which can cause memory
    /// unsafety in code that relies on it being true.
    #[stable(feature = "from_raw_os", since = "1.1.0")]
    unsafe fn from_raw_fd(fd: RawFd) -> Self;
}

/// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor.
#[stable(feature = "into_raw_os", since = "1.4.0")]
pub trait IntoRawFd {
    /// Consumes this object, returning the raw underlying file descriptor.
    ///
    /// This function **transfers ownership** of the underlying file descriptor
    /// to the caller. Callers are then the unique owners of the file descriptor
    /// and must close the descriptor once it's no longer needed.
    #[stable(feature = "into_raw_os", since = "1.4.0")]
    fn into_raw_fd(self) -> RawFd;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for fs::File {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().raw()
    }
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for fs::File {
    unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
        fs::File::from_inner(sys::fs::File::from_inner(fd))
    }
}
#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for fs::File {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::TcpStream {
    fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::TcpListener {
    fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::UdpSocket {
    fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
}

#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for net::TcpStream {
    unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
        let socket = sys::net::Socket::from_inner(fd);
        net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(socket))
    }
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for net::TcpListener {
    unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
        let socket = sys::net::Socket::from_inner(fd);
        net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(socket))
    }
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for net::UdpSocket {
    unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
        let socket = sys::net::Socket::from_inner(fd);
        net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(socket))
    }
}

#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for net::TcpStream {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_socket().into_inner()
    }
}
#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for net::TcpListener {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_socket().into_inner()
    }
}
#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for net::UdpSocket {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_socket().into_inner()
    }
}
<|endoftext|>


<commit_before>#![feature(conservative_impl_trait)]
#![feature(try_from)]

extern crate futures;
extern crate hyper;
extern crate ruma_client;
extern crate ruma_events;
extern crate ruma_identifiers;
extern crate tokio_core;
extern crate url;

use std::convert::TryFrom;

use futures::Future;
use ruma_client::Client;
use ruma_client::api::r0;
use ruma_events::EventType;
use ruma_events::room::message::{MessageEventContent, MessageType, TextMessageEventContent};
use ruma_identifiers::RoomAliasId;
use tokio_core::reactor::{Core as TokioCore, Handle as TokioHandle};
use url::Url;

// from https://stackoverflow.com/a/43992218/1592377
#[macro_export]
macro_rules! clone {
    (@param _) => ( _ );
    (@param $x:ident) => ( $x );
    ($($n:ident),+ => move || $body:expr) => (
        {
            $( let $n = $n.clone(); )+
            move || $body
        }
    );
    ($($n:ident),+ => move |$($p:tt),+| $body:expr) => (
        {
            $( let $n = $n.clone(); )+
            move |$(clone!(@param $p),)+| $body
        }
    );
}

fn hello_world(
    tokio_handle: TokioHandle,
    homeserver_url: Url,
) -> impl Future<Item = (), Error = ruma_client::Error> + 'static {
    let client = Client::https(&tokio_handle, homeserver_url, None).unwrap();

    client.register_guest().and_then(clone!(client => move |_| {
        r0::alias::get_alias::call(client, r0::alias::get_alias::Request {
            room_alias: RoomAliasId::try_from("#ruma-client-test:matrix.org").unwrap(),
        })
    })).and_then(clone!(client => move |response| {
        let room_id = response.room_id;

        r0::membership::join_room_by_id::call(client.clone(), r0::membership::join_room_by_id::Request {
            room_id: room_id.clone(),
            third_party_signed: None,
        }).and_then(move |_| {
            r0::send::send_message_event::call(client, r0::send::send_message_event::Request {
                room_id: room_id,
                event_type: EventType::RoomMessage,
                txn_id: "1".to_owned(),
                data: MessageEventContent::Text(TextMessageEventContent {
                    body: "Hello World!".to_owned(),
                    msgtype: MessageType::Text,
                }),
            })
        })
    })).map(|_| ())
}

fn main() {
    let mut core = TokioCore::new().unwrap();
    let handle = core.handle();
    let server = Url::parse("https://matrix.org/").unwrap();

    core.run(hello_world(handle, server)).unwrap();
}
<commit_msg>Apply small change suggested by clippy<commit_after>#![feature(conservative_impl_trait)]
#![feature(try_from)]

extern crate futures;
extern crate hyper;
extern crate ruma_client;
extern crate ruma_events;
extern crate ruma_identifiers;
extern crate tokio_core;
extern crate url;

use std::convert::TryFrom;

use futures::Future;
use ruma_client::Client;
use ruma_client::api::r0;
use ruma_events::EventType;
use ruma_events::room::message::{MessageEventContent, MessageType, TextMessageEventContent};
use ruma_identifiers::RoomAliasId;
use tokio_core::reactor::{Core as TokioCore, Handle as TokioHandle};
use url::Url;

// from https://stackoverflow.com/a/43992218/1592377
#[macro_export]
macro_rules! clone {
    (@param _) => ( _ );
    (@param $x:ident) => ( $x );
    ($($n:ident),+ => move || $body:expr) => (
        {
            $( let $n = $n.clone(); )+
            move || $body
        }
    );
    ($($n:ident),+ => move |$($p:tt),+| $body:expr) => (
        {
            $( let $n = $n.clone(); )+
            move |$(clone!(@param $p),)+| $body
        }
    );
}

fn hello_world(
    tokio_handle: &TokioHandle,
    homeserver_url: Url,
) -> impl Future<Item = (), Error = ruma_client::Error> + 'static {
    let client = Client::https(tokio_handle, homeserver_url, None).unwrap();

    client.register_guest().and_then(clone!(client => move |_| {
        r0::alias::get_alias::call(client, r0::alias::get_alias::Request {
            room_alias: RoomAliasId::try_from("#ruma-client-test:matrix.org").unwrap(),
        })
    })).and_then(clone!(client => move |response| {
        let room_id = response.room_id;

        r0::membership::join_room_by_id::call(client.clone(), r0::membership::join_room_by_id::Request {
            room_id: room_id.clone(),
            third_party_signed: None,
        }).and_then(move |_| {
            r0::send::send_message_event::call(client, r0::send::send_message_event::Request {
                room_id: room_id,
                event_type: EventType::RoomMessage,
                txn_id: "1".to_owned(),
                data: MessageEventContent::Text(TextMessageEventContent {
                    body: "Hello World!".to_owned(),
                    msgtype: MessageType::Text,
                }),
            })
        })
    })).map(|_| ())
}

fn main() {
    let mut core = TokioCore::new().unwrap();
    let handle = core.handle();
    let server = Url::parse("https://matrix.org/").unwrap();

    core.run(hello_world(&handle, server)).unwrap();
}
<|endoftext|>


<commit_before>use image::ImageResult;
use mli::{Backward, Forward, Graph, Train};
use mli_conv::{Conv2, Conv2n, Conv3};
use mli_ndarray::{Map2One, Map3One, Reshape3to2};
use mli_relu::Blu;
use ndarray::{array, s, Array, Array2, OwnedRepr};
use ndarray_image::{open_gray_image, save_gray_image};
use rand_core::{RngCore, SeedableRng};
use rand_distr::{Distribution, Normal};
use rand_pcg::Pcg64;
use std::path::{Path, PathBuf};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(name = "image", about = "Loads and convolves an image as a test")]
struct Opt {
    /// Number of epochs
    #[structopt(short = "t", default_value = "4000")]
    epochs: usize,
    /// Number of epochs per output image
    #[structopt(short = "s", default_value = "1")]
    show_every: usize,
    /// Pre-start learning rate (for first 10 epochs)
    #[structopt(short = "p", default_value = "0.1")]
    prestart_learning_rate: f32,
    /// Initial learning rate
    #[structopt(short = "i", default_value = "1.0")]
    initial_learning_rate: f32,
    /// Learning rate multiplier per epoch
    #[structopt(short = "m", default_value = "0.999")]
    learning_rate_multiplier: f32,
    /// Seed
    #[structopt(short = "z", default_value = "32")]
    seed: u32,
    /// Beta value for NAG
    #[structopt(short = "b", default_value = "0.9")]
    beta: f32,
    /// File to load
    #[structopt(parse(from_os_str))]
    file: PathBuf,
    /// Output directory
    #[structopt(parse(from_os_str))]
    output_dir: PathBuf,
}

fn sobel(image: &Array2<f32>) -> Array2<f32> {
    let down_filter = array![[-1.0, -2.0, -1.0], [0.0, 0.0, 0.0], [1.0, 2.0, 1.0],];
    let right_filter = down_filter.t().to_owned();
    let down = Conv2::new(down_filter).forward(&image).1;
    let right = Conv2::new(right_filter).forward(&image).1;
    (down.map(|f| f.powi(2)) + right.map(|f| f.powi(2))).map(|f| f.sqrt())
}

fn open_image(path: impl AsRef<Path>) -> ImageResult<Array2<f32>> {
    let image = open_gray_image(path)?;
    Ok(image.map(|&n| f32::from(n) / 255.0))
}

fn save_image(path: impl AsRef<Path>, image: &Array2<f32>) -> ImageResult<()> {
    let image = image.map(|&n| num::clamp(n * 255.0, 0.0, 255.0) as u8);
    save_gray_image(path, image.view())
}

fn main() -> ImageResult<()> {
    let opt = Opt::from_args();
    let image = open_image(opt.file)?;
    let sobel_image = sobel(&image);
    let conv_layers = 4;
    let filter_radius = 1usize;
    let filter_depth = 2usize;
    let filter_area = (filter_radius * 2 + 1).pow(2);
    let filter_volume = filter_area * filter_depth;
    let padding = (conv_layers * filter_radius - 1) as i32;
    #[allow(clippy::deref_addrof)]
    let expected = sobel_image.slice(s![padding..-padding, padding..-padding]);
    save_image(opt.output_dir.join("actual.png"), &expected.to_owned())?;
    let mut prng = make_prng(opt.seed);
    let mut prng_2filter = make_prng(prng.next_u32());
    let mut random_2filter = |mean: f32, variance: f32| -> Conv2<OwnedRepr<f32>> {
        // Xavier initialize by changing the variance to be 1/N where N is the area of the filter.
        Conv2::new(
            Array::from_iter(
                Normal::new(mean / filter_area as f32, variance / filter_area as f32)
                    .unwrap()
                    .sample_iter(&mut prng_2filter)
                    .take(filter_area),
            )
            .into_shape((filter_radius * 2 + 1, filter_radius * 2 + 1))
            .unwrap(),
        )
    };
    let mut prng_2nfilter = make_prng(prng.next_u32());
    let mut random_2nfilter = |mean: f32, variance: f32| -> Conv2n<OwnedRepr<f32>> {
        // Xavier initialize by changing the variance to be 1/N where N is the area of the filter.
        Conv2n::new(
            Array::from_iter(
                Normal::new(mean / filter_area as f32, variance / filter_area as f32)
                    .unwrap()
                    .sample_iter(&mut prng_2nfilter)
                    .take(filter_volume),
            )
            .into_shape((filter_depth, filter_radius * 2 + 1, filter_radius * 2 + 1))
            .unwrap(),
        )
    };
    let mut prng_3filter = make_prng(prng.next_u32());
    let mut random_3filter = |mean: f32, variance: f32| -> Conv3<OwnedRepr<f32>> {
        // Xavier initialize by changing the variance to be 1/N where N is the volume of the filter.
        Conv3::new(
            Array::from_iter(
                Normal::new(mean / filter_volume as f32, variance / filter_volume as f32)
                    .unwrap()
                    .sample_iter(&mut prng_3filter)
                    .take(filter_volume),
            )
            .into_shape((filter_depth, filter_radius * 2 + 1, filter_radius * 2 + 1))
            .unwrap(),
        )
    };
    let mut random_blu = |mean: f32, variance: f32| -> Blu {
        // Xavier initialize by changing the variance to be 1/N where N is the number of neurons.
        let distr = Normal::new(mean, variance).unwrap();
        Blu::new(distr.sample(&mut prng), distr.sample(&mut prng))
    };
    let mut generate_filter = || {
        random_2nfilter(0.0, 4.0)
            .chain(Map3One(random_blu(0.0, 0.5)))
            .chain(random_3filter(0.0, 4.0))
            .chain(Reshape3to2::new())
            .chain(Map2One(random_blu(0.0, 0.5)))
            .chain(random_2filter(0.0, 4.0))
            .chain(Map2One(random_blu(0.0, 0.5)))
            .chain(random_2filter(0.0, 4.0))
    };

    loop {
        let mut train_filter = generate_filter();
        let mut learn_rate = opt.initial_learning_rate;
        // Weird hack to initialize the momentum to zero without knowing the shape of the ndarray in advance.
        let mut momentum = {
            let (internal, output) = train_filter.forward(&image);
            train_filter.backward_train(&image, &internal, &output)
        };
        let mut last_loss = 0.0;
        momentum *= 0.0f32;
        for i in 0..opt.epochs {
            // Compute beta * momentum.
            momentum *= opt.beta;
            train_filter.train(&momentum);
            let (internal, output) = train_filter.forward(&image);
            // Show the image if the frame is divisible by show_every.
            if i % opt.show_every == 0 {
                save_image(opt.output_dir.join(format!("epoch{:04}.png", i)), &output)?;
            }
            if i == opt.epochs - 1 {
                eprintln!("Finished!");
                return Ok(());
            }
            let output_len = output.len() as f32;
            let local_learn_rate = if i < 10 {
                opt.prestart_learning_rate
            } else {
                let llr = learn_rate;
                learn_rate *= opt.learning_rate_multiplier;
                llr
            };
            // Compute the loss for display only (we don't actually need the loss itself for backprop, just its derivative).
            let loss = (output.clone() - expected.view()).map(|n| n.powi(2)).sum() / output_len;
            eprintln!(
                "epoch {:04} loss: {} ({:+}%), learn_rate: {}",
                i,
                loss,
                (loss - last_loss) / last_loss * 100.0,
                local_learn_rate
            );
            last_loss = loss;
            if !loss.is_normal() {
                eprintln!("abnormal loss at epoch {}; starting over", i);
                break;
            }
            // The loss function is (n - t)^2, so 2*(n - t) is dE/df where
            // `E` is loss and `f` is output.
            let delta_loss = (output - expected).map(|n| 2.0 * n / output_len);
            // Compute the output delta.
            let output_delta = -local_learn_rate * delta_loss;
            // Compute the trainable variable delta.
            let mut train_delta = train_filter.backward_train(&image, &internal, &output_delta);
            // Make the train delta a small component.
            train_delta *= 1.0 - opt.beta;
            train_filter.train(&train_delta);
            // Add the small component to the momentum.
            momentum += train_delta;
        }
    }
}

fn make_prng(seed: u32) -> Pcg64 {
    Pcg64::from_seed([
        (seed & 0xFF) as u8,
        ((seed >> 8) & 0xFF) as u8,
        ((seed >> 16) & 0xFF) as u8,
        ((seed >> 24) & 0xFF) as u8,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
    ])
}
<commit_msg>actually, no, it cant<commit_after>use image::ImageResult;
use mli::{Backward, Forward, Graph, Train};
use mli_conv::{Conv2, Conv2n, Conv3};
use mli_ndarray::{Map2One, Map3One, Reshape3to2};
use mli_relu::Blu;
use ndarray::{array, s, Array, Array2, OwnedRepr};
use ndarray_image::{open_gray_image, save_gray_image};
use rand_core::{RngCore, SeedableRng};
use rand_distr::{Distribution, Normal};
use rand_pcg::Pcg64;
use std::path::{Path, PathBuf};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(name = "image", about = "Loads and convolves an image as a test")]
struct Opt {
    /// Number of epochs
    #[structopt(short = "t", default_value = "4000")]
    epochs: usize,
    /// Number of epochs per output image
    #[structopt(short = "s", default_value = "1")]
    show_every: usize,
    /// Pre-start learning rate (for first 10 epochs)
    #[structopt(short = "p", default_value = "0.1")]
    prestart_learning_rate: f32,
    /// Initial learning rate
    #[structopt(short = "i", default_value = "0.5")]
    initial_learning_rate: f32,
    /// Learning rate multiplier per epoch
    #[structopt(short = "m", default_value = "0.999")]
    learning_rate_multiplier: f32,
    /// Seed
    #[structopt(short = "z", default_value = "32")]
    seed: u32,
    /// Beta value for NAG
    #[structopt(short = "b", default_value = "0.9")]
    beta: f32,
    /// File to load
    #[structopt(parse(from_os_str))]
    file: PathBuf,
    /// Output directory
    #[structopt(parse(from_os_str))]
    output_dir: PathBuf,
}

fn sobel(image: &Array2<f32>) -> Array2<f32> {
    let down_filter = array![[-1.0, -2.0, -1.0], [0.0, 0.0, 0.0], [1.0, 2.0, 1.0],];
    let right_filter = down_filter.t().to_owned();
    let down = Conv2::new(down_filter).forward(&image).1;
    let right = Conv2::new(right_filter).forward(&image).1;
    (down.map(|f| f.powi(2)) + right.map(|f| f.powi(2))).map(|f| f.sqrt())
}

fn open_image(path: impl AsRef<Path>) -> ImageResult<Array2<f32>> {
    let image = open_gray_image(path)?;
    Ok(image.map(|&n| f32::from(n) / 255.0))
}

fn save_image(path: impl AsRef<Path>, image: &Array2<f32>) -> ImageResult<()> {
    let image = image.map(|&n| num::clamp(n * 255.0, 0.0, 255.0) as u8);
    save_gray_image(path, image.view())
}

fn main() -> ImageResult<()> {
    let opt = Opt::from_args();
    let image = open_image(opt.file)?;
    let sobel_image = sobel(&image);
    let conv_layers = 4;
    let filter_radius = 1usize;
    let filter_depth = 2usize;
    let filter_area = (filter_radius * 2 + 1).pow(2);
    let filter_volume = filter_area * filter_depth;
    let padding = (conv_layers * filter_radius - 1) as i32;
    #[allow(clippy::deref_addrof)]
    let expected = sobel_image.slice(s![padding..-padding, padding..-padding]);
    save_image(opt.output_dir.join("actual.png"), &expected.to_owned())?;
    let mut prng = make_prng(opt.seed);
    let mut prng_2filter = make_prng(prng.next_u32());
    let mut random_2filter = |mean: f32, variance: f32| -> Conv2<OwnedRepr<f32>> {
        // Xavier initialize by changing the variance to be 1/N where N is the area of the filter.
        Conv2::new(
            Array::from_iter(
                Normal::new(mean / filter_area as f32, variance / filter_area as f32)
                    .unwrap()
                    .sample_iter(&mut prng_2filter)
                    .take(filter_area),
            )
            .into_shape((filter_radius * 2 + 1, filter_radius * 2 + 1))
            .unwrap(),
        )
    };
    let mut prng_2nfilter = make_prng(prng.next_u32());
    let mut random_2nfilter = |mean: f32, variance: f32| -> Conv2n<OwnedRepr<f32>> {
        // Xavier initialize by changing the variance to be 1/N where N is the area of the filter.
        Conv2n::new(
            Array::from_iter(
                Normal::new(mean / filter_area as f32, variance / filter_area as f32)
                    .unwrap()
                    .sample_iter(&mut prng_2nfilter)
                    .take(filter_volume),
            )
            .into_shape((filter_depth, filter_radius * 2 + 1, filter_radius * 2 + 1))
            .unwrap(),
        )
    };
    let mut prng_3filter = make_prng(prng.next_u32());
    let mut random_3filter = |mean: f32, variance: f32| -> Conv3<OwnedRepr<f32>> {
        // Xavier initialize by changing the variance to be 1/N where N is the volume of the filter.
        Conv3::new(
            Array::from_iter(
                Normal::new(mean / filter_volume as f32, variance / filter_volume as f32)
                    .unwrap()
                    .sample_iter(&mut prng_3filter)
                    .take(filter_volume),
            )
            .into_shape((filter_depth, filter_radius * 2 + 1, filter_radius * 2 + 1))
            .unwrap(),
        )
    };
    let mut random_blu = |mean: f32, variance: f32| -> Blu {
        // Xavier initialize by changing the variance to be 1/N where N is the number of neurons.
        let distr = Normal::new(mean, variance).unwrap();
        Blu::new(distr.sample(&mut prng), distr.sample(&mut prng))
    };
    let mut generate_filter = || {
        random_2nfilter(0.0, 4.0)
            .chain(Map3One(random_blu(0.0, 0.5)))
            .chain(random_3filter(0.0, 4.0))
            .chain(Reshape3to2::new())
            .chain(Map2One(random_blu(0.0, 0.5)))
            .chain(random_2filter(0.0, 4.0))
            .chain(Map2One(random_blu(0.0, 0.5)))
            .chain(random_2filter(0.0, 4.0))
    };

    loop {
        let mut train_filter = generate_filter();
        let mut learn_rate = opt.initial_learning_rate;
        // Weird hack to initialize the momentum to zero without knowing the shape of the ndarray in advance.
        let mut momentum = {
            let (internal, output) = train_filter.forward(&image);
            train_filter.backward_train(&image, &internal, &output)
        };
        let mut last_loss = 0.0;
        momentum *= 0.0f32;
        for i in 0..opt.epochs {
            // Compute beta * momentum.
            momentum *= opt.beta;
            train_filter.train(&momentum);
            let (internal, output) = train_filter.forward(&image);
            // Show the image if the frame is divisible by show_every.
            if i % opt.show_every == 0 {
                save_image(opt.output_dir.join(format!("epoch{:04}.png", i)), &output)?;
            }
            if i == opt.epochs - 1 {
                eprintln!("Finished!");
                return Ok(());
            }
            let output_len = output.len() as f32;
            let local_learn_rate = if i < 10 {
                opt.prestart_learning_rate
            } else {
                let llr = learn_rate;
                learn_rate *= opt.learning_rate_multiplier;
                llr
            };
            // Compute the loss for display only (we don't actually need the loss itself for backprop, just its derivative).
            let loss = (output.clone() - expected.view()).map(|n| n.powi(2)).sum() / output_len;
            eprintln!(
                "epoch {:04} loss: {} ({:+}%), learn_rate: {}",
                i,
                loss,
                (loss - last_loss) / last_loss * 100.0,
                local_learn_rate
            );
            last_loss = loss;
            if !loss.is_normal() {
                eprintln!("abnormal loss at epoch {}; starting over", i);
                break;
            }
            // The loss function is (n - t)^2, so 2*(n - t) is dE/df where
            // `E` is loss and `f` is output.
            let delta_loss = (output - expected).map(|n| 2.0 * n / output_len);
            // Compute the output delta.
            let output_delta = -local_learn_rate * delta_loss;
            // Compute the trainable variable delta.
            let mut train_delta = train_filter.backward_train(&image, &internal, &output_delta);
            // Make the train delta a small component.
            train_delta *= 1.0 - opt.beta;
            train_filter.train(&train_delta);
            // Add the small component to the momentum.
            momentum += train_delta;
        }
    }
}

fn make_prng(seed: u32) -> Pcg64 {
    Pcg64::from_seed([
        (seed & 0xFF) as u8,
        ((seed >> 8) & 0xFF) as u8,
        ((seed >> 16) & 0xFF) as u8,
        ((seed >> 24) & 0xFF) as u8,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
    ])
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::path::Path;
use std::env;
use std::borrow::Cow;

pub mod snowball;

use snowball::SnowballEnv;

fn usage(name: &str) {
    println!("{} -l <language> [-i <input file>] [-o <output file>]
The input file consists of a list of words to be stemmed, one per
line. Words should be in lower case, but (for English) A-Z letters
are mapped to their a-z equivalents anyway. If omitted, stdin is
used.", name);
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 3 {
        usage(&args[0]);
    } else {
        let mut language = None;
        let mut input_arg = None;
        let mut output_arg = None;
        let mut i = 1;
        while i < args.len() {
            match args[i].as_str() {
                "-l" => {
                    language = Some(args[i+1].clone());
                    i += 2;
                },
                "-i" => {
                    input_arg = Some(args[i+1].clone());
                    i += 2;
                },
                "-o" => {
                    output_arg = Some(args[i+1].clone());
                    i += 2;
                },
                x => {
                    println!("Unrecognized option '{}'", x);
                    usage(&args[0]);
                    return
                }
            }
        }
        if language.is_none() {
            println!("Please specify a language!");
            usage(&args[0]);
            return;
        }
        let stemmer = Stemmer::create(language.unwrap());

        let mut output = if let Some(output_file) = output_arg {
            Box::new(File::create(Path::new(&output_file)).unwrap()) as Box<Write>
        } else {
            Box::new(std::io::stdout()) as Box<Write>
        };

        if let Some(input_file) = input_arg {
            for line in BufReader::new(File::open(Path::new(&input_file)).unwrap()).lines() {
                writeln!(&mut output, "{}", stemmer.stem(&line.unwrap())).unwrap();
            }
        } else {
            let stdin = std::io::stdin();
            for line in stdin.lock().lines() {
                writeln!(&mut output, "{}", stemmer.stem(&line.unwrap())).unwrap();
            }
        }
    }
}

/// Wraps a usable interface around the actual stemmer implementation
pub struct Stemmer {
    stemmer: Box<Fn(&mut SnowballEnv) -> bool>,
}

impl Stemmer {
    /// Create a new stemmer from an algorithm
    pub fn create(lang: String) -> Self {
        // Have a look at ../build.rs
        // There we generate a file that is rust code for a closure that returns a stemmer.
        // We match against all the algorithms in src/snowball/algoritms/ folder.
        // Alas, this can not be included as a match statment or function because of rust's
        // hygenic macros.
        let match_language = include!(concat!(env!("OUT_DIR"), "/lang_matches.rs"));
        match_language(lang)
    }

    /// Stem a single word
    /// Please note, that the input is expected to be all lowercase (if that is applicable).
    pub fn stem<'a>(&self, input: &'a str) -> Cow<'a, str> {
        let mut env = SnowballEnv::create(input);
        (self.stemmer)(&mut env);
        env.get_current()
    }
}
<commit_msg>more typos<commit_after>use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::path::Path;
use std::env;
use std::borrow::Cow;

pub mod snowball;

use snowball::SnowballEnv;

fn usage(name: &str) {
    println!("{} -l <language> [-i <input file>] [-o <output file>]
The input file consists of a list of words to be stemmed, one per
line. Words should be in lower case, but (for English) A-Z letters
are mapped to their a-z equivalents anyway. If omitted, stdin is
used.", name);
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 3 {
        usage(&args[0]);
    } else {
        let mut language = None;
        let mut input_arg = None;
        let mut output_arg = None;
        let mut i = 1;
        while i < args.len() {
            match args[i].as_str() {
                "-l" => {
                    language = Some(args[i+1].clone());
                    i += 2;
                },
                "-i" => {
                    input_arg = Some(args[i+1].clone());
                    i += 2;
                },
                "-o" => {
                    output_arg = Some(args[i+1].clone());
                    i += 2;
                },
                x => {
                    println!("Unrecognized option '{}'", x);
                    usage(&args[0]);
                    return
                }
            }
        }
        if language.is_none() {
            println!("Please specify a language!");
            usage(&args[0]);
            return;
        }
        let stemmer = Stemmer::create(language.unwrap());

        let mut output = if let Some(output_file) = output_arg {
            Box::new(File::create(Path::new(&output_file)).unwrap()) as Box<Write>
        } else {
            Box::new(std::io::stdout()) as Box<Write>
        };

        if let Some(input_file) = input_arg {
            for line in BufReader::new(File::open(Path::new(&input_file)).unwrap()).lines() {
                writeln!(&mut output, "{}", stemmer.stem(&line.unwrap())).unwrap();
            }
        } else {
            let stdin = std::io::stdin();
            for line in stdin.lock().lines() {
                writeln!(&mut output, "{}", stemmer.stem(&line.unwrap())).unwrap();
            }
        }
    }
}

/// Wraps a usable interface around the actual stemmer implementation
pub struct Stemmer {
    stemmer: Box<Fn(&mut SnowballEnv) -> bool>,
}

impl Stemmer {
    /// Create a new stemmer from an algorithm
    pub fn create(lang: String) -> Self {
        // Have a look at ../build.rs
        // There we generate a file that is rust code for a closure that returns a stemmer.
        // We match against all the algorithms in src/snowball/algoritms/ folder.
        // Alas, this cannot be included as a match statement or function because of Rust's
        // hygenic macros.
        let match_language = include!(concat!(env!("OUT_DIR"), "/lang_matches.rs"));
        match_language(lang)
    }

    /// Stem a single word
    /// Please note, that the input is expected to be all lowercase (if that is applicable).
    pub fn stem<'a>(&self, input: &'a str) -> Cow<'a, str> {
        let mut env = SnowballEnv::create(input);
        (self.stemmer)(&mut env);
        env.get_current()
    }
}
<|endoftext|>


<commit_before>#![warn(rust_2018_idioms)]

use std::iter::repeat;
use std::time::Duration;
use std::{env, path};

use ggez::conf;
use ggez::event;
use ggez::filesystem;
use ggez::graphics;
use ggez::timer;
use ggez::{Context, ContextBuilder, GameResult};
// use image::RgbaImage;

use warmy::SimpleKey;

use openmoonstone::game::Game;
use openmoonstone::input;
use openmoonstone::objects::TextureAtlas;
use openmoonstone::palette::PaletteSwaps;
use openmoonstone::piv::PivImage;
use openmoonstone::piv::{extract_palette, Colour};
use openmoonstone::scenes;
use openmoonstone::scenes::transition::FadeStyle;
use openmoonstone::scenes::{FSceneStack, Fade, MainMenuScene, MainScene, SelectKnight};

struct MainState {
    input_binding: input::InputBinding,
    scene_stack: FSceneStack,
}

impl event::EventHandler for MainState {
    fn update(&mut self, ctx: &mut Context) -> GameResult<()> {
        const MAX_UPDATES_PER_FRAME: u32 = 1;
        // see https://docs.rs/ggez/0.4.4/ggez/timer/fn.check_update_time.html
        // we don't want our while loop to allow unbounded number of ticks
        // in between draw calls, ideally we'd like it to be 1-1.
        //
        // Limiting the number of updates means that when the scene is first
        // loaded we don't suddenly call update loads of times at once.
        // causing knights to zip across the screen if the move button is held.
        // TODO look into passing delta time to scene_stack.update()
        // this might mean we can go back to the recommended loop
        // TODO allow this to be configurable so if people need frame skip as they
        // are running this on a potato then they can.
        let mut ticks = 0;

        // https://en.wikibooks.org/wiki/X86_Assembly/Programmable_Interval_Timer
        const DOS_PIT_FREQUENCY: u32 = 1_193_182; // hz
        const FREQUENCY_DIVISOR: u32 = 21_845; // taken from DOS version of moonstone
        const ONE_SECOND: u32 = 1000; // ms
        const DESIRED_FPS: u32 = ONE_SECOND / (DOS_PIT_FREQUENCY / FREQUENCY_DIVISOR);
        while timer::check_update_time(ctx, DESIRED_FPS) {
            if ticks < MAX_UPDATES_PER_FRAME {
                self.scene_stack.world.input.update(1.0);
                self.scene_stack.update(ctx);
            }
            ticks += 1;
        }
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        self.scene_stack.draw(ctx);
        graphics::present(ctx);
        timer::sleep(Duration::from_millis(50));
        Ok(())
    }

    fn key_down_event(
        &mut self,
        ctx: &mut Context,
        keycode: event::KeyCode,
        keymods: event::KeyMods,
        repeat: bool,
    ) {
        self.scene_stack
            .input(input::InputEvent::Key(keycode), true);
        if let Some(ev) = self.input_binding.resolve(keycode) {
            self.scene_stack.input(input::InputEvent::Binded(ev), true);
            self.scene_stack.world.input.update_effect(ev, true);
        }
    }

    fn key_up_event(
        &mut self,
        ctx: &mut Context,
        keycode: event::KeyCode,
        keymods: event::KeyMods,
    ) {
        if let Some(ev) = self.input_binding.resolve(keycode) {
            self.scene_stack.input(input::InputEvent::Binded(ev), false);
            self.scene_stack.world.input.update_effect(ev, false);
        }
    }
    fn text_input_event(&mut self, _ctx: &mut Context, c: char) {
        self.scene_stack.input(input::InputEvent::Text(c), true);
    }
}

fn main() {
    let mut builder = ContextBuilder::new("openmoonstone", "joetsoi");
    if let Ok(manifest_dir) = env::var("CARGO_MANIFEST_DIR") {
        let path = path::PathBuf::from(manifest_dir).join("resources");
        println!("Adding 'resources' path {:?}", path);
        builder = builder.add_resource_path(path);
    }
    let (ctx, event_loop) = &mut builder.build().unwrap();
    println!("{:?}", graphics::screen_coordinates(ctx));
    println!("{:?}", graphics::renderer_info(ctx));
    graphics::set_default_filter(ctx, graphics::FilterMode::Nearest);

    let game = Game::new().expect("failed to initialize game");
    let scale_matrix = graphics::DrawParam::default()
        .scale(game.screen_scale)
        .to_matrix();
    graphics::push_transform(ctx, Some(scale_matrix));
    graphics::apply_transformations(ctx);

    let mut scene_stack = scenes::FSceneStack::new(ctx, game);
    let map = scene_stack
        .world
        .store
        .get::<PivImage>(&SimpleKey::from("map".to_string()), ctx)
        // TODO: fix with ? error syntax
        .expect("error loading wa1");
    // let image = RgbaImage::from_raw(512, 512, map.borrow().to_rgba8_512()).unwrap();
    // image.save("ch.png");

    // let swaps_res = scene_stack.world.store
    //     .get::<PaletteSwaps>(&SimpleKey::from("/palettes.yaml"), ctx)
    //     // TODO: fix with ?
    //     .expect("error loading palette.yaml");
    // let swaps = swaps_res.borrow();
    // let raw_palette = swaps
    //     .0
    //     .get("default")
    //     .expect("failed to fetch default palette");
    // let palette = extract_palette(raw_palette);

    let cmp = scene_stack
        .world
        .store
        .get::<TextureAtlas>(&SimpleKey::from("mi.c".to_string()), ctx)
        // TODO: fix with ? error syntax
        .expect("error loading wa1");

    let mut palette = map.borrow().palette.to_vec();
    if palette.len() == 16 {
        palette.extend(
            repeat(Colour {
                r: 0,
                g: 0,
                b: 0,
                a: 0,
            })
            .take(16),
        );
    }
    // let image = RgbaImage::from_raw(2048, 2048, cmp.borrow().image.to_rgba8(&map.borrow().palette)).unwrap();
    // // let image = RgbaImage::from_raw(256, 256, cmp.borrow().image.to_rgba8(&palette)).unwrap();
    // image.save("mi.c.png");
    // println!("{:x?}", map.borrow().raw_palette);
    // panic!("wee");

    let main_scene = MainScene::new();
    scene_stack.push(Box::new(main_scene));

    let menu = MainMenuScene::new(ctx, &mut scene_stack.world.store).unwrap();
    scene_stack.push(Box::new(menu));

    // let fade_in = Fade::new(274, 1, FadeStyle::In);
    // scene_stack.push(Box::new(fade_in));

    // let sk = SelectKnight::new(ctx, &mut scene_stack.world.store).unwrap();
    // scene_stack.push(Box::new(sk));

    // let map = scenes::MapScene::new(ctx, &mut scene_stack.world.store, "map").unwrap();
    // scene_stack.push(Box::new(map));

    let mut state = MainState {
        scene_stack,
        input_binding: input::create_input_binding(),
    };
    event::run(ctx, event_loop, &mut state).unwrap();
}
<commit_msg>listen to my own advice on game loops<commit_after>#![warn(rust_2018_idioms)]

use std::iter::repeat;
use std::time::Duration;
use std::{env, path};

use ggez::conf;
use ggez::event;
use ggez::filesystem;
use ggez::graphics;
use ggez::timer;
use ggez::{Context, ContextBuilder, GameResult};
// use image::RgbaImage;

use warmy::SimpleKey;

use openmoonstone::game::Game;
use openmoonstone::input;
use openmoonstone::objects::TextureAtlas;
use openmoonstone::palette::PaletteSwaps;
use openmoonstone::piv::PivImage;
use openmoonstone::piv::{extract_palette, Colour};
use openmoonstone::scenes;
use openmoonstone::scenes::transition::FadeStyle;
use openmoonstone::scenes::{FSceneStack, Fade, MainMenuScene, MainScene, SelectKnight};

struct MainState {
    input_binding: input::InputBinding,
    scene_stack: FSceneStack,
}

impl event::EventHandler for MainState {
    fn update(&mut self, ctx: &mut Context) -> GameResult<()> {
        const MAX_UPDATES_PER_FRAME: u32 = 1;
        // see https://docs.rs/ggez/0.4.4/ggez/timer/fn.check_update_time.html
        // we don't want our while loop to allow unbounded number of ticks
        // in between draw calls, ideally we'd like it to be 1-1.
        //
        // Limiting the number of updates means that when the scene is first
        // loaded we don't suddenly call update loads of times at once.
        // causing knights to zip across the screen if the move button is held.
        // TODO look into passing delta time to scene_stack.update()
        // this might mean we can go back to the recommended loop
        // TODO allow this to be configurable so if people need frame skip as they
        // are running this on a potato then they can.
        let mut ticks = 0;

        // https://en.wikibooks.org/wiki/X86_Assembly/Programmable_Interval_Timer
        const DOS_PIT_FREQUENCY: u32 = 1_193_182; // hz
        const FREQUENCY_DIVISOR: u32 = 21_845; // taken from DOS version of moonstone
        const ONE_SECOND: u32 = 1000; // ms
        const DESIRED_FPS: u32 = ONE_SECOND / (DOS_PIT_FREQUENCY / FREQUENCY_DIVISOR);
        while timer::check_update_time(ctx, DESIRED_FPS) {
            if ticks < MAX_UPDATES_PER_FRAME {
                self.scene_stack.world.input.update(1.0);
                self.scene_stack.update(ctx);
            }
            ticks += 1;
        }
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        self.scene_stack.draw(ctx);
        graphics::present(ctx);
        Ok(())
    }

    fn key_down_event(
        &mut self,
        ctx: &mut Context,
        keycode: event::KeyCode,
        keymods: event::KeyMods,
        repeat: bool,
    ) {
        self.scene_stack
            .input(input::InputEvent::Key(keycode), true);
        if let Some(ev) = self.input_binding.resolve(keycode) {
            self.scene_stack.input(input::InputEvent::Binded(ev), true);
            self.scene_stack.world.input.update_effect(ev, true);
        }
    }

    fn key_up_event(
        &mut self,
        ctx: &mut Context,
        keycode: event::KeyCode,
        keymods: event::KeyMods,
    ) {
        if let Some(ev) = self.input_binding.resolve(keycode) {
            self.scene_stack.input(input::InputEvent::Binded(ev), false);
            self.scene_stack.world.input.update_effect(ev, false);
        }
    }
    fn text_input_event(&mut self, _ctx: &mut Context, c: char) {
        self.scene_stack.input(input::InputEvent::Text(c), true);
    }
}

fn main() {
    let mut builder = ContextBuilder::new("openmoonstone", "joetsoi");
    if let Ok(manifest_dir) = env::var("CARGO_MANIFEST_DIR") {
        let path = path::PathBuf::from(manifest_dir).join("resources");
        println!("Adding 'resources' path {:?}", path);
        builder = builder.add_resource_path(path);
    }
    let (ctx, event_loop) = &mut builder.build().unwrap();
    println!("{:?}", graphics::screen_coordinates(ctx));
    println!("{:?}", graphics::renderer_info(ctx));
    graphics::set_default_filter(ctx, graphics::FilterMode::Nearest);

    let game = Game::new().expect("failed to initialize game");
    let scale_matrix = graphics::DrawParam::default()
        .scale(game.screen_scale)
        .to_matrix();
    graphics::push_transform(ctx, Some(scale_matrix));
    graphics::apply_transformations(ctx);

    let mut scene_stack = scenes::FSceneStack::new(ctx, game);
    let map = scene_stack
        .world
        .store
        .get::<PivImage>(&SimpleKey::from("map".to_string()), ctx)
        // TODO: fix with ? error syntax
        .expect("error loading wa1");
    // let image = RgbaImage::from_raw(512, 512, map.borrow().to_rgba8_512()).unwrap();
    // image.save("ch.png");

    // let swaps_res = scene_stack.world.store
    //     .get::<PaletteSwaps>(&SimpleKey::from("/palettes.yaml"), ctx)
    //     // TODO: fix with ?
    //     .expect("error loading palette.yaml");
    // let swaps = swaps_res.borrow();
    // let raw_palette = swaps
    //     .0
    //     .get("default")
    //     .expect("failed to fetch default palette");
    // let palette = extract_palette(raw_palette);

    let cmp = scene_stack
        .world
        .store
        .get::<TextureAtlas>(&SimpleKey::from("mi.c".to_string()), ctx)
        // TODO: fix with ? error syntax
        .expect("error loading wa1");

    let mut palette = map.borrow().palette.to_vec();
    if palette.len() == 16 {
        palette.extend(
            repeat(Colour {
                r: 0,
                g: 0,
                b: 0,
                a: 0,
            })
            .take(16),
        );
    }
    // let image = RgbaImage::from_raw(2048, 2048, cmp.borrow().image.to_rgba8(&map.borrow().palette)).unwrap();
    // // let image = RgbaImage::from_raw(256, 256, cmp.borrow().image.to_rgba8(&palette)).unwrap();
    // image.save("mi.c.png");
    // println!("{:x?}", map.borrow().raw_palette);
    // panic!("wee");

    let main_scene = MainScene::new();
    scene_stack.push(Box::new(main_scene));

    let menu = MainMenuScene::new(ctx, &mut scene_stack.world.store).unwrap();
    scene_stack.push(Box::new(menu));

    // let fade_in = Fade::new(274, 1, FadeStyle::In);
    // scene_stack.push(Box::new(fade_in));

    // let sk = SelectKnight::new(ctx, &mut scene_stack.world.store).unwrap();
    // scene_stack.push(Box::new(sk));

    // let map = scenes::MapScene::new(ctx, &mut scene_stack.world.store, "map").unwrap();
    // scene_stack.push(Box::new(map));

    let mut state = MainState {
        scene_stack,
        input_binding: input::create_input_binding(),
    };
    event::run(ctx, event_loop, &mut state).unwrap();
}
<|endoftext|>