<commit_before>#![feature(slice_patterns)]

extern crate elmesque;
extern crate gfx;
extern crate gfx_device_gl;
extern crate gfx_graphics;
extern crate glutin_window;
extern crate graphics;
extern crate num;
extern crate shader_version;
extern crate piston;

use elmesque::{Form, Renderer};
use gfx::traits::*;
use gfx_graphics::{Gfx2d, GlyphCache};
use glutin_window::GlutinWindow;
use piston::event::{Event, Events};
use piston::window::{Size, Window, WindowSettings};

fn main() {

    let window = GlutinWindow::new(
        shader_version::opengl::OpenGL::_3_2,
        WindowSettings::new(
            "Elmesque".to_string(),
            Size { width: 1180, height: 580 },
        )
        .exit_on_esc(true)
        .samples(4)
    );
    let (mut device, mut factory) = gfx_device_gl::create(|s| window.window.get_proc_address(s));
    let mut g2d = Gfx2d::new(&mut device, &mut factory);
    let mut renderer = factory.create_renderer();
    let Size { width, height } = window.size();
    let output = factory.make_fake_output(width as u16, height as u16);
    let font_path = ::std::path::Path::new("./assets/NotoSans/NotoSans-Regular.ttf");
    let mut glyph_cache = GlyphCache::new(&font_path, &mut factory).unwrap();
    let event_iter = window.events().ups(180).max_fps(60);
    let mut secs = 0.0;
    for event in event_iter {
        match event {
            Event::Render(args) => {
                g2d.draw(&mut renderer, &output, args.viewport(), |_, graphics| {
                    let (w, h) = (args.width as f64, args.height as f64);

                    let mut renderer = Renderer::new(w, h, graphics).character_cache(&mut glyph_cache);

                    // Construct some freeform graphics aka a `Form`.
                    let form = elmesque_demo_form(secs);

                    // Convert the form to an `Element` for rendering.
                    elmesque::form::collage(w as i32, h as i32, vec![form])
                        .clear(elmesque::color::black())
                        .draw(&mut renderer);

                });
                device.submit(renderer.as_buffer());
                renderer.reset();
                glyph_cache.update(&mut factory);
            },
            Event::Update(args) => secs += args.dt,
            _ => (),
        }
    }
}

/// Demo of grouping multiple forms into a new single form, transformable at any stage.
pub fn elmesque_demo_form(secs: f64) -> Form {
    use elmesque::color::{blue, dark_blue, light_blue, dark_purple, white};
    use elmesque::form::{circle, group, ngon, oval, point_path, rect, solid, text, traced};
    use elmesque::text::Text;
    use elmesque::utils::{degrees};
    use num::Float;

    // Time to get creative!
    group(vec![

        rect(60.0, 40.0).filled(blue())
            .shift(secs.sin() * 50.0, secs.cos() * 50.0)
            .alpha(((secs * 200.0).cos() * 0.5 + 0.5) as f32)
            .rotate(-secs),

        rect(100.0, 10.0).filled(dark_blue())
            .shift((secs * 5.0).sin() * 200.0, (secs * 5.0).cos() * 200.0)
            .alpha(((secs * 2.0).cos() * 0.5 + 0.5) as f32)
            .rotate(-(secs * 5.0)),

        rect(10.0, 300.0).filled(blue())
            .alpha(((secs * 3.0).sin() * 0.25 + 0.75) as f32)
            .rotate(-(secs * 1.5)),

        rect(5.0, (secs * 0.1).sin() * 600.0 + 300.0).filled(light_blue())
            .alpha(((secs).cos() * 0.25 + 0.75) as f32)
            .rotate(secs * 0.75),

        rect(3.0, 2000.0).filled(dark_blue())
            .alpha(((secs * 100.0).cos() * 0.5 + 0.25) as f32)
            .rotate(-(secs * 0.5)),

        oval(3.0, 2000.0 * (secs * 60.0).sin()).filled(light_blue())
            .alpha(((secs * 100.0).cos() * 0.5 + 0.25) as f32)
            .rotate(-(secs * 0.6)),

        rect(10.0, 750.0).filled(blue())
            .alpha(((secs * 2.0).cos() * 0.5 + 0.25) as f32)
            .rotate(-(secs * 1.85)),

        circle((secs * 0.5).sin() * 1500.0).outlined(solid(dark_purple()))
            .alpha(((secs * 0.2).sin() * 0.25 + 0.35) as f32)
            .rotate(-(secs * 0.5)),

        ngon(12, (secs * 0.1).cos() * 100.0 + 300.0).filled(blue())
            .alpha((0.25 * secs.cos()) as f32)
            .rotate(secs * 0.5),

        ngon(9, (secs * 0.1).cos() * 200.0 + 250.0).outlined(solid(dark_blue()))
            .alpha(((0.33 * secs).sin() + 0.15) as f32)
            .rotate(secs * 0.2),

        rect(300.0, 20.0).filled(light_blue())
            .shift((secs * 1.5).cos() * 250.0, (secs * 1.5).sin() * 250.0)
            .alpha(((secs * 4.5).cos() * 0.25 + 0.35) as f32)
            .rotate(secs * 1.5 + degrees(90.0)),

        traced(
            solid(light_blue()),
            point_path(vec![(-500.0, 100.0), (0.0, 250.0 * secs.sin()), (500.0, 100.0)])
        ).alpha(((secs * 0.2).sin() * 0.25 + 0.35) as f32),

        traced(
            solid(blue()),
            point_path(vec![(-500.0, 0.0), (0.0, 0.0), (500.0, 0.0)])
        ).alpha(((secs * 4.5).cos() * 0.25 + 0.35) as f32),

        traced(
            solid(dark_blue()),
            point_path(vec![(-500.0, -100.0), (0.0, -250.0 * secs.sin()), (500.0, -100.0)])
        ).alpha(((secs * 0.15).cos() * 0.25 + 0.35) as f32),

        text(Text::from_string("elmesque".to_string()).color(white())),

    ]).rotate(degrees(secs.sin() * 360.0))
      .scale((secs * 0.05).cos() * 0.2 + 0.9)

}

<commit_msg>Removed unstable slice_patterns feature from example<commit_after>
extern crate elmesque;
extern crate gfx;
extern crate gfx_device_gl;
extern crate gfx_graphics;
extern crate glutin_window;
extern crate graphics;
extern crate num;
extern crate shader_version;
extern crate piston;

use elmesque::{Form, Renderer};
use gfx::traits::*;
use gfx_graphics::{Gfx2d, GlyphCache};
use glutin_window::GlutinWindow;
use piston::event::{Event, Events};
use piston::window::{Size, Window, WindowSettings};

fn main() {

    let window = GlutinWindow::new(
        shader_version::opengl::OpenGL::_3_2,
        WindowSettings::new(
            "Elmesque".to_string(),
            Size { width: 1180, height: 580 },
        )
        .exit_on_esc(true)
        .samples(4)
    );
    let (mut device, mut factory) = gfx_device_gl::create(|s| window.window.get_proc_address(s));
    let mut g2d = Gfx2d::new(&mut device, &mut factory);
    let mut renderer = factory.create_renderer();
    let Size { width, height } = window.size();
    let output = factory.make_fake_output(width as u16, height as u16);
    let font_path = ::std::path::Path::new("./assets/NotoSans/NotoSans-Regular.ttf");
    let mut glyph_cache = GlyphCache::new(&font_path, &mut factory).unwrap();
    let event_iter = window.events().ups(180).max_fps(60);
    let mut secs = 0.0;
    for event in event_iter {
        match event {
            Event::Render(args) => {
                g2d.draw(&mut renderer, &output, args.viewport(), |_, graphics| {
                    let (w, h) = (args.width as f64, args.height as f64);

                    let mut renderer = Renderer::new(w, h, graphics).character_cache(&mut glyph_cache);

                    // Construct some freeform graphics aka a `Form`.
                    let form = elmesque_demo_form(secs);

                    // Convert the form to an `Element` for rendering.
                    elmesque::form::collage(w as i32, h as i32, vec![form])
                        .clear(elmesque::color::black())
                        .draw(&mut renderer);

                });
                device.submit(renderer.as_buffer());
                renderer.reset();
                glyph_cache.update(&mut factory);
            },
            Event::Update(args) => secs += args.dt,
            _ => (),
        }
    }
}

/// Demo of grouping multiple forms into a new single form, transformable at any stage.
pub fn elmesque_demo_form(secs: f64) -> Form {
    use elmesque::color::{blue, dark_blue, light_blue, dark_purple, white};
    use elmesque::form::{circle, group, ngon, oval, point_path, rect, solid, text, traced};
    use elmesque::text::Text;
    use elmesque::utils::{degrees};
    use num::Float;

    // Time to get creative!
    group(vec![

        rect(60.0, 40.0).filled(blue())
            .shift(secs.sin() * 50.0, secs.cos() * 50.0)
            .alpha(((secs * 200.0).cos() * 0.5 + 0.5) as f32)
            .rotate(-secs),

        rect(100.0, 10.0).filled(dark_blue())
            .shift((secs * 5.0).sin() * 200.0, (secs * 5.0).cos() * 200.0)
            .alpha(((secs * 2.0).cos() * 0.5 + 0.5) as f32)
            .rotate(-(secs * 5.0)),

        rect(10.0, 300.0).filled(blue())
            .alpha(((secs * 3.0).sin() * 0.25 + 0.75) as f32)
            .rotate(-(secs * 1.5)),

        rect(5.0, (secs * 0.1).sin() * 600.0 + 300.0).filled(light_blue())
            .alpha(((secs).cos() * 0.25 + 0.75) as f32)
            .rotate(secs * 0.75),

        rect(3.0, 2000.0).filled(dark_blue())
            .alpha(((secs * 100.0).cos() * 0.5 + 0.25) as f32)
            .rotate(-(secs * 0.5)),

        oval(3.0, 2000.0 * (secs * 60.0).sin()).filled(light_blue())
            .alpha(((secs * 100.0).cos() * 0.5 + 0.25) as f32)
            .rotate(-(secs * 0.6)),

        rect(10.0, 750.0).filled(blue())
            .alpha(((secs * 2.0).cos() * 0.5 + 0.25) as f32)
            .rotate(-(secs * 1.85)),

        circle((secs * 0.5).sin() * 1500.0).outlined(solid(dark_purple()))
            .alpha(((secs * 0.2).sin() * 0.25 + 0.35) as f32)
            .rotate(-(secs * 0.5)),

        ngon(12, (secs * 0.1).cos() * 100.0 + 300.0).filled(blue())
            .alpha((0.25 * secs.cos()) as f32)
            .rotate(secs * 0.5),

        ngon(9, (secs * 0.1).cos() * 200.0 + 250.0).outlined(solid(dark_blue()))
            .alpha(((0.33 * secs).sin() + 0.15) as f32)
            .rotate(secs * 0.2),

        rect(300.0, 20.0).filled(light_blue())
            .shift((secs * 1.5).cos() * 250.0, (secs * 1.5).sin() * 250.0)
            .alpha(((secs * 4.5).cos() * 0.25 + 0.35) as f32)
            .rotate(secs * 1.5 + degrees(90.0)),

        traced(
            solid(light_blue()),
            point_path(vec![(-500.0, 100.0), (0.0, 250.0 * secs.sin()), (500.0, 100.0)])
        ).alpha(((secs * 0.2).sin() * 0.25 + 0.35) as f32),

        traced(
            solid(blue()),
            point_path(vec![(-500.0, 0.0), (0.0, 0.0), (500.0, 0.0)])
        ).alpha(((secs * 4.5).cos() * 0.25 + 0.35) as f32),

        traced(
            solid(dark_blue()),
            point_path(vec![(-500.0, -100.0), (0.0, -250.0 * secs.sin()), (500.0, -100.0)])
        ).alpha(((secs * 0.15).cos() * 0.25 + 0.35) as f32),

        text(Text::from_string("elmesque".to_string()).color(white())),

    ]).rotate(degrees(secs.sin() * 360.0))
      .scale((secs * 0.05).cos() * 0.2 + 0.9)

}

<|endoftext|>


<commit_before>//! Module for User-Interactive Authentication API types.

use std::{
    collections::BTreeMap,
    fmt::{self, Display, Formatter},
};

use ruma_api::{error::ResponseDeserializationError, EndpointError};
use ruma_serde::Outgoing;
use serde::{Deserialize, Serialize};
use serde_json::{
    from_slice as from_json_slice, to_vec as to_json_vec, value::RawValue as RawJsonValue,
    Value as JsonValue,
};

use crate::error::{Error as MatrixError, ErrorBody};

/// Additional authentication information for the user-interactive authentication API.
#[derive(Clone, Debug, Outgoing, Serialize)]
#[serde(untagged)]
pub enum AuthData<'a> {
    /// Used for sending UIAA authentication requests to the homeserver directly from the client.
    DirectRequest {
        /// The login type that the client is attempting to complete.
        #[serde(rename = "type")]
        kind: &'a str,

        /// The value of the session key given by the homeserver.
        #[serde(skip_serializing_if = "Option::is_none")]
        session: Option<&'a str>,

        /// Parameters submitted for a particular authentication stage.
        // FIXME: RawJsonValue doesn't work here, is that a bug?
        #[serde(flatten)]
        auth_parameters: BTreeMap<String, JsonValue>,
    },

    /// Used by the client to acknowledge that the user has completed a UIAA stage through the
    /// fallback method.
    FallbackAcknowledgement {
        /// The value of the session key given by the homeserver.
        session: &'a str,
    },
}

/// Information about available authentication flows and status for User-Interactive Authenticiation
/// API.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct UiaaInfo {
    /// List of authentication flows available for this endpoint.
    pub flows: Vec<AuthFlow>,

    /// List of stages in the current flow completed by the client.
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub completed: Vec<String>,

    /// Authentication parameters required for the client to complete authentication.
    ///
    /// To create a `Box<RawJsonValue>`, use `serde_json::value::to_raw_value`.
    pub params: Box<RawJsonValue>,

    /// Session key for client to use to complete authentication.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub session: Option<String>,

    /// Authentication-related errors for previous request returned by homeserver.
    #[serde(flatten, skip_serializing_if = "Option::is_none")]
    pub auth_error: Option<ErrorBody>,
}

/// Description of steps required to authenticate via the User-Interactive Authentication API.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(test, derive(PartialEq))]
pub struct AuthFlow {
    /// Ordered list of stages required to complete authentication.
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub stages: Vec<String>,
}

/// Contains either a User-Interactive Authentication API response body or a Matrix error.
#[derive(Clone, Debug)]
pub enum UiaaResponse {
    /// User-Interactive Authentication API response
    AuthResponse(UiaaInfo),

    /// Matrix error response
    MatrixError(MatrixError),
}

impl Display for UiaaResponse {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        match self {
            Self::AuthResponse(_) => write!(f, "User-Interactive Authentication required."),
            Self::MatrixError(err) => write!(f, "{}", err),
        }
    }
}

impl From<MatrixError> for UiaaResponse {
    fn from(error: MatrixError) -> Self {
        Self::MatrixError(error)
    }
}

impl EndpointError for UiaaResponse {
    fn try_from_response(
        response: http::Response<Vec<u8>>,
    ) -> Result<Self, ResponseDeserializationError> {
        if response.status() == http::StatusCode::UNAUTHORIZED {
            if let Ok(authentication_info) = from_json_slice::<UiaaInfo>(response.body()) {
                return Ok(UiaaResponse::AuthResponse(authentication_info));
            }
        }

        MatrixError::try_from_response(response).map(From::from)
    }
}

impl std::error::Error for UiaaResponse {}

impl From<UiaaResponse> for http::Response<Vec<u8>> {
    fn from(uiaa_response: UiaaResponse) -> http::Response<Vec<u8>> {
        match uiaa_response {
            UiaaResponse::AuthResponse(authentication_info) => http::Response::builder()
                .header(http::header::CONTENT_TYPE, "application/json")
                .status(&http::StatusCode::UNAUTHORIZED)
                .body(to_json_vec(&authentication_info).unwrap())
                .unwrap(),
            UiaaResponse::MatrixError(error) => http::Response::from(error),
        }
    }
}

#[cfg(test)]
mod tests {
    use maplit::btreemap;
    use matches::assert_matches;
    use ruma_api::EndpointError;
    use serde_json::{
        from_slice as from_json_slice, from_str as from_json_str, from_value as from_json_value,
        json, to_value as to_json_value, value::to_raw_value as to_raw_json_value,
        Value as JsonValue,
    };

    use super::{AuthData, AuthFlow, IncomingAuthData, UiaaInfo, UiaaResponse};
    use crate::error::{ErrorBody, ErrorKind};

    #[test]
    fn serialize_authentication_data_direct_request() {
        let authentication_data = AuthData::DirectRequest {
            kind: "example.type.foo",
            session: Some("ZXY000"),
            auth_parameters: btreemap! {
                "example_credential".to_owned() => json!("verypoorsharedsecret")
            },
        };

        assert_eq!(
            json!({
                "type": "example.type.foo",
                "session": "ZXY000",
                "example_credential": "verypoorsharedsecret",
            }),
            to_json_value(authentication_data).unwrap()
        );
    }

    #[test]
    fn deserialize_authentication_data_direct_request() {
        let json = json!({
            "type": "example.type.foo",
            "session": "opaque_session_id",
            "example_credential": "verypoorsharedsecret",
        });

        assert_matches!(
            from_json_value(json).unwrap(),
            IncomingAuthData::DirectRequest { kind, session: Some(session), auth_parameters }
            if kind == "example.type.foo"
                && session == "opaque_session_id"
                && auth_parameters == btreemap!{
                    "example_credential".to_owned() => json!("verypoorsharedsecret")
                }
        );
    }

    #[test]
    fn serialize_authentication_data_fallback() {
        let authentication_data = AuthData::FallbackAcknowledgement { session: "ZXY000" };

        assert_eq!(json!({ "session": "ZXY000" }), to_json_value(authentication_data).unwrap());
    }

    #[test]
    fn deserialize_authentication_data_fallback() {
        let json = json!({ "session": "opaque_session_id" });

        assert_matches!(
            from_json_value(json).unwrap(),
            IncomingAuthData::FallbackAcknowledgement { session }
            if session == "opaque_session_id"
        );
    }

    #[test]
    fn serialize_uiaa_info() {
        let uiaa_info = UiaaInfo {
            flows: vec![AuthFlow {
                stages: vec!["m.login.password".into(), "m.login.dummy".into()],
            }],
            completed: vec!["m.login.password".into()],
            params: to_raw_json_value(&json!({
                "example.type.baz": {
                    "example_key": "foobar"
                }
            }))
            .unwrap(),
            session: None,
            auth_error: None,
        };

        let json = json!({
            "flows": [{ "stages": ["m.login.password", "m.login.dummy"] }],
            "completed": ["m.login.password"],
            "params": {
                "example.type.baz": {
                    "example_key": "foobar"
                }
            }
        });
        assert_eq!(to_json_value(uiaa_info).unwrap(), json);
    }

    #[test]
    fn deserialize_uiaa_info() {
        let json = json!({
            "errcode": "M_FORBIDDEN",
            "error": "Invalid password",
            "completed": ["example.type.foo"],
            "flows": [
                {
                    "stages": ["example.type.foo", "example.type.bar"]
                },
                {
                    "stages": ["example.type.foo", "example.type.baz"]
                }
            ],
            "params": {
                "example.type.baz": {
                    "example_key": "foobar"
                }
            },
            "session": "xxxxxx"
        });

        assert_matches!(
            from_json_value::<UiaaInfo>(json).unwrap(),
            UiaaInfo {
                auth_error: Some(ErrorBody {
                    kind: ErrorKind::Forbidden,
                    message: error_message,
                }),
                completed,
                flows,
                params,
                session: Some(session),
            } if error_message == "Invalid password"
                && completed == vec!["example.type.foo".to_owned()]
                && flows == vec![
                    AuthFlow {
                        stages: vec![
                            "example.type.foo".into(),
                            "example.type.bar".into(),
                        ],
                    },
                    AuthFlow {
                        stages: vec![
                            "example.type.foo".into(),
                            "example.type.baz".into(),
                        ],
                    },
                ]
                && from_json_str::<JsonValue>(params.get()).unwrap() == json!({
                    "example.type.baz": {
                        "example_key": "foobar"
                    }
                })
                && session == "xxxxxx"
        );
    }

    #[test]
    fn try_uiaa_response_into_http_response() {
        let uiaa_info = UiaaInfo {
            flows: vec![AuthFlow {
                stages: vec!["m.login.password".into(), "m.login.dummy".into()],
            }],
            completed: vec!["m.login.password".into()],
            params: to_raw_json_value(&json!({
                "example.type.baz": {
                    "example_key": "foobar"
                }
            }))
            .unwrap(),
            session: None,
            auth_error: None,
        };
        let uiaa_response: http::Response<Vec<u8>> = UiaaResponse::AuthResponse(uiaa_info).into();

        assert_matches!(
            from_json_slice::<UiaaInfo>(uiaa_response.body()).unwrap(),
            UiaaInfo {
                flows,
                completed,
                params,
                session: None,
                auth_error: None,
            } if flows == vec![AuthFlow {
                    stages: vec!["m.login.password".into(), "m.login.dummy".into()],
                }]
                && completed == vec!["m.login.password".to_owned()]
                && from_json_str::<JsonValue>(params.get()).unwrap() == json!({
                    "example.type.baz": {
                        "example_key": "foobar"
                    }
                })
        );
        assert_eq!(uiaa_response.status(), http::status::StatusCode::UNAUTHORIZED);
    }

    #[test]
    fn try_uiaa_response_from_http_response() {
        let json = serde_json::to_string(&json!({
            "errcode": "M_FORBIDDEN",
            "error": "Invalid password",
            "completed": [ "example.type.foo" ],
            "flows": [
                {
                    "stages": [ "example.type.foo", "example.type.bar" ]
                },
                {
                    "stages": [ "example.type.foo", "example.type.baz" ]
                }
            ],
            "params": {
                "example.type.baz": {
                    "example_key": "foobar"
                }
            },
            "session": "xxxxxx"
        }))
        .unwrap();

        let http_response = http::Response::builder()
            .status(http::StatusCode::UNAUTHORIZED)
            .body(json.into())
            .unwrap();

        let parsed_uiaa_info = match UiaaResponse::try_from_response(http_response).unwrap() {
            UiaaResponse::AuthResponse(uiaa_info) => uiaa_info,
            _ => panic!("Expected UiaaResponse::AuthResponse"),
        };

        assert_matches!(
            parsed_uiaa_info,
            UiaaInfo {
                auth_error: Some(ErrorBody {
                    kind: ErrorKind::Forbidden,
                    message: error_message,
                }),
                completed,
                flows,
                params,
                session: Some(session),
            } if error_message == "Invalid password"
                && completed == vec!["example.type.foo".to_owned()]
                && flows == vec![
                    AuthFlow {
                        stages: vec![
                            "example.type.foo".into(),
                            "example.type.bar".into(),
                        ],
                    },
                    AuthFlow {
                        stages: vec![
                            "example.type.foo".into(),
                            "example.type.baz".into(),
                        ],
                    },
                ]
                && from_json_str::<JsonValue>(params.get()).unwrap() == json!({
                    "example.type.baz": {
                        "example_key": "foobar"
                    }
                })
                && session == "xxxxxx"
        );
    }
}
<commit_msg>client-api: Make UIAA types non-exhaustive<commit_after>//! Module for User-Interactive Authentication API types.

use std::{
    collections::BTreeMap,
    fmt::{self, Display, Formatter},
};

use ruma_api::{error::ResponseDeserializationError, EndpointError};
use ruma_serde::Outgoing;
use serde::{Deserialize, Serialize};
use serde_json::{
    from_slice as from_json_slice, to_vec as to_json_vec, value::RawValue as RawJsonValue,
    Value as JsonValue,
};

use crate::error::{Error as MatrixError, ErrorBody};

/// Additional authentication information for the user-interactive authentication API.
#[derive(Clone, Debug, Outgoing, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[serde(untagged)]
pub enum AuthData<'a> {
    /// Used for sending UIAA authentication requests to the homeserver directly from the client.
    // Could be made non-exhaustive by creating a separate struct and making auth_parameters
    // private, but probably not worth the hassle.
    DirectRequest {
        /// The login type that the client is attempting to complete.
        #[serde(rename = "type")]
        kind: &'a str,

        /// The value of the session key given by the homeserver.
        #[serde(skip_serializing_if = "Option::is_none")]
        session: Option<&'a str>,

        /// Parameters submitted for a particular authentication stage.
        #[serde(flatten)]
        auth_parameters: BTreeMap<String, JsonValue>,
    },

    /// Used by the client to acknowledge that the user has completed a UIAA stage through the
    /// fallback method.
    // Exhaustiveness is correct here since this variant is a fallback that explicitly only has a
    // single field. TODO: #[serde(deny_unknown_fields)] not supported on enum variants
    // https://github.com/serde-rs/serde/issues/1982
    FallbackAcknowledgement {
        /// The value of the session key given by the homeserver.
        session: &'a str,
    },
}

/// Information about available authentication flows and status for User-Interactive Authenticiation
/// API.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct UiaaInfo {
    /// List of authentication flows available for this endpoint.
    pub flows: Vec<AuthFlow>,

    /// List of stages in the current flow completed by the client.
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub completed: Vec<String>,

    /// Authentication parameters required for the client to complete authentication.
    ///
    /// To create a `Box<RawJsonValue>`, use `serde_json::value::to_raw_value`.
    pub params: Box<RawJsonValue>,

    /// Session key for client to use to complete authentication.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub session: Option<String>,

    /// Authentication-related errors for previous request returned by homeserver.
    #[serde(flatten, skip_serializing_if = "Option::is_none")]
    pub auth_error: Option<ErrorBody>,
}

impl UiaaInfo {
    /// Creates a new `UiaaInfo` with the given flows and parameters.
    pub fn new(flows: Vec<AuthFlow>, params: Box<RawJsonValue>) -> Self {
        Self { flows, completed: Vec::new(), params, session: None, auth_error: None }
    }
}

/// Description of steps required to authenticate via the User-Interactive Authentication API.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[cfg_attr(test, derive(PartialEq))]
pub struct AuthFlow {
    /// Ordered list of stages required to complete authentication.
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub stages: Vec<String>,
}

impl AuthFlow {
    /// Creates an empty `AuthFlow`.
    pub fn new() -> Self {
        Self { stages: Vec::new() }
    }
}

/// Contains either a User-Interactive Authentication API response body or a Matrix error.
#[derive(Clone, Debug)]
pub enum UiaaResponse {
    /// User-Interactive Authentication API response
    AuthResponse(UiaaInfo),

    /// Matrix error response
    MatrixError(MatrixError),
}

impl Display for UiaaResponse {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        match self {
            Self::AuthResponse(_) => write!(f, "User-Interactive Authentication required."),
            Self::MatrixError(err) => write!(f, "{}", err),
        }
    }
}

impl From<MatrixError> for UiaaResponse {
    fn from(error: MatrixError) -> Self {
        Self::MatrixError(error)
    }
}

impl EndpointError for UiaaResponse {
    fn try_from_response(
        response: http::Response<Vec<u8>>,
    ) -> Result<Self, ResponseDeserializationError> {
        if response.status() == http::StatusCode::UNAUTHORIZED {
            if let Ok(authentication_info) = from_json_slice::<UiaaInfo>(response.body()) {
                return Ok(UiaaResponse::AuthResponse(authentication_info));
            }
        }

        MatrixError::try_from_response(response).map(From::from)
    }
}

impl std::error::Error for UiaaResponse {}

impl From<UiaaResponse> for http::Response<Vec<u8>> {
    fn from(uiaa_response: UiaaResponse) -> http::Response<Vec<u8>> {
        match uiaa_response {
            UiaaResponse::AuthResponse(authentication_info) => http::Response::builder()
                .header(http::header::CONTENT_TYPE, "application/json")
                .status(&http::StatusCode::UNAUTHORIZED)
                .body(to_json_vec(&authentication_info).unwrap())
                .unwrap(),
            UiaaResponse::MatrixError(error) => http::Response::from(error),
        }
    }
}

#[cfg(test)]
mod tests {
    use maplit::btreemap;
    use matches::assert_matches;
    use ruma_api::EndpointError;
    use serde_json::{
        from_slice as from_json_slice, from_str as from_json_str, from_value as from_json_value,
        json, to_value as to_json_value, value::to_raw_value as to_raw_json_value,
        Value as JsonValue,
    };

    use super::{AuthData, AuthFlow, IncomingAuthData, UiaaInfo, UiaaResponse};
    use crate::error::{ErrorBody, ErrorKind};

    #[test]
    fn serialize_authentication_data_direct_request() {
        let authentication_data = AuthData::DirectRequest {
            kind: "example.type.foo",
            session: Some("ZXY000"),
            auth_parameters: btreemap! {
                "example_credential".to_owned() => json!("verypoorsharedsecret")
            },
        };

        assert_eq!(
            json!({
                "type": "example.type.foo",
                "session": "ZXY000",
                "example_credential": "verypoorsharedsecret",
            }),
            to_json_value(authentication_data).unwrap()
        );
    }

    #[test]
    fn deserialize_authentication_data_direct_request() {
        let json = json!({
            "type": "example.type.foo",
            "session": "opaque_session_id",
            "example_credential": "verypoorsharedsecret",
        });

        assert_matches!(
            from_json_value(json).unwrap(),
            IncomingAuthData::DirectRequest { kind, session: Some(session), auth_parameters }
            if kind == "example.type.foo"
                && session == "opaque_session_id"
                && auth_parameters == btreemap!{
                    "example_credential".to_owned() => json!("verypoorsharedsecret")
                }
        );
    }

    #[test]
    fn serialize_authentication_data_fallback() {
        let authentication_data = AuthData::FallbackAcknowledgement { session: "ZXY000" };

        assert_eq!(json!({ "session": "ZXY000" }), to_json_value(authentication_data).unwrap());
    }

    #[test]
    fn deserialize_authentication_data_fallback() {
        let json = json!({ "session": "opaque_session_id" });

        assert_matches!(
            from_json_value(json).unwrap(),
            IncomingAuthData::FallbackAcknowledgement { session }
            if session == "opaque_session_id"
        );
    }

    #[test]
    fn serialize_uiaa_info() {
        let uiaa_info = UiaaInfo {
            flows: vec![AuthFlow {
                stages: vec!["m.login.password".into(), "m.login.dummy".into()],
            }],
            completed: vec!["m.login.password".into()],
            params: to_raw_json_value(&json!({
                "example.type.baz": {
                    "example_key": "foobar"
                }
            }))
            .unwrap(),
            session: None,
            auth_error: None,
        };

        let json = json!({
            "flows": [{ "stages": ["m.login.password", "m.login.dummy"] }],
            "completed": ["m.login.password"],
            "params": {
                "example.type.baz": {
                    "example_key": "foobar"
                }
            }
        });
        assert_eq!(to_json_value(uiaa_info).unwrap(), json);
    }

    #[test]
    fn deserialize_uiaa_info() {
        let json = json!({
            "errcode": "M_FORBIDDEN",
            "error": "Invalid password",
            "completed": ["example.type.foo"],
            "flows": [
                {
                    "stages": ["example.type.foo", "example.type.bar"]
                },
                {
                    "stages": ["example.type.foo", "example.type.baz"]
                }
            ],
            "params": {
                "example.type.baz": {
                    "example_key": "foobar"
                }
            },
            "session": "xxxxxx"
        });

        assert_matches!(
            from_json_value::<UiaaInfo>(json).unwrap(),
            UiaaInfo {
                auth_error: Some(ErrorBody {
                    kind: ErrorKind::Forbidden,
                    message: error_message,
                }),
                completed,
                flows,
                params,
                session: Some(session),
            } if error_message == "Invalid password"
                && completed == vec!["example.type.foo".to_owned()]
                && flows == vec![
                    AuthFlow {
                        stages: vec![
                            "example.type.foo".into(),
                            "example.type.bar".into(),
                        ],
                    },
                    AuthFlow {
                        stages: vec![
                            "example.type.foo".into(),
                            "example.type.baz".into(),
                        ],
                    },
                ]
                && from_json_str::<JsonValue>(params.get()).unwrap() == json!({
                    "example.type.baz": {
                        "example_key": "foobar"
                    }
                })
                && session == "xxxxxx"
        );
    }

    #[test]
    fn try_uiaa_response_into_http_response() {
        let uiaa_info = UiaaInfo {
            flows: vec![AuthFlow {
                stages: vec!["m.login.password".into(), "m.login.dummy".into()],
            }],
            completed: vec!["m.login.password".into()],
            params: to_raw_json_value(&json!({
                "example.type.baz": {
                    "example_key": "foobar"
                }
            }))
            .unwrap(),
            session: None,
            auth_error: None,
        };
        let uiaa_response: http::Response<Vec<u8>> = UiaaResponse::AuthResponse(uiaa_info).into();

        assert_matches!(
            from_json_slice::<UiaaInfo>(uiaa_response.body()).unwrap(),
            UiaaInfo {
                flows,
                completed,
                params,
                session: None,
                auth_error: None,
            } if flows == vec![AuthFlow {
                    stages: vec!["m.login.password".into(), "m.login.dummy".into()],
                }]
                && completed == vec!["m.login.password".to_owned()]
                && from_json_str::<JsonValue>(params.get()).unwrap() == json!({
                    "example.type.baz": {
                        "example_key": "foobar"
                    }
                })
        );
        assert_eq!(uiaa_response.status(), http::status::StatusCode::UNAUTHORIZED);
    }

    #[test]
    fn try_uiaa_response_from_http_response() {
        let json = serde_json::to_string(&json!({
            "errcode": "M_FORBIDDEN",
            "error": "Invalid password",
            "completed": [ "example.type.foo" ],
            "flows": [
                {
                    "stages": [ "example.type.foo", "example.type.bar" ]
                },
                {
                    "stages": [ "example.type.foo", "example.type.baz" ]
                }
            ],
            "params": {
                "example.type.baz": {
                    "example_key": "foobar"
                }
            },
            "session": "xxxxxx"
        }))
        .unwrap();

        let http_response = http::Response::builder()
            .status(http::StatusCode::UNAUTHORIZED)
            .body(json.into())
            .unwrap();

        let parsed_uiaa_info = match UiaaResponse::try_from_response(http_response).unwrap() {
            UiaaResponse::AuthResponse(uiaa_info) => uiaa_info,
            _ => panic!("Expected UiaaResponse::AuthResponse"),
        };

        assert_matches!(
            parsed_uiaa_info,
            UiaaInfo {
                auth_error: Some(ErrorBody {
                    kind: ErrorKind::Forbidden,
                    message: error_message,
                }),
                completed,
                flows,
                params,
                session: Some(session),
            } if error_message == "Invalid password"
                && completed == vec!["example.type.foo".to_owned()]
                && flows == vec![
                    AuthFlow {
                        stages: vec![
                            "example.type.foo".into(),
                            "example.type.bar".into(),
                        ],
                    },
                    AuthFlow {
                        stages: vec![
                            "example.type.foo".into(),
                            "example.type.baz".into(),
                        ],
                    },
                ]
                && from_json_str::<JsonValue>(params.get()).unwrap() == json!({
                    "example.type.baz": {
                        "example_key": "foobar"
                    }
                })
                && session == "xxxxxx"
        );
    }
}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>update<commit_after>use std::io;

fn main() {
    println!("Pleas input your guess.");

    let mut guess = String::new();

    io::stdin()
        .read_line(&mut guess)
        .expect("Failed to read line");

    println!("You guessed: {}", guess);
}
<|endoftext|>


<commit_before>use crate::{Pointable, Pointer, PointerMut};
use eyre::{bail, Result};
use node_address::Address;
use node_dispatch::dispatch_work;
use stencila_schema::*;

impl Pointable for CreativeWorkTypes {
    /// Resolve an [`Address`] into a node [`Pointer`].
    ///
    /// `CreativeWorkTypes` is one of the pointer variants so return a `Pointer::Work` if
    /// the address is empty. Otherwise dispatch to variant.
    fn resolve(&self, address: &mut Address) -> Result<Pointer> {
        match address.is_empty() {
            true => Ok(Pointer::Work(self)),
            false => dispatch_work!(self, resolve, address),
        }
    }
    fn resolve_mut(&mut self, address: &mut Address) -> Result<PointerMut> {
        match address.is_empty() {
            true => Ok(PointerMut::Work(self)),
            false => dispatch_work!(self, resolve_mut, address),
        }
    }

    /// Find a node based on its `id` and return a [`Pointer`] to it.
    ///
    /// Dispatch to variant and if it returns `Pointer::Some` then rewrite to `Pointer::Work`
    fn find(&self, id: &str) -> Pointer {
        match dispatch_work!(self, find, id) {
            Pointer::Some => Pointer::Work(self),
            _ => Pointer::None,
        }
    }
    fn find_mut(&mut self, id: &str) -> PointerMut {
        match dispatch_work!(self, find_mut, id) {
            PointerMut::Some => PointerMut::Work(self),
            _ => PointerMut::None,
        }
    }
}

// Implementations for `CreativeWork` structs. For descendants of these
// works to be pointable they must be within one of the listed properties e.g. `Article.content`.

pointable_struct!(Article, content);
pointable_struct!(AudioObject);
pointable_struct!(Claim, content);
pointable_struct!(Collection, parts);
pointable_struct!(Comment);
pointable_struct!(CreativeWork);
pointable_struct!(Figure);
pointable_struct!(ImageObject);
pointable_struct!(MediaObject);
pointable_struct!(Periodical);
pointable_struct!(PublicationIssue);
pointable_struct!(PublicationVolume);
pointable_struct!(Review);
pointable_struct!(SoftwareApplication);
pointable_struct!(SoftwareSourceCode);
pointable_struct!(Table, caption, rows);
pointable_struct!(VideoObject);
<commit_msg>fix(Node pointers): Add `content` a pointeable field of `CreativeWork`<commit_after>use crate::{Pointable, Pointer, PointerMut};
use eyre::{bail, Result};
use node_address::Address;
use node_dispatch::dispatch_work;
use stencila_schema::*;

impl Pointable for CreativeWorkTypes {
    /// Resolve an [`Address`] into a node [`Pointer`].
    ///
    /// `CreativeWorkTypes` is one of the pointer variants so return a `Pointer::Work` if
    /// the address is empty. Otherwise dispatch to variant.
    fn resolve(&self, address: &mut Address) -> Result<Pointer> {
        match address.is_empty() {
            true => Ok(Pointer::Work(self)),
            false => dispatch_work!(self, resolve, address),
        }
    }
    fn resolve_mut(&mut self, address: &mut Address) -> Result<PointerMut> {
        match address.is_empty() {
            true => Ok(PointerMut::Work(self)),
            false => dispatch_work!(self, resolve_mut, address),
        }
    }

    /// Find a node based on its `id` and return a [`Pointer`] to it.
    ///
    /// Dispatch to variant and if it returns `Pointer::Some` then rewrite to `Pointer::Work`
    fn find(&self, id: &str) -> Pointer {
        match dispatch_work!(self, find, id) {
            Pointer::Some => Pointer::Work(self),
            _ => Pointer::None,
        }
    }
    fn find_mut(&mut self, id: &str) -> PointerMut {
        match dispatch_work!(self, find_mut, id) {
            PointerMut::Some => PointerMut::Work(self),
            _ => PointerMut::None,
        }
    }
}

// Implementations for `CreativeWork` structs. For descendants of these
// works to be pointable they must be within one of the listed properties e.g. `Article.content`.

pointable_struct!(Article, content);
pointable_struct!(AudioObject);
pointable_struct!(Claim, content);
pointable_struct!(Collection, parts);
pointable_struct!(Comment);
pointable_struct!(CreativeWork, content);
pointable_struct!(Figure);
pointable_struct!(ImageObject);
pointable_struct!(MediaObject);
pointable_struct!(Periodical);
pointable_struct!(PublicationIssue);
pointable_struct!(PublicationVolume);
pointable_struct!(Review);
pointable_struct!(SoftwareApplication);
pointable_struct!(SoftwareSourceCode);
pointable_struct!(Table, caption, rows);
pointable_struct!(VideoObject);

pointable_variants!(
    CreativeWorkContent,
    CreativeWorkContent::String,
    CreativeWorkContent::VecNode
);
<|endoftext|>


<commit_before>/*!
Utilities and other tidbits.
*/

// For testing, assert that structs have specified ABI size
#[cfg(test)]
macro_rules! assert_size_of {
	($size_of:expr, $ident:ident) => (assert_eq!($size_of, ::std::mem::size_of::<$ident>(),
		concat!("Unexpected sizeof(", stringify!($ident), ")")));
}

#[test]
#[should_panic]
fn assert_size_of() {
	struct Foo(i32);
	assert_size_of!(8, Foo);
}

macro_rules! offset_of {
	($ty:ty, $($field_bits:tt)*) => {
		unsafe { &(*(0 as *const $ty)).$($field_bits)* as *const _ as usize }
	}
}

mod c_str;
mod wide_str;
mod pod;
mod guid;

#[cfg(feature = "serde")]
pub(crate) mod serde_helper;

pub use self::c_str::CStr;
pub use self::wide_str::WideStr;
pub use self::pod::Pod;

/// Converts from a byte slice to a string.
pub trait FromBytes {
	/// Minimum size argument.
	const MIN_SIZE_OF: usize;
	/// Alignment argument.
	const ALIGN_OF: usize;
	/// Converts from a byte slice to a string.
	///
	/// # Safety
	///
	/// The given byte slice must have the minimum size and alignment as specified.
	unsafe fn from_bytes(bytes: &[u8]) -> Option<&Self>;
}

/// Splits a slice at the point defined by the callback.
#[inline]
pub(crate) fn split_f<T, F: FnMut(&T) -> bool>(slice: &[T], f: F) -> (&[T], &[T]) {
	let i = slice.iter().position(f).unwrap_or(slice.len());
	(&slice[..i], &slice[i..])
}

/// Reads an optionally nul-terminated string from byte buffer.
///
/// Returns the slice split before the nul byte and the whole slice if no nul byte is found.
///
/// Analog to the `strn*` family of C string functions.
///
/// # Examples
///
/// ```
/// use pelite::util::strn;
///
/// let buf: &[u8; 8] = b"STRING\0\0";
/// assert_eq!(strn(buf), b"STRING");
///
/// let buf: &[u8; 4] = b"FOUR";
/// assert_eq!(strn(buf), b"FOUR");
/// ```
#[inline]
pub fn strn(buf: &[u8]) -> &[u8] {
	split_f(buf, |&byte| byte == 0).0
}

/// Reads an optionally nul-terminated wide char string from buffer.
///
/// Returns the slice split before the nul word and the whole slice if no nul word is found.
///
/// Analog to the `wcsn*` family of C string functions.
///
/// # Examples
///
/// ```
/// use pelite::util::wstrn;
///
/// let buf: [u16; 8] = [83, 84, 82, 73, 78, 71, 0, 0];
/// assert_eq!(wstrn(&buf), &[83, 84, 82, 73, 78, 71]);
///
/// let buf: [u16; 4] = [70, 79, 85, 82];
/// assert_eq!(wstrn(&buf), &[70, 79, 85, 82]);
/// ```
#[inline]
pub fn wstrn(buf: &[u16]) -> &[u16] {
	split_f(buf, |&word| word == 0).0
}
<commit_msg>Add shannon entropy function (#114)<commit_after>/*!
Utilities and other tidbits.
*/

// For testing, assert that structs have specified ABI size
#[cfg(test)]
macro_rules! assert_size_of {
	($size_of:expr, $ident:ident) => (assert_eq!($size_of, ::std::mem::size_of::<$ident>(),
		concat!("Unexpected sizeof(", stringify!($ident), ")")));
}

#[test]
#[should_panic]
fn assert_size_of() {
	struct Foo(i32);
	assert_size_of!(8, Foo);
}

macro_rules! offset_of {
	($ty:ty, $($field_bits:tt)*) => {
		unsafe { &(*(0 as *const $ty)).$($field_bits)* as *const _ as usize }
	}
}

mod c_str;
mod wide_str;
mod pod;
mod guid;

#[cfg(feature = "serde")]
pub(crate) mod serde_helper;

pub use self::c_str::CStr;
pub use self::wide_str::WideStr;
pub use self::pod::Pod;

/// Converts from a byte slice to a string.
pub trait FromBytes {
	/// Minimum size argument.
	const MIN_SIZE_OF: usize;
	/// Alignment argument.
	const ALIGN_OF: usize;
	/// Converts from a byte slice to a string.
	///
	/// # Safety
	///
	/// The given byte slice must have the minimum size and alignment as specified.
	unsafe fn from_bytes(bytes: &[u8]) -> Option<&Self>;
}

/// Splits a slice at the point defined by the callback.
#[inline]
pub(crate) fn split_f<T, F: FnMut(&T) -> bool>(slice: &[T], f: F) -> (&[T], &[T]) {
	let i = slice.iter().position(f).unwrap_or(slice.len());
	(&slice[..i], &slice[i..])
}

/// Reads an optionally nul-terminated string from byte buffer.
///
/// Returns the slice split before the nul byte and the whole slice if no nul byte is found.
///
/// Analog to the `strn*` family of C string functions.
///
/// # Examples
///
/// ```
/// use pelite::util::strn;
///
/// let buf: &[u8; 8] = b"STRING\0\0";
/// assert_eq!(strn(buf), b"STRING");
///
/// let buf: &[u8; 4] = b"FOUR";
/// assert_eq!(strn(buf), b"FOUR");
/// ```
#[inline]
pub fn strn(buf: &[u8]) -> &[u8] {
	split_f(buf, |&byte| byte == 0).0
}

/// Reads an optionally nul-terminated wide char string from buffer.
///
/// Returns the slice split before the nul word and the whole slice if no nul word is found.
///
/// Analog to the `wcsn*` family of C string functions.
///
/// # Examples
///
/// ```
/// use pelite::util::wstrn;
///
/// let buf: [u16; 8] = [83, 84, 82, 73, 78, 71, 0, 0];
/// assert_eq!(wstrn(&buf), &[83, 84, 82, 73, 78, 71]);
///
/// let buf: [u16; 4] = [70, 79, 85, 82];
/// assert_eq!(wstrn(&buf), &[70, 79, 85, 82]);
/// ```
#[inline]
pub fn wstrn(buf: &[u16]) -> &[u16] {
	split_f(buf, |&word| word == 0).0
}

/// Bits of entropy represented in a given byte slice.
pub fn shannon_entropy(data: &[u8]) -> f64 {
	let mut map = [0usize; 256];

	for &byte in data {
		map[byte as usize] += 1;
	}

	let mut result = 0.0;
	let len = data.len() as f64;
	for &item in &map[..] {
		if item != 0 {
			let freq = item as f64 / len;
			result -= freq * freq.log2();
		}
	}

	result
}
<|endoftext|>


<commit_before>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use v2::Extras;

/// Extension specific data for `Asset`
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct AssetExtensions {
    #[serde(default)]
    _allow_extra_fields: (),
}

/// Metadata about the glTF asset
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Asset<E: Extras> {
    /// A copyright message suitable for display to credit the content creator
    pub copyright: Option<String>,

    /// Extension specific data
    #[serde(default)]
    pub extensions: AssetExtensions,

    /// Optional application specific data
    #[serde(default)]
    pub extras: <E as Extras>::Asset,

    /// Tool that generated this glTF model
    pub generator: Option<String>,

    /// The glTF version of this asset
    #[serde(default = "asset_version_default")]
    pub version: String,
}

fn asset_version_default() -> String {
    "2.0".to_string()
}
<commit_msg>Reorganised v2::asset<commit_after>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use v2::Extras;

/// Metadata about the glTF asset
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Asset<E: Extras> {
    /// A copyright message suitable for display to credit the content creator
    pub copyright: Option<String>,

    /// Extension specific data
    #[serde(default)]
    pub extensions: AssetExtensions,

    /// Optional application specific data
    #[serde(default)]
    pub extras: <E as Extras>::Asset,

    /// Tool that generated this glTF model
    pub generator: Option<String>,

    /// The glTF version of this asset
    #[serde(default = "asset_version_default")]
    pub version: String,
}

fn asset_version_default() -> String {
    "2.0".to_string()
}

/// Extension specific data for `Asset`
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct AssetExtensions {
    #[serde(default)]
    _allow_extra_fields: (),
}

<|endoftext|>


<commit_before>//! Patch of a VM, indicating different hard-fork of the Ethereum
//! block range.

/// Represents different block range context.
pub struct Patch {
    /// Limit of the call stack.
    pub callstack_limit: usize,
    /// Gas paid for extcode.
    pub gas_extcode: usize,
    /// Gas paid for BALANCE opcode.
    pub gas_balance: usize,
    /// Gas paid for SLOAD opcode.
    pub gas_sload: usize,
    /// Gas paid for SUICIDE opcode.
    pub gas_suicide: usize,
    /// Gas paid for SUICIDE opcode when it hits a new account.
    pub gas_suicide_new_account: usize,
    /// Gas paid for CALL opcode.
    pub gas_call: usize,
    /// Gas paid for EXP opcode for every byte.
    pub gas_expbyte: usize,
    /// Gas paid for a contract creation transaction.
    pub gas_transaction_create: usize,
    /// Whether to force code deposit even if it does not have enough
    /// gas.
    pub force_code_deposit: bool,
    /// Whether the EVM has DELEGATECALL opcode.
    pub has_delegate_call: bool,
    /// Whether to throw out of gas error when
    /// CALL/CALLCODE/DELEGATECALL requires more than maximum amount
    /// of gas.
    pub err_on_call_with_more_gas: bool,
    /// If true, only consume at maximum l64(after_gas) when
    /// CALL/CALLCODE/DELEGATECALL.
    pub call_l64_after_gas: bool,
}

/// Frontier patch.
pub static FRONTIER_PATCH: Patch = Patch {
    callstack_limit: 1024,
    gas_extcode: 20,
    gas_balance: 20,
    gas_sload: 50,
    gas_suicide: 0,
    gas_suicide_new_account: 0,
    gas_call: 40,
    gas_expbyte: 10,
    gas_transaction_create: 0,
    force_code_deposit: true,
    has_delegate_call: false,
    err_on_call_with_more_gas: true,
    call_create_l64_after_gas: false,
};

/// Homestead patch.
pub static HOMESTEAD_PATCH: Patch = Patch {
    callstack_limit: 1024,
    gas_extcode: 20,
    gas_balance: 20,
    gas_sload: 50,
    gas_suicide: 0,
    gas_suicide_new_account: 0,
    gas_call: 40,
    gas_expbyte: 10,
    gas_transaction_create: 32000,
    force_code_deposit: false,
    has_delegate_call: true,
    err_on_call_with_more_gas: true,
    call_create_l64_after_gas: false,
};

/// Patch specific for the `jsontests` crate.
pub static VMTEST_PATCH: Patch = Patch {
    callstack_limit: 2,
    gas_extcode: 20,
    gas_balance: 20,
    gas_sload: 50,
    gas_suicide: 0,
    gas_suicide_new_account: 0,
    gas_call: 40,
    gas_expbyte: 10,
    gas_transaction_create: 0,
    force_code_deposit: true,
    has_delegate_call: false,
    err_on_call_with_more_gas: true,
    call_create_l64_after_gas: false,
};

/// EIP150 patch.
pub static EIP150_PATCH: Patch = Patch {
    callstack_limit: 1024,
    gas_extcode: 700,
    gas_balance: 400,
    gas_sload: 200,
    gas_suicide: 5000,
    gas_suicide_new_account: 25000,
    gas_call: 700,
    gas_expbyte: 10,
    gas_transaction_create: 32000,
    force_code_deposit: false,
    has_delegate_call: true,
    err_on_call_with_more_gas: false,
    call_create_l64_after_gas: true,
};

/// EIP160 patch.
pub static EIP160_PATCH: Patch = Patch {
    callstack_limit: 1024,
    gas_extcode: 700,
    gas_balance: 400,
    gas_sload: 200,
    gas_suicide: 5000,
    gas_suicide_new_account: 25000,
    gas_call: 700,
    gas_expbyte: 50,
    gas_transaction_create: 32000,
    force_code_deposit: false,
    has_delegate_call: true,
    err_on_call_with_more_gas: false,
    call_create_l64_after_gas: true,
};
<commit_msg>Typo in patch<commit_after>//! Patch of a VM, indicating different hard-fork of the Ethereum
//! block range.

/// Represents different block range context.
pub struct Patch {
    /// Limit of the call stack.
    pub callstack_limit: usize,
    /// Gas paid for extcode.
    pub gas_extcode: usize,
    /// Gas paid for BALANCE opcode.
    pub gas_balance: usize,
    /// Gas paid for SLOAD opcode.
    pub gas_sload: usize,
    /// Gas paid for SUICIDE opcode.
    pub gas_suicide: usize,
    /// Gas paid for SUICIDE opcode when it hits a new account.
    pub gas_suicide_new_account: usize,
    /// Gas paid for CALL opcode.
    pub gas_call: usize,
    /// Gas paid for EXP opcode for every byte.
    pub gas_expbyte: usize,
    /// Gas paid for a contract creation transaction.
    pub gas_transaction_create: usize,
    /// Whether to force code deposit even if it does not have enough
    /// gas.
    pub force_code_deposit: bool,
    /// Whether the EVM has DELEGATECALL opcode.
    pub has_delegate_call: bool,
    /// Whether to throw out of gas error when
    /// CALL/CALLCODE/DELEGATECALL requires more than maximum amount
    /// of gas.
    pub err_on_call_with_more_gas: bool,
    /// If true, only consume at maximum l64(after_gas) when
    /// CALL/CALLCODE/DELEGATECALL.
    pub call_create_l64_after_gas: bool,
}

/// Frontier patch.
pub static FRONTIER_PATCH: Patch = Patch {
    callstack_limit: 1024,
    gas_extcode: 20,
    gas_balance: 20,
    gas_sload: 50,
    gas_suicide: 0,
    gas_suicide_new_account: 0,
    gas_call: 40,
    gas_expbyte: 10,
    gas_transaction_create: 0,
    force_code_deposit: true,
    has_delegate_call: false,
    err_on_call_with_more_gas: true,
    call_create_l64_after_gas: false,
};

/// Homestead patch.
pub static HOMESTEAD_PATCH: Patch = Patch {
    callstack_limit: 1024,
    gas_extcode: 20,
    gas_balance: 20,
    gas_sload: 50,
    gas_suicide: 0,
    gas_suicide_new_account: 0,
    gas_call: 40,
    gas_expbyte: 10,
    gas_transaction_create: 32000,
    force_code_deposit: false,
    has_delegate_call: true,
    err_on_call_with_more_gas: true,
    call_create_l64_after_gas: false,
};

/// Patch specific for the `jsontests` crate.
pub static VMTEST_PATCH: Patch = Patch {
    callstack_limit: 2,
    gas_extcode: 20,
    gas_balance: 20,
    gas_sload: 50,
    gas_suicide: 0,
    gas_suicide_new_account: 0,
    gas_call: 40,
    gas_expbyte: 10,
    gas_transaction_create: 0,
    force_code_deposit: true,
    has_delegate_call: false,
    err_on_call_with_more_gas: true,
    call_create_l64_after_gas: false,
};

/// EIP150 patch.
pub static EIP150_PATCH: Patch = Patch {
    callstack_limit: 1024,
    gas_extcode: 700,
    gas_balance: 400,
    gas_sload: 200,
    gas_suicide: 5000,
    gas_suicide_new_account: 25000,
    gas_call: 700,
    gas_expbyte: 10,
    gas_transaction_create: 32000,
    force_code_deposit: false,
    has_delegate_call: true,
    err_on_call_with_more_gas: false,
    call_create_l64_after_gas: true,
};

/// EIP160 patch.
pub static EIP160_PATCH: Patch = Patch {
    callstack_limit: 1024,
    gas_extcode: 700,
    gas_balance: 400,
    gas_sload: 200,
    gas_suicide: 5000,
    gas_suicide_new_account: 25000,
    gas_call: 700,
    gas_expbyte: 50,
    gas_transaction_create: 32000,
    force_code_deposit: false,
    has_delegate_call: true,
    err_on_call_with_more_gas: false,
    call_create_l64_after_gas: true,
};
<|endoftext|>


<commit_before>#![no_main]
#[macro_use] extern crate libfuzzer_sys;
extern crate image;

use std::io::Cursor;
use image::ImageResult;
use image::codecs::openexr::*;
use image::Rgba32FImage;
use std::io::Seek;
use std::io::BufRead;
use std::convert::TryFrom;
use image::ImageDecoder;
use image::ImageEncoder;

// "just dont panic"
fn roundtrip(bytes: &[u8]) -> ImageResult<()> {
    use std::io::Write;

    /// Read the file from the specified path into an `Rgba32FImage`.
    // TODO this method should probably already exist in the main image crate
    fn read_as_rgba_byte_image(read: impl BufRead + Seek) -> ImageResult<(u32,u32,Vec<u8>)> {
        let decoder = OpenExrDecoder::with_alpha_preference(read, Some(true))?;
        let (width, height) = decoder.dimensions();

        let mut buffer = vec![0; usize::try_from(decoder.total_bytes()).unwrap()];
        decoder.read_image(buffer.as_mut_slice())?;

        Ok((width, height, buffer))
    }

    /// Write an `Rgba32FImage`.
    /// Assumes the writer is buffered. In most cases,
    /// you should wrap your writer in a `BufWriter` for best performance.
    // TODO this method should probably already exist in the main image crate
    fn write_rgba_image(write: impl Write/* + Seek*/, (width, height, data): &(u32,u32,Vec<u8>)) -> ImageResult<()> {
        OpenExrEncoder::new(write).write_image(
            data.as_slice(), width, height,
            ColorType::Rgba32F
        )
    }

    let decoded_image = read_as_rgba_byte_image(Cursor::new(bytes))?;

    let mut bytes = Vec::with_capacity(bytes.len() + 20);
    write_rgba_image(Cursor::new(&mut bytes), &decoded_image)?;

    let redecoded_image = read_as_rgba_byte_image(Cursor::new(bytes))?;

    // if both images are valid, assert read/write consistency
    assert_eq!(decoded_image, redecoded_image, "image was valid but was not reproducible");
    Ok(())
}

fuzz_target!(|data: &[u8]| {
    let _img = roundtrip(data); // fixme not optimized away?
});
<commit_msg>fix fuzzer script compile errors<commit_after>#![no_main]
#[macro_use] extern crate libfuzzer_sys;
extern crate image;

use std::io::Cursor;
use image::ImageResult;
use image::codecs::openexr::*;
use std::io::Seek;
use std::io::BufRead;
use std::convert::TryFrom;
use image::ImageDecoder;
use image::ImageEncoder;
use image::ColorType;

// "just dont panic"
fn roundtrip(bytes: &[u8]) -> ImageResult<()> {
    use std::io::Write;

    /// Read the file from the specified path into an `Rgba32FImage`.
    // TODO this method should probably already exist in the main image crate
    fn read_as_rgba_byte_image(read: impl BufRead + Seek) -> ImageResult<(u32,u32,Vec<u8>)> {
        let decoder = OpenExrDecoder::with_alpha_preference(read, Some(true))?;
        let (width, height) = decoder.dimensions();

        let mut buffer = vec![0; usize::try_from(decoder.total_bytes()).unwrap()];
        decoder.read_image(buffer.as_mut_slice())?;

        Ok((width, height, buffer))
    }

    /// Write an `Rgba32FImage`.
    /// Assumes the writer is buffered. In most cases,
    /// you should wrap your writer in a `BufWriter` for best performance.
    // TODO this method should probably already exist in the main image crate
    fn write_rgba_image(write: impl Write/* + Seek*/, (width, height, data): &(u32,u32,Vec<u8>)) -> ImageResult<()> {
        OpenExrEncoder::new(write).write_image(
            data.as_slice(), *width, *height,
            ColorType::Rgba32F
        )
    }

    let decoded_image = read_as_rgba_byte_image(Cursor::new(bytes))?;

    let mut bytes = Vec::with_capacity(bytes.len() + 20);
    write_rgba_image(Cursor::new(&mut bytes), &decoded_image)?;

    let redecoded_image = read_as_rgba_byte_image(Cursor::new(bytes))?;

    // if both images are valid, assert read/write consistency
    assert_eq!(decoded_image, redecoded_image, "image was valid but was not reproducible");
    Ok(())
}

fuzz_target!(|data: &[u8]| {
    let _img = roundtrip(data); // fixme not optimized away?
});
<|endoftext|>


<commit_before>extern crate polydraw;

use std::cmp::max;

use polydraw::{Application, Renderer, RenderFrame};
use polydraw::geom::line::{LineSegment, LineSegmentIntersection};
use polydraw::geom::point::Point;
use polydraw::draw::{RGB, bresenham, hline, vline};

const HALF_RECT: i32 = 12;

#[derive (Debug)]
enum ActivePoint {
   Line1Point1,
   Line1Point2,
   Line2Point1,
   Line2Point2,
}

struct IntersectionRenderer {
   intersection_point: Option<Point<f64>>,
   intersection_overlap: Option<(Point<f64>, Point<f64>)>,

   l1: LineSegment<f64>,
   l2: LineSegment<f64>,

   mouse_x: i32,
   mouse_y: i32,

   width: u32,
   height: u32,

   line_color: RGB,
   default_color: RGB,
   hover_color: RGB,
   intersection_color: RGB,
   overlap_color: RGB,

   dragged_point: Option<ActivePoint>,
}

impl IntersectionRenderer {
   fn new() -> Self {
      IntersectionRenderer {
         intersection_point: None,
         intersection_overlap: None,

         l1: LineSegment::default(),
         l2: LineSegment::default(),

         mouse_x: -10000,
         mouse_y: -10000,

         width: 0,
         height: 0,

         line_color: RGB::new(93, 181, 241),
         default_color: RGB::new(127, 191, 63),
         hover_color: RGB::new(255, 255, 255),
         intersection_color: RGB::new(127, 127, 255),
         overlap_color: RGB::new(255, 191, 63),

         dragged_point: None,
      }
   }

   fn line_point_rect(&self, frame: &mut RenderFrame, x: i32, y: i32) {
      self.point_rect(frame, x, y, self.hit_test_color(x, y));
   }

   fn point_rect(&self, frame: &mut RenderFrame, x: i32, y: i32, color: &RGB) {
      let right_x = x + HALF_RECT;
      let left_x = x - HALF_RECT;
      let top_y = y + HALF_RECT;
      let bottom_y = y - HALF_RECT;

      hline(frame, left_x, right_x, top_y, color);
      hline(frame, left_x, right_x, bottom_y, color);

      vline(frame, left_x, bottom_y, top_y, color);
      vline(frame, right_x, bottom_y, top_y, color);
   }

   fn hit_test_color(&self, x: i32, y: i32) -> &RGB {
      if self.hit_test(x, y) {
         &self.hover_color
      } else {
         &self.default_color
      }
   }

   fn hit_test(&self, x: i32, y: i32) -> bool {
      let distance = max((x - self.mouse_x).abs(), (y - self.mouse_y).abs());
      distance <= HALF_RECT
   }

   fn active_point(&self) -> Option<ActivePoint> {
      let l1_p1_x = self.l1.x1() as i32;
      let l1_p1_y = self.l1.y1() as i32;

      if self.hit_test(l1_p1_x, l1_p1_y) {
         return Some(ActivePoint::Line1Point1);
      }

      let l1_p2_x = self.l1.x2() as i32;
      let l1_p2_y = self.l1.y2() as i32;

      if self.hit_test(l1_p2_x, l1_p2_y) {
         return Some(ActivePoint::Line1Point2);
      }

      let l2_p1_x = self.l2.x1() as i32;
      let l2_p1_y = self.l2.y1() as i32;

      if self.hit_test(l2_p1_x, l2_p1_y) {
         return Some(ActivePoint::Line2Point1);
      }

      let l2_p2_x = self.l2.x2() as i32;
      let l2_p2_y = self.l2.y2() as i32;

      if self.hit_test(l2_p2_x, l2_p2_y) {
         return Some(ActivePoint::Line2Point2);
      }

      None
   }

   fn recalc_intersection(&mut self) {
      let intersection = self.l1.intersect(&self.l2);
      match intersection {
         LineSegmentIntersection::Point(p) => {
            self.intersection_point = Some(p);
            self.intersection_overlap = None;
         },
         LineSegmentIntersection::Overlapping(p1, p2) => {
            self.intersection_point = None;
            self.intersection_overlap = Some((p1, p2));
         },
         _ => {
            self.intersection_point = None;
            self.intersection_overlap = None;
         }
      }
   }
}

impl Renderer for IntersectionRenderer {
   fn init(&mut self, width: u32, height: u32) {
      self.l1.update(
         100_f64, 120_f64,
         width as f64 - 100_f64, height as f64 - 100_f64
      );

      self.l2.update(
         140_f64, height as f64 - 90_f64,
         width as f64 - 140_f64, 100_f64
      );

      self.width = width;
      self.height = height;

      self.recalc_intersection();
   }

   fn resized(&mut self, width: u32, height: u32) {
      let dx: f64 = width as f64 - self.width as f64;
      let dy: f64 = height as f64 - self.height as f64;

      let l1_p1_x = self.l1.x1();
      let l1_p1_y = self.l1.y1();

      let l1_p2_x = self.l1.x2();
      let l1_p2_y = self.l1.y2();

      let l2_p1_x = self.l2.x1();
      let l2_p1_y = self.l2.y1();

      let l2_p2_x = self.l2.x2();
      let l2_p2_y = self.l2.y2();

      self.l1.update(l1_p1_x, l1_p1_y, l1_p2_x + dx, l1_p2_y + dy);

      self.l2.update(l2_p1_x, l2_p1_y + dy, l2_p2_x + dx, l2_p2_y);

      self.width = width;
      self.height = height;

      self.recalc_intersection();
   }

   fn mouse_moved(&mut self, x: i32, y: i32) {
      self.mouse_x = x;
      self.mouse_y = y;

      let x_f64 = x as f64;
      let y_f64 = y as f64;

      match self.dragged_point {
         Some(ActivePoint::Line1Point1) => {
            let x2 = self.l1.x2();
            let y2 = self.l1.y2();
            self.l1.update(x_f64, y_f64, x2, y2);
         },

         Some(ActivePoint::Line1Point2) => {
            let x1 = self.l1.x1();
            let y1 = self.l1.y1();
            self.l1.update(x1, y1, x_f64, y_f64);
         },

         Some(ActivePoint::Line2Point1) => {
            let x2 = self.l2.x2();
            let y2 = self.l2.y2();
            self.l2.update(x_f64, y_f64, x2, y2);
         },

         Some(ActivePoint::Line2Point2) => {
            let x1 = self.l2.x1();
            let y1 = self.l2.y1();
            self.l2.update(x1, y1, x_f64, y_f64);
         },

         _ => {
            return;
         }
      }

      self.recalc_intersection();
   }

   fn mouse_left_button_pressed(&mut self) {
      self.dragged_point = self.active_point();
   }

   fn mouse_left_button_released(&mut self) {
      self.dragged_point = None;
   }

   fn render(&mut self, frame: &mut RenderFrame) {
      frame.clear();

      let l1_p1_x = self.l1.x1() as i32;
      let l1_p1_y = self.l1.y1() as i32;

      let l1_p2_x = self.l1.x2() as i32;
      let l1_p2_y = self.l1.y2() as i32;

      let l2_p1_x = self.l2.x1() as i32;
      let l2_p1_y = self.l2.y1() as i32;

      let l2_p2_x = self.l2.x2() as i32;
      let l2_p2_y = self.l2.y2() as i32;

      bresenham(frame, l1_p1_x, l1_p1_y, l1_p2_x, l1_p2_y, &self.line_color);
      bresenham(frame, l2_p1_x, l2_p1_y, l2_p2_x, l2_p2_y, &self.line_color);

      match self.intersection_overlap {
         Some((ref p1, ref p2)) => {
            bresenham(frame, p1.x as i32, p1.y as i32, p2.x as i32, p2.y as i32, &self.overlap_color);
         },
         _ => {}
      }

      self.line_point_rect(frame, l1_p1_x, l1_p1_y);
      self.line_point_rect(frame, l1_p2_x, l1_p2_y);
      self.line_point_rect(frame, l2_p1_x, l2_p1_y);
      self.line_point_rect(frame, l2_p2_x, l2_p2_y);

      match self.intersection_point {
         Some(ref p) => {
            self.point_rect(frame, p.x as i32, p.y as i32, &self.intersection_color);
         },
         _ => {}
      }
   }
}

fn main() {
   let mut renderer = IntersectionRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Intersection")
      .run();
}
<commit_msg>Updating the intersection example to support the new geom module<commit_after>extern crate polydraw;

use std::cmp::max;

use polydraw::{Application, Renderer, RenderFrame};
use polydraw::geom::line::{LineSegment, LineSegmentIntersection};
use polydraw::geom::point::Point;
use polydraw::draw::{RGB, bresenham, hline, vline};

const HALF_RECT: i32 = 12;

#[derive (Debug)]
enum ActivePoint {
   Line1Point1,
   Line1Point2,
   Line2Point1,
   Line2Point2,
}

struct IntersectionRenderer {
   intersection_point: Option<Point>,
   intersection_overlap: Option<(Point, Point)>,

   l1: LineSegment,
   l2: LineSegment,

   mouse_x: i32,
   mouse_y: i32,

   width: u32,
   height: u32,

   line_color: RGB,
   default_color: RGB,
   hover_color: RGB,
   intersection_color: RGB,
   overlap_color: RGB,

   dragged_point: Option<ActivePoint>,
}

impl IntersectionRenderer {
   fn new() -> Self {
      IntersectionRenderer {
         intersection_point: None,
         intersection_overlap: None,

         l1: LineSegment::default(),
         l2: LineSegment::default(),

         mouse_x: -10000,
         mouse_y: -10000,

         width: 0,
         height: 0,

         line_color: RGB::new(93, 181, 241),
         default_color: RGB::new(127, 191, 63),
         hover_color: RGB::new(255, 255, 255),
         intersection_color: RGB::new(127, 127, 255),
         overlap_color: RGB::new(255, 191, 63),

         dragged_point: None,
      }
   }

   fn line_point_rect(&self, frame: &mut RenderFrame, x: i32, y: i32) {
      self.point_rect(frame, x, y, self.hit_test_color(x, y));
   }

   fn point_rect(&self, frame: &mut RenderFrame, x: i32, y: i32, color: &RGB) {
      let right_x = x + HALF_RECT;
      let left_x = x - HALF_RECT;
      let top_y = y + HALF_RECT;
      let bottom_y = y - HALF_RECT;

      hline(frame, left_x, right_x, top_y, color);
      hline(frame, left_x, right_x, bottom_y, color);

      vline(frame, left_x, bottom_y, top_y, color);
      vline(frame, right_x, bottom_y, top_y, color);
   }

   fn hit_test_color(&self, x: i32, y: i32) -> &RGB {
      if self.hit_test(x, y) {
         &self.hover_color
      } else {
         &self.default_color
      }
   }

   fn hit_test(&self, x: i32, y: i32) -> bool {
      let distance = max((x - self.mouse_x).abs(), (y - self.mouse_y).abs());
      distance <= HALF_RECT
   }

   fn active_point(&self) -> Option<ActivePoint> {
      let l1_p1_x = self.l1.x1() as i32;
      let l1_p1_y = self.l1.y1() as i32;

      if self.hit_test(l1_p1_x, l1_p1_y) {
         return Some(ActivePoint::Line1Point1);
      }

      let l1_p2_x = self.l1.x2() as i32;
      let l1_p2_y = self.l1.y2() as i32;

      if self.hit_test(l1_p2_x, l1_p2_y) {
         return Some(ActivePoint::Line1Point2);
      }

      let l2_p1_x = self.l2.x1() as i32;
      let l2_p1_y = self.l2.y1() as i32;

      if self.hit_test(l2_p1_x, l2_p1_y) {
         return Some(ActivePoint::Line2Point1);
      }

      let l2_p2_x = self.l2.x2() as i32;
      let l2_p2_y = self.l2.y2() as i32;

      if self.hit_test(l2_p2_x, l2_p2_y) {
         return Some(ActivePoint::Line2Point2);
      }

      None
   }

   fn recalc_intersection(&mut self) {
      let intersection = self.l1.intersect(&self.l2);
      match intersection {
         LineSegmentIntersection::Point(p) => {
            self.intersection_point = Some(p);
            self.intersection_overlap = None;
         },
         LineSegmentIntersection::Overlapping(p1, p2) => {
            self.intersection_point = None;
            self.intersection_overlap = Some((p1, p2));
         },
         _ => {
            self.intersection_point = None;
            self.intersection_overlap = None;
         }
      }
   }
}

impl Renderer for IntersectionRenderer {
   fn init(&mut self, width: u32, height: u32) {
      self.l1.update(
         100, 120,
         width as i64 - 100, height as i64 - 100
      );

      self.l2.update(
         140, height as i64 - 90,
         width as i64 - 140, 100
      );

      self.width = width;
      self.height = height;

      self.recalc_intersection();
   }

   fn resized(&mut self, width: u32, height: u32) {
      let dx: i64 = width as i64 - self.width as i64;
      let dy: i64 = height as i64 - self.height as i64;

      let l1_p1_x = self.l1.x1();
      let l1_p1_y = self.l1.y1();

      let l1_p2_x = self.l1.x2();
      let l1_p2_y = self.l1.y2();

      let l2_p1_x = self.l2.x1();
      let l2_p1_y = self.l2.y1();

      let l2_p2_x = self.l2.x2();
      let l2_p2_y = self.l2.y2();

      self.l1.update(l1_p1_x, l1_p1_y, l1_p2_x + dx, l1_p2_y + dy);

      self.l2.update(l2_p1_x, l2_p1_y + dy, l2_p2_x + dx, l2_p2_y);

      self.width = width;
      self.height = height;

      self.recalc_intersection();
   }

   fn mouse_moved(&mut self, x: i32, y: i32) {
      self.mouse_x = x;
      self.mouse_y = y;

      let x_i64 = x as i64;
      let y_i64 = y as i64;

      match self.dragged_point {
         Some(ActivePoint::Line1Point1) => {
            let x2 = self.l1.x2();
            let y2 = self.l1.y2();
            self.l1.update(x_i64, y_i64, x2, y2);
         },

         Some(ActivePoint::Line1Point2) => {
            let x1 = self.l1.x1();
            let y1 = self.l1.y1();
            self.l1.update(x1, y1, x_i64, y_i64);
         },

         Some(ActivePoint::Line2Point1) => {
            let x2 = self.l2.x2();
            let y2 = self.l2.y2();
            self.l2.update(x_i64, y_i64, x2, y2);
         },

         Some(ActivePoint::Line2Point2) => {
            let x1 = self.l2.x1();
            let y1 = self.l2.y1();
            self.l2.update(x1, y1, x_i64, y_i64);
         },

         _ => {
            return;
         }
      }

      self.recalc_intersection();
   }

   fn mouse_left_button_pressed(&mut self) {
      self.dragged_point = self.active_point();
   }

   fn mouse_left_button_released(&mut self) {
      self.dragged_point = None;
   }

   fn render(&mut self, frame: &mut RenderFrame) {
      frame.clear();

      let l1_p1_x = self.l1.x1() as i32;
      let l1_p1_y = self.l1.y1() as i32;

      let l1_p2_x = self.l1.x2() as i32;
      let l1_p2_y = self.l1.y2() as i32;

      let l2_p1_x = self.l2.x1() as i32;
      let l2_p1_y = self.l2.y1() as i32;

      let l2_p2_x = self.l2.x2() as i32;
      let l2_p2_y = self.l2.y2() as i32;

      bresenham(frame, l1_p1_x, l1_p1_y, l1_p2_x, l1_p2_y, &self.line_color);
      bresenham(frame, l2_p1_x, l2_p1_y, l2_p2_x, l2_p2_y, &self.line_color);

      match self.intersection_overlap {
         Some((ref p1, ref p2)) => {
            bresenham(frame, p1.x as i32, p1.y as i32, p2.x as i32, p2.y as i32, &self.overlap_color);
         },
         _ => {}
      }

      self.line_point_rect(frame, l1_p1_x, l1_p1_y);
      self.line_point_rect(frame, l1_p2_x, l1_p2_y);
      self.line_point_rect(frame, l2_p1_x, l2_p1_y);
      self.line_point_rect(frame, l2_p2_x, l2_p2_y);

      match self.intersection_point {
         Some(ref p) => {
            self.point_rect(frame, p.x as i32, p.y as i32, &self.intersection_color);
         },
         _ => {}
      }
   }
}

fn main() {
   let mut renderer = IntersectionRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Intersection")
      .run();
}
<|endoftext|>


<commit_before>extern crate llvm_sys as llvm;

use std::mem;

use llvm::core::*;
use llvm::execution_engine::*;
use llvm::target::*;

fn main() {
    unsafe {
        // Set up a context, module and builder in that context.
        let context = LLVMContextCreate();
        let module = LLVMModuleCreateWithName(b"sum\0".as_ptr() as *const _);
        let builder = LLVMCreateBuilderInContext(context);

        // get a type for sum function
        let i64t = LLVMInt64TypeInContext(context);
        let argts = [i64t, i64t, i64t];
        let function_type = LLVMFunctionType(
            i64t,
            mem::transmute(&argts[0]), // can't figure out how to make it *mut
            3,
            0);

        // add it to our module
        let function = LLVMAddFunction(
            module,
            b"sum\0".as_ptr() as *const _,
            function_type);

        // Create a basic block in the function and set our builder to generate
        // code in it.
        let bb = LLVMAppendBasicBlockInContext(
            context,
            function,
            b"entry\0".as_ptr() as *const _);

        LLVMPositionBuilderAtEnd(builder, bb);

        // get the functions arguments
        let x = LLVMGetParam(function, 0);
        let y = LLVMGetParam(function, 1);
        let z = LLVMGetParam(function, 2);

        let sum = LLVMBuildAdd(builder, x, y, b"sum.1\0".as_ptr() as *const _);
        let sum = LLVMBuildAdd(builder, sum, z, b"sum.2\0".as_ptr() as *const _);

        // Emit a `ret void` into the function
        LLVMBuildRet(builder, sum);

        // Dump the module as IR to stdout.
        LLVMDumpModule(module);

        // build an execution engine
        let mut ee = mem::uninitialized();
        let mut out = mem::zeroed();

        // who cares about error handing??
        LLVMLinkInMCJIT();
        LLVM_InitializeNativeTarget();
        LLVM_InitializeNativeAsmPrinter();
        LLVMCreateExecutionEngineForModule(&mut ee, module, &mut out);

        let addr = LLVMGetFunctionAddress(ee, b"sum\0".as_ptr() as *const _);

        let f: fn(u64, u64, u64) -> u64 = mem::transmute(addr);

        let x: u64 = 1;
        let y: u64 = 1;
        let z: u64 = 1;
        let res = f(x, y, z);

        println!("{} + {} + {} = {}", x, y, res);

        // Clean up. Values created in the context mostly get cleaned up there.
        LLVMDisposeExecutionEngine(ee);
        LLVMDisposeBuilder(builder);
        LLVMDisposeModule(module);
        LLVMContextDispose(context);
    }
}
<commit_msg>fixed typo in jit-function<commit_after>extern crate llvm_sys as llvm;

use std::mem;

use llvm::core::*;
use llvm::execution_engine::*;
use llvm::target::*;

fn main() {
    unsafe {
        // Set up a context, module and builder in that context.
        let context = LLVMContextCreate();
        let module = LLVMModuleCreateWithName(b"sum\0".as_ptr() as *const _);
        let builder = LLVMCreateBuilderInContext(context);

        // get a type for sum function
        let i64t = LLVMInt64TypeInContext(context);
        let argts = [i64t, i64t, i64t];
        let function_type = LLVMFunctionType(
            i64t,
            mem::transmute(&argts[0]), // can't figure out how to make it *mut
            3,
            0);

        // add it to our module
        let function = LLVMAddFunction(
            module,
            b"sum\0".as_ptr() as *const _,
            function_type);

        // Create a basic block in the function and set our builder to generate
        // code in it.
        let bb = LLVMAppendBasicBlockInContext(
            context,
            function,
            b"entry\0".as_ptr() as *const _);

        LLVMPositionBuilderAtEnd(builder, bb);

        // get the functions arguments
        let x = LLVMGetParam(function, 0);
        let y = LLVMGetParam(function, 1);
        let z = LLVMGetParam(function, 2);

        let sum = LLVMBuildAdd(builder, x, y, b"sum.1\0".as_ptr() as *const _);
        let sum = LLVMBuildAdd(builder, sum, z, b"sum.2\0".as_ptr() as *const _);

        // Emit a `ret void` into the function
        LLVMBuildRet(builder, sum);

        // Dump the module as IR to stdout.
        LLVMDumpModule(module);

        // build an execution engine
        let mut ee = mem::uninitialized();
        let mut out = mem::zeroed();

        // who cares about error handing??
        LLVMLinkInMCJIT();
        LLVM_InitializeNativeTarget();
        LLVM_InitializeNativeAsmPrinter();
        LLVMCreateExecutionEngineForModule(&mut ee, module, &mut out);

        let addr = LLVMGetFunctionAddress(ee, b"sum\0".as_ptr() as *const _);

        let f: fn(u64, u64, u64) -> u64 = mem::transmute(addr);

        let x: u64 = 1;
        let y: u64 = 1;
        let z: u64 = 1;
        let res = f(x, y, z);

        println!("{} + {} + {} = {}", x, y, z, res);

        // Clean up. Values created in the context mostly get cleaned up there.
        LLVMDisposeExecutionEngine(ee);
        LLVMDisposeBuilder(builder);
        LLVMDisposeModule(module);
        LLVMContextDispose(context);
    }
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate timely;
extern crate differential_dataflow;

use std::time::Instant;

use rand::{Rng, SeedableRng, StdRng};

use timely::dataflow::*;

use differential_dataflow::input::Input;
use differential_dataflow::Collection;
use differential_dataflow::operators::*;
use differential_dataflow::lattice::Lattice;

type Node = u32;
type Edge = (Node, Node);

fn main() {

    let nodes: u32 = std::env::args().nth(1).unwrap().parse().unwrap();
    let edges: u32 = std::env::args().nth(2).unwrap().parse().unwrap();
    let batch: u32 = std::env::args().nth(3).unwrap().parse().unwrap();
    let waves: u32 = std::env::args().nth(4).unwrap().parse().unwrap();

    println!("performing reachability on {} nodes, {} edges:", nodes, edges);

    // define a new computational scope, in which to run BFS
    timely::execute_from_args(std::env::args().skip(5), move |worker| {

        let timer = Instant::now();

        // define BFS dataflow; return handles to roots and edges inputs
        let (mut graph, mut roots, probe) = worker.dataflow(|scope| {
            let (root_input, roots) = scope.new_collection();
            let (edge_input, graph) = scope.new_collection();
            let probe = reach(&graph, &roots).probe();
            (edge_input, root_input, probe)
        });

        let seed: &[_] = &[1, 2, 3, 4];
        let mut rng1: StdRng = SeedableRng::from_seed(seed);    // rng for edge additions
        let mut rng2: StdRng = SeedableRng::from_seed(seed);    // rng for edge deletions

        if worker.index() == 0 {
            for _ in 0 .. edges {
                graph.insert((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)));
            }
        }

        roots.advance_to(1); roots.flush();
        graph.advance_to(1); graph.flush();
        worker.step_while(|| probe.less_than(graph.time()));

        if worker.index() == 0 {
            println!("stable; elapsed: {:?}", timer.elapsed());
        }

        for i in 0..1 {
            roots.insert(i);
            roots.advance_to(2 + i); roots.flush();
            graph.advance_to(2 + i); graph.flush();

            let timer = ::std::time::Instant::now();
            worker.step_while(|| probe.less_than(graph.time()));
            if worker.index() == 0 {
                println!("query; elapsed: {:?}", timer.elapsed());
            }
        }

        for _wave in 0..waves {
            let timer = ::std::time::Instant::now();
            let round = *graph.epoch();
            if worker.index() == 0 {
                for _ in 0..batch {
                    graph.insert((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)));
                    graph.remove((rng2.gen_range(0, nodes), rng2.gen_range(0, nodes)));
                }
            }
            roots.advance_to(round + 1); roots.flush();
            graph.advance_to(round + 1); graph.flush();

            worker.step_while(|| probe.less_than(graph.time()));

            if worker.index() == 0 {
                let elapsed = timer.elapsed();
                let nanos = elapsed.as_secs() * 1_000_000_000 + elapsed.subsec_nanos() as u64;
                // println!("wave {}: avg {:?}", wave, nanos / (batch as u32));
                println!("{}", (nanos as f64) / 1000000000.0f64);
            }
        }
    }).unwrap();
}

// returns pairs (n, s) indicating node n can be reached from a root in s steps.
fn reach<G: Scope>(edges: &Collection<G, Edge>, roots: &Collection<G, Node>) -> Collection<G, Node>
where G::Timestamp: Lattice+Ord {

    roots.iterate(|inner| {

        let edges = edges.enter(&inner.scope());
        let roots = roots.enter(&inner.scope());

        edges
            .semijoin(&inner)
            .map(|(_s,d)| d)
            .concat(&roots)
            .distinct()
     })
}
<commit_msg>more interactive<commit_after>extern crate rand;
extern crate timely;
extern crate differential_dataflow;

use std::time::Instant;

use rand::{Rng, SeedableRng, StdRng};

use timely::dataflow::*;

use differential_dataflow::input::InputSession;
use differential_dataflow::Collection;
use differential_dataflow::operators::*;
use differential_dataflow::lattice::Lattice;

type Node = u32;
type Edge = (Node, Node);

fn main() {

    let mut args = std::env::args().skip(1);
    let nodes: u32 = args.next().unwrap().parse().unwrap();
    let edges: u32 = args.next().unwrap().parse().unwrap();
    let batch: u32 = args.next().unwrap().parse().unwrap();
    let waves: u32 = args.next().unwrap().parse().unwrap();
    let inspect: bool = std::env::args().any(|x| x == "inspect");

    println!("performing reachability on {} nodes, {} edges:", nodes, edges);

    // define a new computational scope, in which to run BFS
    timely::execute_from_args(std::env::args(), move |worker| {

        let timer = Instant::now();

        let mut roots = InputSession::new();
        let mut graph = InputSession::new();
        let mut probe = ProbeHandle::new();

        // define BFS dataflow; return handles to roots and edges inputs
        worker.dataflow(|scope| {
            let roots = roots.to_collection(scope);
            let graph = graph.to_collection(scope);
            reach(&graph, &roots, inspect).probe_with(&mut probe);
        });

        let seed: &[_] = &[1, 2, 3, 4];
        let mut rng1: StdRng = SeedableRng::from_seed(seed);    // rng for edge additions
        let mut rng2: StdRng = SeedableRng::from_seed(seed);    // rng for edge deletions

        if worker.index() == 0 {
            for _ in 0 .. edges {
                graph.insert((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)));
            }
        }

        roots.advance_to(1); roots.flush();
        graph.advance_to(1); graph.flush();
        worker.step_while(|| probe.less_than(graph.time()));

        if worker.index() == 0 {
            println!("stable; elapsed: {:?}", timer.elapsed());
        }

        for i in 0..1 {
            roots.insert(i);
            roots.advance_to(2 + i); roots.flush();
            graph.advance_to(2 + i); graph.flush();

            let timer = ::std::time::Instant::now();
            worker.step_while(|| probe.less_than(graph.time()));
            if worker.index() == 0 {
                println!("query; elapsed: {:?}", timer.elapsed());
            }
        }

        for _wave in 0..waves {
            let timer = ::std::time::Instant::now();
            let round = *graph.epoch();
            if worker.index() == 0 {
                for _ in 0..batch {
                    graph.insert((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)));
                    graph.remove((rng2.gen_range(0, nodes), rng2.gen_range(0, nodes)));
                }
            }
            roots.advance_to(round + 1); roots.flush();
            graph.advance_to(round + 1); graph.flush();

            worker.step_while(|| probe.less_than(graph.time()));

            if worker.index() == 0 {
                let elapsed = timer.elapsed();
                let nanos = elapsed.as_secs() * 1_000_000_000 + elapsed.subsec_nanos() as u64;
                // println!("wave {}: avg {:?}", wave, nanos / (batch as u32));
                println!("{}", (nanos as f64) / 1000000000.0f64);
            }
        }
    }).unwrap();
}

// returns pairs (n, s) indicating node n can be reached from a root in s steps.
fn reach<G: Scope>(edges: &Collection<G, Edge>, roots: &Collection<G, Node>, inspect: bool) -> Collection<G, Node>
where G::Timestamp: Lattice+Ord {

    roots.iterate(|inner| {

        let edges = edges.enter(&inner.scope());
        let roots = roots.enter(&inner.scope());

        edges
            .semijoin(&inner)
            .map(|(_s,d)| d)
            .concat(&roots)
            .inspect(move |x| if inspect { println!("{:?}", x); })
            .distinct()
     })
}
<|endoftext|>