<commit_before>// Copyright 2013 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.

extern crate libc;

extern {
    fn rust_get_test_int() -> libc::intptr_t;
}

trait A {
    fn foo(&self) {
        unsafe {
            rust_get_test_int();
        }
    }
}

pub fn main() {
}
<commit_msg>Rollup merge of #23099 - brson:lint-cstack, r=alexcrichton<commit_after><|endoftext|>


<commit_before>use std::io;

use serde::de;

use nbt::serialize::{emit_next_header, raw};

use error::{Error, Result};

/// Decode an object from Named Binary Tag (NBT) format.
///
/// Note that only maps and structs can be decoded, because the NBT format does
/// not support bare types. Other types will return `Error::NoRootCompound`.
pub fn from_reader<R, T>(src: R) -> Result<T>
    where R: io::Read,
          T: de::Deserialize,
{
    let mut decoder = Decoder::new(src);
    de::Deserialize::deserialize(&mut decoder)
}

/// Decode objects from Named Binary Tag (NBT) format.
///
/// Note that only maps and structs can be decoded, because the NBT format does
/// not support bare types. Other types will return `Error::NoRootCompound`.
pub struct Decoder<R> {
    reader: R,
}

impl<R> Decoder<R> where R: io::Read {

    /// Create an NBT Decoder from a given `io::Read` source.
    pub fn new(src: R) -> Self {
        Decoder { reader: src }
    }
}

impl<'a, R: io::Read> de::Deserializer for &'a mut Decoder<R> {
    type Error = Error;

    fn deserialize<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        // The decoder cannot deserialize types by default. It can only handle
        // maps and structs.
        Err(Error::NoRootCompound)
    }

    fn deserialize_struct<V>(self, _name: &'static str,
                             _fields: &'static [&'static str], visitor: V)
                             -> Result<V::Value>
        where V: de::Visitor
    {
        self.deserialize_map(visitor)
    }

    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V)
                                  -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_unit()
    }

    /// Deserialize newtype structs by their underlying types.
    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V)
                                     -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_newtype_struct(self)
    }

    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        // Ignore the header (if there is one).
        let (tag, _) = try!(emit_next_header(&mut self.reader));

        match tag {
            0x0a => visitor.visit_map(MapDecoder::new(self)),
            _ => Err(Error::NoRootCompound)
        }
    }

    forward_to_deserialize! {
        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char
        str string bytes byte_buf unit seq seq_fixed_size
        tuple_struct struct_field tuple option enum
        ignored_any
    }
}

struct InnerDecoder<'a, R: io::Read + 'a> {
    outer: &'a mut Decoder<R>,
    tag: u8,
}

struct MapDecoder<'a, R: io::Read + 'a> {
    outer: &'a mut Decoder<R>,
    tag: Option<u8>,
}

impl<'a, R> MapDecoder<'a, R> where R: io::Read {

    fn new(outer: &'a mut Decoder<R>) -> Self {
        MapDecoder { outer: outer, tag: None }
    }
}

impl<'a, 'b: 'a, R: io::Read> de::Deserializer for &'b mut InnerDecoder<'a, R> {
    type Error = Error;

    fn deserialize<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        let ref mut outer = self.outer;

        match self.tag {
            0x01 => visitor.visit_i8(raw::read_bare_byte(&mut outer.reader)?),
            0x02 => visitor.visit_i16(raw::read_bare_short(&mut outer.reader)?),
            0x03 => visitor.visit_i32(raw::read_bare_int(&mut outer.reader)?),
            0x04 => visitor.visit_i64(raw::read_bare_long(&mut outer.reader)?),
            0x05 => visitor.visit_f32(raw::read_bare_float(&mut outer.reader)?),
            0x06 => visitor.visit_f64(raw::read_bare_double(&mut outer.reader)?),
            0x07 => unimplemented!(), // Byte array.
            0x08 => visitor.visit_string(raw::read_bare_string(&mut outer.reader)?),
            0x09 => unimplemented!(), // List.
            0x0a => visitor.visit_map(MapDecoder::new(outer)),
            0x0b => unimplemented!(), // Int array.
            _    => unimplemented!(),
        }
    }

    /// Deserialize bool values from a byte. Fail if that byte is not 0 or 1.
    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        match self.tag {
            0x01 => {
                let ref mut reader = self.outer.reader;
                let value = try!(raw::read_bare_byte(reader));
                match value {
                    0 => visitor.visit_bool(false),
                    1 => visitor.visit_bool(true),
                    // FIXME: Handle non-conforming bool values.
                    _ => unimplemented!(),
                }
            },
            // FIXME: Handle mismatched tags.
            _ => unimplemented!(),
        }
    }

    /// Interpret missing values as None.
    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_some(self)
    }

    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_unit()
    }

    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V)
                                  -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_unit()
    }

    /// Deserialize newtype structs by their underlying types.
    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V)
                                     -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_newtype_struct(self)
    }

    forward_to_deserialize! {
        u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char
        str string bytes byte_buf seq seq_fixed_size map
        tuple_struct struct struct_field tuple enum
        ignored_any
    }
}

impl<'a, R: io::Read + 'a> de::MapVisitor for MapDecoder<'a, R> {
    type Error = Error;

    fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
        where K: de::DeserializeSeed
    {
        let tag = try!(raw::read_bare_byte(&mut self.outer.reader));

        // NBT indicates the end of a compound type with a 0x00 tag.
        if tag == 0x00 {
            return Ok(None);
        }

        // Keep track of the tag so that we can decode the field correctly.
        self.tag = Some(tag as u8);

        // TODO: Enforce that keys must be String. This is a bit of a hack.
        let mut de = InnerDecoder { outer: self.outer, tag: 0x08 };

        Ok(Some(seed.deserialize(&mut de)?))
    }

    fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
        where V: de::DeserializeSeed
    {
        let mut de = match self.tag {
            Some(tag) => InnerDecoder { outer: self.outer, tag: tag },
            None => unimplemented!(),
        };
        Ok(seed.deserialize(&mut de)?)
    }
}
<commit_msg>Minor refactor of decoding module.<commit_after>use std::io;

use serde::de;

use nbt::serialize::{emit_next_header, raw};

use error::{Error, Result};

/// Decode an object from Named Binary Tag (NBT) format.
///
/// Note that only maps and structs can be decoded, because the NBT format does
/// not support bare types. Other types will return `Error::NoRootCompound`.
pub fn from_reader<R, T>(src: R) -> Result<T>
    where R: io::Read,
          T: de::Deserialize,
{
    let mut decoder = Decoder::new(src);
    de::Deserialize::deserialize(&mut decoder)
}

/// Decode objects from Named Binary Tag (NBT) format.
///
/// Note that only maps and structs can be decoded, because the NBT format does
/// not support bare types. Other types will return `Error::NoRootCompound`.
pub struct Decoder<R> {
    reader: R,
}

impl<R> Decoder<R> where R: io::Read {

    /// Create an NBT Decoder from a given `io::Read` source.
    pub fn new(src: R) -> Self {
        Decoder { reader: src }
    }
}

impl<'a, R: io::Read> de::Deserializer for &'a mut Decoder<R> {
    type Error = Error;

    fn deserialize<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        // The decoder cannot deserialize types by default. It can only handle
        // maps and structs.
        Err(Error::NoRootCompound)
    }

    fn deserialize_struct<V>(self, _name: &'static str,
                             _fields: &'static [&'static str], visitor: V)
                             -> Result<V::Value>
        where V: de::Visitor
    {
        self.deserialize_map(visitor)
    }

    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V)
                                  -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_unit()
    }

    /// Deserialize newtype structs by their underlying types.
    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V)
                                     -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_newtype_struct(self)
    }

    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        // Ignore the header (if there is one).
        let (tag, _) = try!(emit_next_header(&mut self.reader));

        match tag {
            0x0a => visitor.visit_map(MapDecoder::new(self)),
            _ => Err(Error::NoRootCompound)
        }
    }

    forward_to_deserialize! {
        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char
        str string bytes byte_buf unit seq seq_fixed_size
        tuple_struct struct_field tuple option enum
        ignored_any
    }
}

/// Decoder for map-like types.
struct MapDecoder<'a, R: io::Read + 'a> {
    outer: &'a mut Decoder<R>,
    tag: Option<u8>,
}

impl<'a, R> MapDecoder<'a, R> where R: io::Read {

    fn new(outer: &'a mut Decoder<R>) -> Self {
        MapDecoder { outer: outer, tag: None }
    }
}

impl<'a, R: io::Read + 'a> de::MapVisitor for MapDecoder<'a, R> {
    type Error = Error;

    fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
        where K: de::DeserializeSeed
    {
        let tag = try!(raw::read_bare_byte(&mut self.outer.reader));

        // NBT indicates the end of a compound type with a 0x00 tag.
        if tag == 0x00 {
            return Ok(None);
        }

        // Keep track of the tag so that we can decode the field correctly.
        self.tag = Some(tag as u8);

        // TODO: Enforce that keys must be String. This is a bit of a hack.
        let mut de = InnerDecoder { outer: self.outer, tag: 0x08 };

        Ok(Some(seed.deserialize(&mut de)?))
    }

    fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
        where V: de::DeserializeSeed
    {
        let mut de = match self.tag {
            Some(tag) => InnerDecoder { outer: self.outer, tag: tag },
            None => unimplemented!(),
        };
        Ok(seed.deserialize(&mut de)?)
    }
}

/// Private inner decoder, for decoding raw (i.e. non-Compound) types.
struct InnerDecoder<'a, R: io::Read + 'a> {
    outer: &'a mut Decoder<R>,
    tag: u8,
}

impl<'a, 'b: 'a, R: io::Read> de::Deserializer for &'b mut InnerDecoder<'a, R> {
    type Error = Error;

    fn deserialize<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        let ref mut outer = self.outer;

        match self.tag {
            0x01 => visitor.visit_i8(raw::read_bare_byte(&mut outer.reader)?),
            0x02 => visitor.visit_i16(raw::read_bare_short(&mut outer.reader)?),
            0x03 => visitor.visit_i32(raw::read_bare_int(&mut outer.reader)?),
            0x04 => visitor.visit_i64(raw::read_bare_long(&mut outer.reader)?),
            0x05 => visitor.visit_f32(raw::read_bare_float(&mut outer.reader)?),
            0x06 => visitor.visit_f64(raw::read_bare_double(&mut outer.reader)?),
            0x07 => unimplemented!(), // Byte array.
            0x08 => visitor.visit_string(raw::read_bare_string(&mut outer.reader)?),
            0x09 => unimplemented!(), // List.
            0x0a => visitor.visit_map(MapDecoder::new(outer)),
            0x0b => unimplemented!(), // Int array.
            _    => unimplemented!(),
        }
    }

    /// Deserialize bool values from a byte. Fail if that byte is not 0 or 1.
    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        match self.tag {
            0x01 => {
                let ref mut reader = self.outer.reader;
                let value = try!(raw::read_bare_byte(reader));
                match value {
                    0 => visitor.visit_bool(false),
                    1 => visitor.visit_bool(true),
                    // FIXME: Handle non-conforming bool values.
                    _ => unimplemented!(),
                }
            },
            // FIXME: Handle mismatched tags.
            _ => unimplemented!(),
        }
    }

    /// Interpret missing values as None.
    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_some(self)
    }

    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_unit()
    }

    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V)
                                  -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_unit()
    }

    /// Deserialize newtype structs by their underlying types.
    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V)
                                     -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_newtype_struct(self)
    }

    forward_to_deserialize! {
        u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char
        str string bytes byte_buf seq seq_fixed_size map
        tuple_struct struct struct_field tuple enum
        ignored_any
    }
}
<|endoftext|>


<commit_before>extern crate gitlab_api as gitlab;

use std::env;
#[macro_use]
extern crate log;
extern crate env_logger;

fn main() {
    env_logger::init().unwrap();
    info!("starting up");

    let hostname = match env::var("GITLAB_HOSTNAME") {
        Ok(val) => val,
        Err(_) => {
            let default = String::from("gitlab.com");
            println!("Please set environment variable 'GITLAB_HOSTNAME'. Using default '{}'.",
                     default);
            default
        }
    };

    let token = match env::var("GITLAB_TOKEN") {
        Ok(val) => val,
        Err(_) => {
            panic!("Please set environment variable 'GITLAB_TOKEN'. Take it from \
                    http://{}/profile/account",
                   hostname);
        }
    };

    let mut gl = gitlab::GitLab::new(&hostname, &token);
    gl.set_pagination(gitlab::Pagination {
        page: 1,
        per_page: 100,
    });
    println!("gl: {:?}", gl);

    let groups = gl.groups().list();
    println!("groups: {:?}", groups);

    let groups = gl.groups().details(gitlab::groups::ListingId::Id(2)).list();
    println!("groups: {:?}", groups);

    // let groups = gl.groups(gitlab::groups::Listing::new().skip_groups(vec![1, 2, 3]).clone());
    // println!("groups: {:?}", groups);
    //
    // let owned_groups = gl.owned_groups();
    // println!("owned_groups: {:?}", owned_groups);
}
<commit_msg>Change default group id to list.<commit_after>extern crate gitlab_api as gitlab;

use std::env;
#[macro_use]
extern crate log;
extern crate env_logger;

fn main() {
    env_logger::init().unwrap();
    info!("starting up");

    let hostname = match env::var("GITLAB_HOSTNAME") {
        Ok(val) => val,
        Err(_) => {
            let default = String::from("gitlab.com");
            println!("Please set environment variable 'GITLAB_HOSTNAME'. Using default '{}'.",
                     default);
            default
        }
    };

    let token = match env::var("GITLAB_TOKEN") {
        Ok(val) => val,
        Err(_) => {
            panic!("Please set environment variable 'GITLAB_TOKEN'. Take it from \
                    http://{}/profile/account",
                   hostname);
        }
    };

    let mut gl = gitlab::GitLab::new(&hostname, &token);
    gl.set_pagination(gitlab::Pagination {
        page: 1,
        per_page: 100,
    });
    println!("gl: {:?}", gl);

    let groups = gl.groups().list();
    println!("groups: {:?}", groups);

    let groups = gl.groups().details(gitlab::groups::ListingId::Id(21)).list();
    println!("groups: {:?}", groups);

    // let groups = gl.groups(gitlab::groups::Listing::new().skip_groups(vec![1, 2, 3]).clone());
    // println!("groups: {:?}", groups);
    //
    // let owned_groups = gl.owned_groups();
    // println!("owned_groups: {:?}", owned_groups);
}
<|endoftext|>


<commit_before>
extern crate gitlab_api as gitlab;

use std::env;
#[macro_use]
extern crate log;
extern crate env_logger;

fn main() {
    env_logger::init().unwrap();
    info!("starting up");

    let hostname = match env::var("GITLAB_HOSTNAME") {
        Ok(val) => val,
        Err(_) => {
            let default = String::from("gitlab.com");
            println!("Please set environment variable 'GITLAB_HOSTNAME'. Using default '{}'.",
                     default);
            default
        }
    };

    let token = match env::var("GITLAB_TOKEN") {
        Ok(val) => val,
        Err(_) => {
            panic!("Please set environment variable 'GITLAB_TOKEN'. Take it from \
                    http://{}/profile/account",
                   hostname);
        }
    };
    let mut gl = GitLab::new_https(&hostname, &token);
    gl.set_pagination(gitlab::Pagination {
        page: 1,
        per_page: 100,
    });
    println!("gl: {:?}", gl);

    // let groups = gl.groups(Default::default());
    let groups = gl.groups(gitlab::groups::Listing::new().skip_groups(vec![1, 2, 3]).clone());
    println!("groups: {:?}", groups);

    let owned_groups = gl.owned_groups();
    println!("owned_groups: {:?}", owned_groups);
}
<commit_msg>Fix compilation<commit_after>
extern crate gitlab_api as gitlab;

use std::env;
#[macro_use]
extern crate log;
extern crate env_logger;

fn main() {
    env_logger::init().unwrap();
    info!("starting up");

    let hostname = match env::var("GITLAB_HOSTNAME") {
        Ok(val) => val,
        Err(_) => {
            let default = String::from("gitlab.com");
            println!("Please set environment variable 'GITLAB_HOSTNAME'. Using default '{}'.",
                     default);
            default
        }
    };

    let token = match env::var("GITLAB_TOKEN") {
        Ok(val) => val,
        Err(_) => {
            panic!("Please set environment variable 'GITLAB_TOKEN'. Take it from \
                    http://{}/profile/account",
                   hostname);
        }
    };
    let mut gl = gitlab::GitLab::new_https(&hostname, &token);
    gl.set_pagination(gitlab::Pagination {
        page: 1,
        per_page: 100,
    });
    println!("gl: {:?}", gl);

    // let groups = gl.groups(Default::default());
    let groups = gl.groups(gitlab::groups::Listing::new().skip_groups(vec![1, 2, 3]).clone());
    println!("groups: {:?}", groups);

    let owned_groups = gl.owned_groups();
    println!("owned_groups: {:?}", owned_groups);
}
<|endoftext|>


<commit_before>use std::fmt;

use wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle};

use crate::{
    utils::{Logical, Point},
    wayland::Serial,
};

use super::{
    events::{ButtonEvent, MotionEvent},
    AxisFrame, PointerInnerHandle,
};

/// A trait to implement a pointer grab
///
/// In some context, it is necessary to temporarily change the behavior of the pointer. This is
/// typically known as a pointer grab. A typical example would be, during a drag'n'drop operation,
/// the underlying surfaces will no longer receive classic pointer event, but rather special events.
///
/// This trait is the interface to intercept regular pointer events and change them as needed, its
/// interface mimics the [`PointerHandle`](super::PointerHandle) interface.
///
/// Any interactions with [`PointerHandle`](super::PointerHandle)
/// should be done using [`PointerInnerHandle`], as handle is borrowed/locked before grab methods are called,
/// so calling methods on [`PointerHandle`](super::PointerHandle) would result in a deadlock.
///
/// If your logic decides that the grab should end, both [`PointerInnerHandle`]
/// and [`PointerHandle`](super::PointerHandle) have
/// a method to change it.
///
/// When your grab ends (either as you requested it or if it was forcefully cancelled by the server),
/// the struct implementing this trait will be dropped. As such you should put clean-up logic in the destructor,
/// rather than trying to guess when the grab will end.
pub trait PointerGrab<D>: Send + Sync {
    /// A motion was reported
    ///
    /// This method allows you attach additional behavior to a motion event, possibly altering it.
    /// You generally will want to invoke `PointerInnerHandle::motion()` as part of your processing. If you
    /// don't, the rest of the compositor will behave as if the motion event never occurred.
    ///
    /// Some grabs (such as drag'n'drop, shell resize and motion) unset the focus while they are active,
    /// this is achieved by just setting the focus to `None` when invoking `PointerInnerHandle::motion()`.
    fn motion(
        &mut self,
        data: &mut D,
        dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        event: &MotionEvent,
    );
    /// A button press was reported
    ///
    /// This method allows you attach additional behavior to a button event, possibly altering it.
    /// You generally will want to invoke `PointerInnerHandle::button()` as part of your processing. If you
    /// don't, the rest of the compositor will behave as if the button event never occurred.
    fn button(
        &mut self,
        data: &mut D,
        dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        event: &ButtonEvent,
    );
    /// An axis scroll was reported
    ///
    /// This method allows you attach additional behavior to an axis event, possibly altering it.
    /// You generally will want to invoke `PointerInnerHandle::axis()` as part of your processing. If you
    /// don't, the rest of the compositor will behave as if the axis event never occurred.
    fn axis(
        &mut self,
        data: &mut D,
        dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        details: AxisFrame,
    );
    /// The data about the event that started the grab.
    fn start_data(&self) -> &GrabStartData;
}

/// Data about the event that started the grab.
#[derive(Debug, Clone)]
pub struct GrabStartData {
    /// The focused surface and its location, if any, at the start of the grab.
    ///
    /// The location coordinates are in the global compositor space.
    pub focus: Option<(WlSurface, Point<i32, Logical>)>,
    /// The button that initiated the grab.
    pub button: u32,
    /// The location of the click that initiated the grab, in the global compositor space.
    pub location: Point<f64, Logical>,
}

pub(super) enum GrabStatus<D> {
    None,
    Active(Serial, Box<dyn PointerGrab<D>>),
    Borrowed,
}

// PointerGrab is a trait, so we have to impl Debug manually
impl<D> fmt::Debug for GrabStatus<D> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            GrabStatus::None => f.debug_tuple("GrabStatus::None").finish(),
            GrabStatus::Active(serial, _) => f.debug_tuple("GrabStatus::Active").field(&serial).finish(),
            GrabStatus::Borrowed => f.debug_tuple("GrabStatus::Borrowed").finish(),
        }
    }
}

// The default grab, the behavior when no particular grab is in progress
pub(super) struct DefaultGrab;

impl<D> PointerGrab<D> for DefaultGrab {
    fn motion(
        &mut self,
        _data: &mut D,
        _dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        event: &MotionEvent,
    ) {
        handle.motion(event.location, event.focus.clone(), event.serial, event.time);
    }

    fn button(
        &mut self,
        _data: &mut D,
        _dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        event: &ButtonEvent,
    ) {
        handle.button(event.button, event.state, event.serial, event.time);
        handle.set_grab(
            event.serial,
            event.time,
            ClickGrab {
                start_data: GrabStartData {
                    focus: handle.current_focus().cloned(),
                    button: event.button,
                    location: handle.current_location(),
                },
            },
        );
    }

    fn axis(
        &mut self,
        _data: &mut D,
        _dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        details: AxisFrame,
    ) {
        handle.axis(details);
    }

    fn start_data(&self) -> &GrabStartData {
        unreachable!()
    }
}

// A click grab, basic grab started when an user clicks a surface
// to maintain it focused until the user releases the click.
//
// In case the user maintains several simultaneous clicks, release
// the grab once all are released.
struct ClickGrab {
    start_data: GrabStartData,
}

impl<D> PointerGrab<D> for ClickGrab {
    fn motion(
        &mut self,
        _data: &mut D,
        _dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        event: &MotionEvent,
    ) {
        handle.motion(
            event.location,
            self.start_data.focus.clone(),
            event.serial,
            event.time,
        );
    }

    fn button(
        &mut self,
        _data: &mut D,
        _dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        event: &ButtonEvent,
    ) {
        handle.button(event.button, event.state, event.serial, event.time);
        if handle.current_pressed().is_empty() {
            // no more buttons are pressed, release the grab
            handle.unset_grab(event.serial, event.time);
        }
    }

    fn axis(
        &mut self,
        _data: &mut D,
        _dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        details: AxisFrame,
    ) {
        handle.axis(details);
    }

    fn start_data(&self) -> &GrabStartData {
        &self.start_data
    }
}
<commit_msg>seat: only set click grab on pressed<commit_after>use std::fmt;

use wayland_server::{
    protocol::{wl_pointer::ButtonState, wl_surface::WlSurface},
    DisplayHandle,
};

use crate::{
    utils::{Logical, Point},
    wayland::Serial,
};

use super::{
    events::{ButtonEvent, MotionEvent},
    AxisFrame, PointerInnerHandle,
};

/// A trait to implement a pointer grab
///
/// In some context, it is necessary to temporarily change the behavior of the pointer. This is
/// typically known as a pointer grab. A typical example would be, during a drag'n'drop operation,
/// the underlying surfaces will no longer receive classic pointer event, but rather special events.
///
/// This trait is the interface to intercept regular pointer events and change them as needed, its
/// interface mimics the [`PointerHandle`](super::PointerHandle) interface.
///
/// Any interactions with [`PointerHandle`](super::PointerHandle)
/// should be done using [`PointerInnerHandle`], as handle is borrowed/locked before grab methods are called,
/// so calling methods on [`PointerHandle`](super::PointerHandle) would result in a deadlock.
///
/// If your logic decides that the grab should end, both [`PointerInnerHandle`]
/// and [`PointerHandle`](super::PointerHandle) have
/// a method to change it.
///
/// When your grab ends (either as you requested it or if it was forcefully cancelled by the server),
/// the struct implementing this trait will be dropped. As such you should put clean-up logic in the destructor,
/// rather than trying to guess when the grab will end.
pub trait PointerGrab<D>: Send + Sync {
    /// A motion was reported
    ///
    /// This method allows you attach additional behavior to a motion event, possibly altering it.
    /// You generally will want to invoke `PointerInnerHandle::motion()` as part of your processing. If you
    /// don't, the rest of the compositor will behave as if the motion event never occurred.
    ///
    /// Some grabs (such as drag'n'drop, shell resize and motion) unset the focus while they are active,
    /// this is achieved by just setting the focus to `None` when invoking `PointerInnerHandle::motion()`.
    fn motion(
        &mut self,
        data: &mut D,
        dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        event: &MotionEvent,
    );
    /// A button press was reported
    ///
    /// This method allows you attach additional behavior to a button event, possibly altering it.
    /// You generally will want to invoke `PointerInnerHandle::button()` as part of your processing. If you
    /// don't, the rest of the compositor will behave as if the button event never occurred.
    fn button(
        &mut self,
        data: &mut D,
        dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        event: &ButtonEvent,
    );
    /// An axis scroll was reported
    ///
    /// This method allows you attach additional behavior to an axis event, possibly altering it.
    /// You generally will want to invoke `PointerInnerHandle::axis()` as part of your processing. If you
    /// don't, the rest of the compositor will behave as if the axis event never occurred.
    fn axis(
        &mut self,
        data: &mut D,
        dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        details: AxisFrame,
    );
    /// The data about the event that started the grab.
    fn start_data(&self) -> &GrabStartData;
}

/// Data about the event that started the grab.
#[derive(Debug, Clone)]
pub struct GrabStartData {
    /// The focused surface and its location, if any, at the start of the grab.
    ///
    /// The location coordinates are in the global compositor space.
    pub focus: Option<(WlSurface, Point<i32, Logical>)>,
    /// The button that initiated the grab.
    pub button: u32,
    /// The location of the click that initiated the grab, in the global compositor space.
    pub location: Point<f64, Logical>,
}

pub(super) enum GrabStatus<D> {
    None,
    Active(Serial, Box<dyn PointerGrab<D>>),
    Borrowed,
}

// PointerGrab is a trait, so we have to impl Debug manually
impl<D> fmt::Debug for GrabStatus<D> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            GrabStatus::None => f.debug_tuple("GrabStatus::None").finish(),
            GrabStatus::Active(serial, _) => f.debug_tuple("GrabStatus::Active").field(&serial).finish(),
            GrabStatus::Borrowed => f.debug_tuple("GrabStatus::Borrowed").finish(),
        }
    }
}

// The default grab, the behavior when no particular grab is in progress
pub(super) struct DefaultGrab;

impl<D> PointerGrab<D> for DefaultGrab {
    fn motion(
        &mut self,
        _data: &mut D,
        _dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        event: &MotionEvent,
    ) {
        handle.motion(event.location, event.focus.clone(), event.serial, event.time);
    }

    fn button(
        &mut self,
        _data: &mut D,
        _dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        event: &ButtonEvent,
    ) {
        handle.button(event.button, event.state, event.serial, event.time);
        if event.state == ButtonState::Pressed {
            handle.set_grab(
                event.serial,
                event.time,
                ClickGrab {
                    start_data: GrabStartData {
                        focus: handle.current_focus().cloned(),
                        button: event.button,
                        location: handle.current_location(),
                    },
                },
            );
        }
    }

    fn axis(
        &mut self,
        _data: &mut D,
        _dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        details: AxisFrame,
    ) {
        handle.axis(details);
    }

    fn start_data(&self) -> &GrabStartData {
        unreachable!()
    }
}

// A click grab, basic grab started when an user clicks a surface
// to maintain it focused until the user releases the click.
//
// In case the user maintains several simultaneous clicks, release
// the grab once all are released.
struct ClickGrab {
    start_data: GrabStartData,
}

impl<D> PointerGrab<D> for ClickGrab {
    fn motion(
        &mut self,
        _data: &mut D,
        _dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        event: &MotionEvent,
    ) {
        handle.motion(
            event.location,
            self.start_data.focus.clone(),
            event.serial,
            event.time,
        );
    }

    fn button(
        &mut self,
        _data: &mut D,
        _dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        event: &ButtonEvent,
    ) {
        handle.button(event.button, event.state, event.serial, event.time);
        if handle.current_pressed().is_empty() {
            // no more buttons are pressed, release the grab
            handle.unset_grab(event.serial, event.time);
        }
    }

    fn axis(
        &mut self,
        _data: &mut D,
        _dh: &DisplayHandle,
        handle: &mut PointerInnerHandle<'_, D>,
        details: AxisFrame,
    ) {
        handle.axis(details);
    }

    fn start_data(&self) -> &GrabStartData {
        &self.start_data
    }
}
<|endoftext|>


<commit_before>#![cfg(feature = "rustls")]

extern crate tls_rustls as rustls;

use std::{
    io::BufReader,
    sync::{
        atomic::{AtomicUsize, Ordering},
        Arc,
    },
};

use actix_http::HttpService;
use actix_http_test::test_server;
use actix_service::{map_config, pipeline_factory, ServiceFactoryExt};
use actix_utils::future::ok;
use actix_web::{dev::AppConfig, http::Version, web, App, HttpResponse};
use rustls::internal::pemfile::{certs, pkcs8_private_keys};
use rustls::{ClientConfig, NoClientAuth, ServerConfig};

fn tls_config() -> ServerConfig {
    let cert = rcgen::generate_simple_self_signed(vec!["localhost".to_owned()]).unwrap();
    let cert_file = cert.serialize_pem().unwrap();
    let key_file = cert.serialize_private_key_pem();

    let mut config = ServerConfig::new(NoClientAuth::new());
    let cert_file = &mut BufReader::new(cert_file.as_bytes());
    let key_file = &mut BufReader::new(key_file.as_bytes());

    let cert_chain = certs(cert_file).unwrap();
    let mut keys = pkcs8_private_keys(key_file).unwrap();
    config.set_single_cert(cert_chain, keys.remove(0)).unwrap();

    config
}

mod danger {
    pub struct NoCertificateVerification;

    impl rustls::ServerCertVerifier for NoCertificateVerification {
        fn verify_server_cert(
            &self,
            _roots: &rustls::RootCertStore,
            _presented_certs: &[rustls::Certificate],
            _dns_name: webpki::DNSNameRef<'_>,
            _ocsp: &[u8],
        ) -> Result<rustls::ServerCertVerified, rustls::TLSError> {
            Ok(rustls::ServerCertVerified::assertion())
        }
    }
}

#[actix_rt::test]
async fn test_connection_reuse_h2() {
    let num = Arc::new(AtomicUsize::new(0));
    let num2 = num.clone();

    let srv = test_server(move || {
        let num2 = num2.clone();
        pipeline_factory(move |io| {
            num2.fetch_add(1, Ordering::Relaxed);
            ok(io)
        })
        .and_then(
            HttpService::build()
                .h2(map_config(
                    App::new().service(web::resource("/").route(web::to(HttpResponse::Ok))),
                    |_| AppConfig::default(),
                ))
                .rustls(tls_config())
                .map_err(|_| ()),
        )
    })
    .await;

    // disable TLS verification
    let mut config = ClientConfig::new();
    let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
    config.set_protocols(&protos);
    config
        .dangerous()
        .set_certificate_verifier(Arc::new(danger::NoCertificateVerification));

    let client = awc::Client::builder()
        .connector(awc::Connector::new().rustls(Arc::new(config)))
        .finish();

    // req 1
    let request = client.get(srv.surl("/")).send();
    let response = request.await.unwrap();
    assert!(response.status().is_success());

    // req 2
    let req = client.post(srv.surl("/"));
    let response = req.send().await.unwrap();
    assert!(response.status().is_success());
    assert_eq!(response.version(), Version::HTTP_2);

    // one connection
    assert_eq!(num.load(Ordering::Relaxed), 1);
}
<commit_msg>missed one pipeline_factory<commit_after>#![cfg(feature = "rustls")]

extern crate tls_rustls as rustls;

use std::{
    io::BufReader,
    sync::{
        atomic::{AtomicUsize, Ordering},
        Arc,
    },
};

use actix_http::HttpService;
use actix_http_test::test_server;
use actix_service::{fn_service, map_config, ServiceFactoryExt};
use actix_utils::future::ok;
use actix_web::{dev::AppConfig, http::Version, web, App, HttpResponse};
use rustls::internal::pemfile::{certs, pkcs8_private_keys};
use rustls::{ClientConfig, NoClientAuth, ServerConfig};

fn tls_config() -> ServerConfig {
    let cert = rcgen::generate_simple_self_signed(vec!["localhost".to_owned()]).unwrap();
    let cert_file = cert.serialize_pem().unwrap();
    let key_file = cert.serialize_private_key_pem();

    let mut config = ServerConfig::new(NoClientAuth::new());
    let cert_file = &mut BufReader::new(cert_file.as_bytes());
    let key_file = &mut BufReader::new(key_file.as_bytes());

    let cert_chain = certs(cert_file).unwrap();
    let mut keys = pkcs8_private_keys(key_file).unwrap();
    config.set_single_cert(cert_chain, keys.remove(0)).unwrap();

    config
}

mod danger {
    pub struct NoCertificateVerification;

    impl rustls::ServerCertVerifier for NoCertificateVerification {
        fn verify_server_cert(
            &self,
            _roots: &rustls::RootCertStore,
            _presented_certs: &[rustls::Certificate],
            _dns_name: webpki::DNSNameRef<'_>,
            _ocsp: &[u8],
        ) -> Result<rustls::ServerCertVerified, rustls::TLSError> {
            Ok(rustls::ServerCertVerified::assertion())
        }
    }
}

#[actix_rt::test]
async fn test_connection_reuse_h2() {
    let num = Arc::new(AtomicUsize::new(0));
    let num2 = num.clone();

    let srv = test_server(move || {
        let num2 = num2.clone();
        fn_service(move |io| {
            num2.fetch_add(1, Ordering::Relaxed);
            ok(io)
        })
        .and_then(
            HttpService::build()
                .h2(map_config(
                    App::new().service(web::resource("/").route(web::to(HttpResponse::Ok))),
                    |_| AppConfig::default(),
                ))
                .rustls(tls_config())
                .map_err(|_| ()),
        )
    })
    .await;

    // disable TLS verification
    let mut config = ClientConfig::new();
    let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
    config.set_protocols(&protos);
    config
        .dangerous()
        .set_certificate_verifier(Arc::new(danger::NoCertificateVerification));

    let client = awc::Client::builder()
        .connector(awc::Connector::new().rustls(Arc::new(config)))
        .finish();

    // req 1
    let request = client.get(srv.surl("/")).send();
    let response = request.await.unwrap();
    assert!(response.status().is_success());

    // req 2
    let req = client.post(srv.surl("/"));
    let response = req.send().await.unwrap();
    assert!(response.status().is_success());
    assert_eq!(response.version(), Version::HTTP_2);

    // one connection
    assert_eq!(num.load(Ordering::Relaxed), 1);
}
<|endoftext|>


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

pub fn check(s: &str) -> bool {
    let mut cs = HashSet::new();
    for c in s.to_lowercase().chars().filter(|c| c.is_alphabetic()) {
        if cs.contains(&c) {
            return false;
        } else {
            cs.insert(c);
        }
    }
    true
}
<commit_msg>different rust answer<commit_after>use std::collections::HashSet;

pub fn check(s: &str) -> bool {
    let xs: Vec<_> = s.to_lowercase().chars().filter(|c| c.is_alphabetic()).collect();
    let ys: HashSet<_> = xs.iter().collect();
    xs.len() == ys.len()
}
<|endoftext|>


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

use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
use dom::bindings::error::Error::Type;
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties;
use dom::bluetoothdevice::BluetoothDevice;
use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic;
use dom::bluetoothuuid::{BluetoothCharacteristicUUID, BluetoothServiceUUID, BluetoothUUID};
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_thread::BluetoothMethodMsg;

// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattservice
#[dom_struct]
pub struct BluetoothRemoteGATTService {
    reflector_: Reflector,
    device: MutHeap<JS<BluetoothDevice>>,
    uuid: DOMString,
    isPrimary: bool,
    instanceID: String,
}

impl BluetoothRemoteGATTService {
    pub fn new_inherited(device: &BluetoothDevice,
                         uuid: DOMString,
                         isPrimary: bool,
                         instanceID: String)
                         -> BluetoothRemoteGATTService {
        BluetoothRemoteGATTService {
            reflector_: Reflector::new(),
            device: MutHeap::new(device),
            uuid: uuid,
            isPrimary: isPrimary,
            instanceID: instanceID,
        }
    }

    pub fn new(global: GlobalRef,
               device: &BluetoothDevice,
               uuid: DOMString,
               isPrimary: bool,
               instanceID: String)
               -> Root<BluetoothRemoteGATTService> {
        reflect_dom_object(box BluetoothRemoteGATTService::new_inherited(device,
                                                                         uuid,
                                                                         isPrimary,
                                                                         instanceID),
                           global,
                           BluetoothRemoteGATTServiceBinding::Wrap)
    }

    fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
        let global_root = self.global();
        let global_ref = global_root.r();
        global_ref.as_window().bluetooth_thread()
    }

    pub fn get_instance_id(&self) -> String {
        self.instanceID.clone()
    }
}

impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-device
    fn Device(&self) -> Root<BluetoothDevice> {
        self.device.get()
    }

    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-isprimary
    fn IsPrimary(&self) -> bool {
        self.isPrimary
    }

    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-uuid
    fn Uuid(&self) -> DOMString {
        self.uuid.clone()
    }

    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristic
    fn GetCharacteristic(&self,
                         characteristic: BluetoothCharacteristicUUID)
                         -> Fallible<Root<BluetoothRemoteGATTCharacteristic>> {
        let uuid = try!(BluetoothUUID::GetCharacteristic(self.global().r(), characteristic)).to_string();
        let (sender, receiver) = ipc::channel().unwrap();
        self.get_bluetooth_thread().send(
            BluetoothMethodMsg::GetCharacteristic(self.get_instance_id(), uuid, sender)).unwrap();
        let characteristic = receiver.recv().unwrap();
        match characteristic {
            Ok(characteristic) => {
                let properties = BluetoothCharacteristicProperties::new(self.global().r(),
                                                                        characteristic.broadcast,
                                                                        characteristic.read,
                                                                        characteristic.write_without_response,
                                                                        characteristic.write,
                                                                        characteristic.notify,
                                                                        characteristic.indicate,
                                                                        characteristic.authenticated_signed_writes,
                                                                        characteristic.reliable_write,
                                                                        characteristic.writable_auxiliaries);
                Ok(BluetoothRemoteGATTCharacteristic::new(self.global().r(),
                                                          self,
                                                          DOMString::from(characteristic.uuid),
                                                          &properties,
                                                          characteristic.instance_id))
            },
            Err(error) => {
                Err(Type(error))
            },
        }
    }

    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristics
    fn GetCharacteristics(&self,
                          characteristic: Option<BluetoothCharacteristicUUID>)
                          -> Fallible<Vec<Root<BluetoothRemoteGATTCharacteristic>>> {
        let mut uuid: Option<String> = None;
        if let Some(c) = characteristic {
            uuid = Some(try!(BluetoothUUID::GetCharacteristic(self.global().r(), c)).to_string())
        };
        let mut characteristics = vec!();
        let (sender, receiver) = ipc::channel().unwrap();
        self.get_bluetooth_thread().send(
            BluetoothMethodMsg::GetCharacteristics(self.get_instance_id(), uuid, sender)).unwrap();
        let characteristics_vec = receiver.recv().unwrap();
        match characteristics_vec {
            Ok(characteristic_vec) => {
                for characteristic in characteristic_vec {
                    let properties = BluetoothCharacteristicProperties::new(self.global().r(),
                                                                            characteristic.broadcast,
                                                                            characteristic.read,
                                                                            characteristic.write_without_response,
                                                                            characteristic.write,
                                                                            characteristic.notify,
                                                                            characteristic.indicate,
                                                                            characteristic.authenticated_signed_writes,
                                                                            characteristic.reliable_write,
                                                                            characteristic.writable_auxiliaries);
                    characteristics.push(BluetoothRemoteGATTCharacteristic::new(self.global().r(),
                                                                                self,
                                                                                DOMString::from(characteristic.uuid),
                                                                                &properties,
                                                                                characteristic.instance_id));
                }
                Ok(characteristics)
            },
            Err(error) => {
                Err(Type(error))
            },
        }
    }

    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservice
    fn GetIncludedService(&self,
                          service: BluetoothServiceUUID)
                          -> Fallible<Root<BluetoothRemoteGATTService>> {
        let uuid = try!(BluetoothUUID::GetService(self.global().r(), service)).to_string();
        let (sender, receiver) = ipc::channel().unwrap();
        self.get_bluetooth_thread().send(
            BluetoothMethodMsg::GetIncludedService(self.get_instance_id(),
                                                   uuid,
                                                   sender)).unwrap();
        let service = receiver.recv().unwrap();
        match service {
            Ok(service) => {
                Ok(BluetoothRemoteGATTService::new(self.global().r(),
                                                   &self.device.get(),
                                                   DOMString::from(service.uuid),
                                                   service.is_primary,
                                                   service.instance_id))
            },
            Err(error) => {
                Err(Type(error))
            },
        }
    }

    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservices
    fn GetIncludedServices(&self,
                          service: Option<BluetoothServiceUUID>)
                          -> Fallible<Vec<Root<BluetoothRemoteGATTService>>> {
        let mut uuid: Option<String> = None;
        if let Some(s) = service {
            uuid = Some(try!(BluetoothUUID::GetService(self.global().r(), s)).to_string())
        };
        let (sender, receiver) = ipc::channel().unwrap();
        self.get_bluetooth_thread().send(
            BluetoothMethodMsg::GetIncludedServices(self.get_instance_id(),
                                                    uuid,
                                                    sender)).unwrap();
        let services_vec = receiver.recv().unwrap();
        match services_vec {
            Ok(service_vec) => {
                Ok(service_vec.into_iter()
                              .map(|service| BluetoothRemoteGATTService::new(self.global().r(),
                                                                             &self.device.get(),
                                                                             DOMString::from(service.uuid),
                                                                             service.is_primary,
                                                                             service.instance_id))
                              .collect())
            },
            Err(error) => {
                Err(Type(error))
            },
        }
    }
}
<commit_msg>Auto merge of #11455 - ConnorGBrewster:fix_warning, r=emilio<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
use dom::bindings::error::Error::Type;
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties;
use dom::bluetoothdevice::BluetoothDevice;
use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic;
use dom::bluetoothuuid::{BluetoothCharacteristicUUID, BluetoothServiceUUID, BluetoothUUID};
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_thread::BluetoothMethodMsg;

// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattservice
#[dom_struct]
pub struct BluetoothRemoteGATTService {
    reflector_: Reflector,
    device: MutHeap<JS<BluetoothDevice>>,
    uuid: DOMString,
    isPrimary: bool,
    instanceID: String,
}

impl BluetoothRemoteGATTService {
    pub fn new_inherited(device: &BluetoothDevice,
                         uuid: DOMString,
                         isPrimary: bool,
                         instanceID: String)
                         -> BluetoothRemoteGATTService {
        BluetoothRemoteGATTService {
            reflector_: Reflector::new(),
            device: MutHeap::new(device),
            uuid: uuid,
            isPrimary: isPrimary,
            instanceID: instanceID,
        }
    }

    pub fn new(global: GlobalRef,
               device: &BluetoothDevice,
               uuid: DOMString,
               isPrimary: bool,
               instanceID: String)
               -> Root<BluetoothRemoteGATTService> {
        reflect_dom_object(box BluetoothRemoteGATTService::new_inherited(device,
                                                                         uuid,
                                                                         isPrimary,
                                                                         instanceID),
                           global,
                           BluetoothRemoteGATTServiceBinding::Wrap)
    }

    fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
        let global_root = self.global();
        let global_ref = global_root.r();
        global_ref.as_window().bluetooth_thread()
    }

    pub fn get_instance_id(&self) -> String {
        self.instanceID.clone()
    }
}

impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-device
    fn Device(&self) -> Root<BluetoothDevice> {
        self.device.get()
    }

    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-isprimary
    fn IsPrimary(&self) -> bool {
        self.isPrimary
    }

    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-uuid
    fn Uuid(&self) -> DOMString {
        self.uuid.clone()
    }

    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristic
    fn GetCharacteristic(&self,
                         characteristic: BluetoothCharacteristicUUID)
                         -> Fallible<Root<BluetoothRemoteGATTCharacteristic>> {
        let uuid = try!(BluetoothUUID::GetCharacteristic(self.global().r(), characteristic)).to_string();
        let (sender, receiver) = ipc::channel().unwrap();
        self.get_bluetooth_thread().send(
            BluetoothMethodMsg::GetCharacteristic(self.get_instance_id(), uuid, sender)).unwrap();
        let characteristic = receiver.recv().unwrap();
        match characteristic {
            Ok(characteristic) => {
                let properties = BluetoothCharacteristicProperties::new(self.global().r(),
                                                                        characteristic.broadcast,
                                                                        characteristic.read,
                                                                        characteristic.write_without_response,
                                                                        characteristic.write,
                                                                        characteristic.notify,
                                                                        characteristic.indicate,
                                                                        characteristic.authenticated_signed_writes,
                                                                        characteristic.reliable_write,
                                                                        characteristic.writable_auxiliaries);
                Ok(BluetoothRemoteGATTCharacteristic::new(self.global().r(),
                                                          self,
                                                          DOMString::from(characteristic.uuid),
                                                          &properties,
                                                          characteristic.instance_id))
            },
            Err(error) => {
                Err(Type(error))
            },
        }
    }

    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristics
    fn GetCharacteristics(&self,
                          characteristic: Option<BluetoothCharacteristicUUID>)
                          -> Fallible<Vec<Root<BluetoothRemoteGATTCharacteristic>>> {
        let mut uuid: Option<String> = None;
        if let Some(c) = characteristic {
            uuid = Some(try!(BluetoothUUID::GetCharacteristic(self.global().r(), c)).to_string())
        };
        let mut characteristics = vec!();
        let (sender, receiver) = ipc::channel().unwrap();
        self.get_bluetooth_thread().send(
            BluetoothMethodMsg::GetCharacteristics(self.get_instance_id(), uuid, sender)).unwrap();
        let characteristics_vec = receiver.recv().unwrap();
        match characteristics_vec {
            Ok(characteristic_vec) => {
                for characteristic in characteristic_vec {
                    let properties = BluetoothCharacteristicProperties::new(self.global().r(),
                                                                            characteristic.broadcast,
                                                                            characteristic.read,
                                                                            characteristic.write_without_response,
                                                                            characteristic.write,
                                                                            characteristic.notify,
                                                                            characteristic.indicate,
                                                                            characteristic.authenticated_signed_writes,
                                                                            characteristic.reliable_write,
                                                                            characteristic.writable_auxiliaries);
                    characteristics.push(BluetoothRemoteGATTCharacteristic::new(self.global().r(),
                                                                                self,
                                                                                DOMString::from(characteristic.uuid),
                                                                                &properties,
                                                                                characteristic.instance_id));
                }
                Ok(characteristics)
            },
            Err(error) => {
                Err(Type(error))
            },
        }
    }

    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservice
    fn GetIncludedService(&self,
                          service: BluetoothServiceUUID)
                          -> Fallible<Root<BluetoothRemoteGATTService>> {
        let uuid = try!(BluetoothUUID::GetService(self.global().r(), service)).to_string();
        let (sender, receiver) = ipc::channel().unwrap();
        self.get_bluetooth_thread().send(
            BluetoothMethodMsg::GetIncludedService(self.get_instance_id(),
                                                   uuid,
                                                   sender)).unwrap();
        let service = receiver.recv().unwrap();
        match service {
            Ok(service) => {
                Ok(BluetoothRemoteGATTService::new(self.global().r(),
                                                   &self.device.get(),
                                                   DOMString::from(service.uuid),
                                                   service.is_primary,
                                                   service.instance_id))
            },
            Err(error) => {
                Err(Type(error))
            },
        }
    }

    // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservices
    fn GetIncludedServices(&self,
                          service: Option<BluetoothServiceUUID>)
                          -> Fallible<Vec<Root<BluetoothRemoteGATTService>>> {
        let mut uuid: Option<String> = None;
        if let Some(s) = service {
            uuid = Some(try!(BluetoothUUID::GetService(self.global().r(), s)).to_string())
        };
        let (sender, receiver) = ipc::channel().unwrap();
        self.get_bluetooth_thread().send(
            BluetoothMethodMsg::GetIncludedServices(self.get_instance_id(),
                                                    uuid,
                                                    sender)).unwrap();
        let services_vec = receiver.recv().unwrap();
        match services_vec {
            Ok(service_vec) => {
                Ok(service_vec.into_iter()
                              .map(|service| BluetoothRemoteGATTService::new(self.global().r(),
                                                                             &self.device.get(),
                                                                             DOMString::from(service.uuid),
                                                                             service.is_primary,
                                                                             service.instance_id))
                              .collect())
            },
            Err(error) => {
                Err(Type(error))
            },
        }
    }
}
<|endoftext|>


<commit_before>//! Library for manipulating Pokémon Gen3 (Fire Red/Leaf Green, Ruby/Emerald/Sapphire) save data.

#[macro_use]
extern crate log;
extern crate byteorder;
extern crate rgen3_string;

mod util {
    mod lower_upper;
    pub use self::lower_upper::LowerUpper;
}
mod rw;

use crate::util::LowerUpper;
use std::error::Error;
use std::fs::File;
use std::path::Path;
use std::{fmt, io};

const UNKNOWN_SAVE_FOOTER_SIZE: usize = 16384;

/// Pokémon Gen3 save data.
pub struct Save {
    blocks: [SaveBlock; 2],
    unknown: [u8; UNKNOWN_SAVE_FOOTER_SIZE],
    most_recent_index: usize,
}

impl fmt::Debug for Save {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.blocks.fmt(f)
    }
}

impl Save {
    /// Load the save data from a file at the provided path.
    pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Self, Box<Error>> {
        let mut file = File::open(path)?;
        Save::read(&mut file)
    }
    /// Save the save data to a file at the provided path.
    pub fn save_to_file<P: AsRef<Path>>(&mut self, path: P) -> Result<(), io::Error> {
        let mut file = File::create(path)?;
        self.write(&mut file)
    }
    pub fn sections(&mut self) -> SaveSections {
        let block = &mut self.blocks[self.most_recent_index];
        let sections = &mut block.sections[..];
        let team_and_items = if let SectionData::TeamAndItems(ref mut data) =
            sections[block.team_and_items_index].data
        {
            data
        } else {
            panic!("Unexpected section data. Expected TeamAndItems");
        };
        let trainer_info = if let SectionData::TrainerInfo(ref mut data) =
            sections[block.trainer_info_index].data
        {
            data
        } else {
            panic!("Unexpected section data. Expected TrainerInfo");
        };
        SaveSections {
            team: &mut team_and_items.team,
            trainer: trainer_info,
            pc_boxes: &mut block.pokemon_storage.boxes,
        }
    }
}

pub struct SaveSections<'a> {
    pub trainer: &'a mut TrainerInfo,
    pub team: &'a mut Vec<Pokemon>,
    pub pc_boxes: &'a mut [PokeBox],
}

#[derive(Debug)]
struct SaveBlock {
    sections: Vec<Section>,
    trainer_info_index: usize,
    team_and_items_index: usize,
    // Does not exist yet, meaning the game has only been saved once, and this
    // block hasn't been written over yet.
    nonexistent: bool,
    pokemon_storage: PokemonStorage,
    box_indexes: [usize; N_BOXES],
}

#[allow(clippy::large_enum_variant)]
enum SectionData {
    Unimplemented {
        raw: [u8; DATA_SIZE as usize],
        id: u16,
        cksum: u16,
    },
    TrainerInfo(TrainerInfo),
    TeamAndItems(TeamAndItems),
    PcBuffer(PcBuffer),
}

impl fmt::Debug for SectionData {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            SectionData::Unimplemented { .. } => f.write_str("<Unimplemented section>"),
            SectionData::TrainerInfo(ref data) => data.fmt(f),
            SectionData::TeamAndItems(ref data) => data.fmt(f),
            SectionData::PcBuffer(ref data) => data.fmt(f),
        }
    }
}

#[derive(Debug)]
struct Section {
    data: SectionData,
    unknown_1: u32,
    save_idx: u32,
}

const DATA_SIZE: i64 = 0xFF4;

#[repr(u8)]
#[derive(Clone, Copy, Debug)]
enum Gender {
    Male = 0,
    Female = 1,
}

impl fmt::Display for Gender {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str = match *self {
            Gender::Male => "Male",
            Gender::Female => "Female",
        };
        f.write_str(str)
    }
}

#[derive(Debug)]
struct Time {
    hours: u16,
    minutes: u8,
    seconds: u8,
    frames: u8,
}

const TRAINER_INFO_UNKNOWN_3_SIZE: usize = 0x00AC - (0x0013 + 3);
const RS_EM_PLAYERINFO_TRAILING_DATA_SIZE: usize = DATA_SIZE as usize - (0x0AC + 4);
const FRLG_PLAYERINFO_UNKNOWN_CHUNK_SIZE: usize = 0x0AF8 - (0x00AC + 4);
const FRLG_PLAYERINFO_TRAILING_DATA_SIZE: usize = DATA_SIZE as usize - (0x0AF8 + 4);

enum Game {
    RubyOrSapphire {
        trailing_data: [u8; RS_EM_PLAYERINFO_TRAILING_DATA_SIZE],
    },
    FireredOrLeafgreen {
        unknown: [u8; FRLG_PLAYERINFO_UNKNOWN_CHUNK_SIZE],
        security_key: u32,
        trailing_data: [u8; FRLG_PLAYERINFO_TRAILING_DATA_SIZE],
    },
    Emerald {
        security_key: u32,
        trailing_data: [u8; RS_EM_PLAYERINFO_TRAILING_DATA_SIZE],
    },
}

#[derive(Clone, Copy)]
enum GameType {
    RubyOrSapphire,
    FireredOrLeafgreen,
    Emerald,
}

impl<'a> From<&'a Game> for GameType {
    fn from(src: &Game) -> Self {
        match *src {
            Game::RubyOrSapphire { .. } => GameType::RubyOrSapphire,
            Game::FireredOrLeafgreen { .. } => GameType::FireredOrLeafgreen,
            Game::Emerald { .. } => GameType::Emerald,
        }
    }
}

impl fmt::Debug for Game {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Game::RubyOrSapphire { .. } => write!(f, "Ruby/Sapphire"),
            Game::FireredOrLeafgreen { security_key, .. } => {
                write!(f, "Fire Red/Leaf Green (security key: {})", security_key)
            }
            Game::Emerald { security_key, .. } => {
                write!(f, "Emerald (security key: {})", security_key)
            }
        }
    }
}

const TRAINER_NAME_LEN: usize = 7;

pub struct TrainerInfo {
    pub name: TrainerName,
    unknown_1: u8,
    gender: Gender,
    unknown_2: u8,
    public_id: u16,
    secret_id: u16,
    time_played: Time,
    options_data: [u8; 3],
    unknown_3: [u8; TRAINER_INFO_UNKNOWN_3_SIZE],
    game: Game,
}

impl TrainerInfo {
    pub fn full_id(&self) -> u32 {
        u32::merge(self.public_id, self.secret_id)
    }
}

impl fmt::Debug for TrainerInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("== Trainer Info ==\n")?;
        writeln!(f, "name: {:?}", self.name)?;
        writeln!(f, "gender: {:?}", self.gender)?;
        writeln!(
            f,
            "id: public({:?}) secret({:?}) combined({:?})",
            self.public_id,
            self.secret_id,
            u32::merge(self.public_id, self.secret_id)
        )?;
        writeln!(f, "Time played: {:?}", self.time_played)?;
        writeln!(f, "GAME ID: {:?}", self.game)
    }
}

const EM_RU_SA_TEAMANDITEMS_UNK_LEN: usize = 0x0234;
const FR_LG_TEAMANDITEMS_UNK_LEN: usize = 0x0034;
const TEAMANDITEMS_POKE_LEN: usize = 600;
const EM_RU_SA_TEAMANDITEMS_REM_LEN: usize =
    DATA_SIZE as usize - (EM_RU_SA_TEAMANDITEMS_UNK_LEN + TEAMANDITEMS_POKE_LEN + 4);
const FR_LG_TEAMANDITEMS_REM_LEN: usize =
    DATA_SIZE as usize - (FR_LG_TEAMANDITEMS_UNK_LEN + TEAMANDITEMS_POKE_LEN + 4);

#[allow(clippy::large_enum_variant)]
enum TeamAndItemsUnknown {
    EmeraldOrRubyOrSapphire([u8; EM_RU_SA_TEAMANDITEMS_UNK_LEN]),
    FireRedOrLeafGreen([u8; FR_LG_TEAMANDITEMS_UNK_LEN]),
}

#[allow(clippy::large_enum_variant)]
enum TeamAndItemsRemaining {
    EmeraldOrRubyOrSapphire([u8; EM_RU_SA_TEAMANDITEMS_REM_LEN]),
    FireredOrLeafgreen([u8; FR_LG_TEAMANDITEMS_REM_LEN]),
}

struct TeamAndItems {
    unknown: TeamAndItemsUnknown,
    team: Vec<Pokemon>,
    orig_pokemon_data: [u8; TEAMANDITEMS_POKE_LEN],
    remaining_data: TeamAndItemsRemaining,
}

impl fmt::Debug for TeamAndItems {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("=== Team And Items ===\nTeam listing:\n")?;
        for pokemon in &self.team {
            pokemon.fmt(f)?
        }
        Ok(())
    }
}

const POKEMON_NICK_LEN: usize = 10;

#[derive(Default, Clone, Copy)]
pub struct PokemonNick(pub [u8; POKEMON_NICK_LEN]);
#[derive(Default, Clone, Copy)]
pub struct TrainerName(pub [u8; TRAINER_NAME_LEN]);
#[derive(Default, Clone, Copy)]
pub struct BoxName(pub [u8; BOX_NAME_LEN]);

const BOX_NAME_LEN: usize = 8;

macro_rules! debug_impl {
    ($target:ident) => {
        impl fmt::Debug for $target {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "{}", rgen3_string::decode_string(&self.0[..]))
            }
        }
    };
}

debug_impl!(PokemonNick);
debug_impl!(TrainerName);
debug_impl!(BoxName);

/// A Pokemon.
#[derive(Debug, Default)]
#[allow(missing_docs)]
pub struct Pokemon {
    pub personality: u32,
    pub ot_id: u32,
    pub nickname: PokemonNick,
    language: u16,
    pub ot_name: TrainerName,
    markings: u8,
    checksum: u16,
    unknown_1: u16,
    pub data: PokemonData,
    pub active_data: Option<PokemonActiveData>,
}

#[derive(Debug)]
pub struct InvalidSpecies;

impl Pokemon {
    pub fn set_species(&mut self, num: u16) -> Result<(), InvalidSpecies> {
        match num {
            1...251 | 277...411 => {
                self.data.growth.species = num;
                Ok(())
            }
            _ => Err(InvalidSpecies),
        }
    }
}

/// "Active" data that is not stored in the PC boxes.
#[derive(Debug, Default)]
pub struct PokemonActiveData {
    status_condition: u32,
    pub level: u8,
    pokerus_remaining: u8,
    pub current_hp: u16,
    pub total_hp: u16,
    pub attack: u16,
    pub defense: u16,
    pub speed: u16,
    pub sp_attack: u16,
    pub sp_defense: u16,
}

#[derive(Debug, Default)]
pub struct PokemonData {
    pub growth: PokemonGrowth,
    pub attacks: PokemonAttacks,
    pub evs_and_condition: PokemonEvsAndCondition,
    misc: PokemonMisc,
}

#[derive(Debug, Default)]
pub struct PokemonGrowth {
    pub species: u16,
    item_held: u16,
    pub experience: u32,
    pub pp_bonuses: u8,
    pub friendship: u8,
    unknown: u16,
}

#[derive(Debug, Default)]
pub struct PokemonAttacks {
    pub move1: u16,
    pub move2: u16,
    pub move3: u16,
    pub move4: u16,
    pub pp1: u8,
    pub pp2: u8,
    pub pp3: u8,
    pub pp4: u8,
}

#[derive(Debug, Default)]
pub struct PokemonEvsAndCondition {
    pub hp: u8,
    pub attack: u8,
    pub defense: u8,
    pub speed: u8,
    pub sp_attack: u8,
    pub sp_defense: u8,
    pub coolness: u8,
    pub beauty: u8,
    pub cuteness: u8,
    pub smartness: u8,
    pub toughness: u8,
    pub feel: u8,
}

#[derive(Debug, Default)]
struct PokemonMisc {
    pokerus_status: u8,
    met_location: u8,
    origins_info: u16,
    ivs_eggs_and_ability: u32,
    ribbons_and_obedience: u32,
}

struct PcBuffer {
    data: [u8; DATA_SIZE as usize],
    index: usize,
}

impl fmt::Debug for PcBuffer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "PC Buffer {}", self.index)
    }
}

const N_BOXES: usize = 14;

#[derive(Default)]
pub struct PokemonStorage {
    current_box: usize,
    boxes: Vec<PokeBox>,
}

impl fmt::Debug for PokemonStorage {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Pokemon storage: (current box: {})", self.current_box)?;
        for b in &self.boxes {
            b.fmt(f)?;
        }
        Ok(())
    }
}

const N_POKEMON_PER_BOX: usize = 30;

#[derive(Debug, Default)]
pub struct PokeBox {
    name: BoxName,
    wallpaper: u8,
    pub pokemon: [Option<Pokemon>; N_POKEMON_PER_BOX],
}
<commit_msg>Fix borrow checker error in 2018 edition? I guess?<commit_after>//! Library for manipulating Pokémon Gen3 (Fire Red/Leaf Green, Ruby/Emerald/Sapphire) save data.

#[macro_use]
extern crate log;
extern crate byteorder;
extern crate rgen3_string;

mod util {
    mod lower_upper;
    pub use self::lower_upper::LowerUpper;
}
mod rw;

use crate::util::LowerUpper;
use std::error::Error;
use std::fs::File;
use std::path::Path;
use std::{fmt, io};

const UNKNOWN_SAVE_FOOTER_SIZE: usize = 16384;

/// Pokémon Gen3 save data.
pub struct Save {
    blocks: [SaveBlock; 2],
    unknown: [u8; UNKNOWN_SAVE_FOOTER_SIZE],
    most_recent_index: usize,
}

impl fmt::Debug for Save {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.blocks.fmt(f)
    }
}

impl Save {
    /// Load the save data from a file at the provided path.
    pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Self, Box<Error>> {
        let mut file = File::open(path)?;
        Save::read(&mut file)
    }
    /// Save the save data to a file at the provided path.
    pub fn save_to_file<P: AsRef<Path>>(&mut self, path: P) -> Result<(), io::Error> {
        let mut file = File::create(path)?;
        self.write(&mut file)
    }
    pub fn sections(&mut self) -> SaveSections {
        let block = &mut self.blocks[self.most_recent_index];
        let sections = &mut block.sections[..];
        let (team_items_sec, trainer_sec) = if block.team_and_items_index > block.trainer_info_index
        {
            let (lhs, rhs) = sections.split_at_mut(block.team_and_items_index);
            (&mut rhs[0], &mut lhs[block.trainer_info_index])
        } else {
            let (lhs, rhs) = sections.split_at_mut(block.trainer_info_index);
            (&mut lhs[block.team_and_items_index], &mut rhs[0])
        };
        let team_and_items = if let SectionData::TeamAndItems(ref mut data) = team_items_sec.data {
            data
        } else {
            panic!("Unexpected section data. Expected TeamAndItems");
        };
        let trainer_info = if let SectionData::TrainerInfo(ref mut data) = trainer_sec.data {
            data
        } else {
            panic!("Unexpected section data. Expected TrainerInfo");
        };
        SaveSections {
            team: &mut team_and_items.team,
            trainer: trainer_info,
            pc_boxes: &mut block.pokemon_storage.boxes,
        }
    }
}

pub struct SaveSections<'a> {
    pub trainer: &'a mut TrainerInfo,
    pub team: &'a mut Vec<Pokemon>,
    pub pc_boxes: &'a mut [PokeBox],
}

#[derive(Debug)]
struct SaveBlock {
    sections: Vec<Section>,
    trainer_info_index: usize,
    team_and_items_index: usize,
    // Does not exist yet, meaning the game has only been saved once, and this
    // block hasn't been written over yet.
    nonexistent: bool,
    pokemon_storage: PokemonStorage,
    box_indexes: [usize; N_BOXES],
}

#[allow(clippy::large_enum_variant)]
enum SectionData {
    Unimplemented {
        raw: [u8; DATA_SIZE as usize],
        id: u16,
        cksum: u16,
    },
    TrainerInfo(TrainerInfo),
    TeamAndItems(TeamAndItems),
    PcBuffer(PcBuffer),
}

impl fmt::Debug for SectionData {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            SectionData::Unimplemented { .. } => f.write_str("<Unimplemented section>"),
            SectionData::TrainerInfo(ref data) => data.fmt(f),
            SectionData::TeamAndItems(ref data) => data.fmt(f),
            SectionData::PcBuffer(ref data) => data.fmt(f),
        }
    }
}

#[derive(Debug)]
struct Section {
    data: SectionData,
    unknown_1: u32,
    save_idx: u32,
}

const DATA_SIZE: i64 = 0xFF4;

#[repr(u8)]
#[derive(Clone, Copy, Debug)]
enum Gender {
    Male = 0,
    Female = 1,
}

impl fmt::Display for Gender {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str = match *self {
            Gender::Male => "Male",
            Gender::Female => "Female",
        };
        f.write_str(str)
    }
}

#[derive(Debug)]
struct Time {
    hours: u16,
    minutes: u8,
    seconds: u8,
    frames: u8,
}

const TRAINER_INFO_UNKNOWN_3_SIZE: usize = 0x00AC - (0x0013 + 3);
const RS_EM_PLAYERINFO_TRAILING_DATA_SIZE: usize = DATA_SIZE as usize - (0x0AC + 4);
const FRLG_PLAYERINFO_UNKNOWN_CHUNK_SIZE: usize = 0x0AF8 - (0x00AC + 4);
const FRLG_PLAYERINFO_TRAILING_DATA_SIZE: usize = DATA_SIZE as usize - (0x0AF8 + 4);

enum Game {
    RubyOrSapphire {
        trailing_data: [u8; RS_EM_PLAYERINFO_TRAILING_DATA_SIZE],
    },
    FireredOrLeafgreen {
        unknown: [u8; FRLG_PLAYERINFO_UNKNOWN_CHUNK_SIZE],
        security_key: u32,
        trailing_data: [u8; FRLG_PLAYERINFO_TRAILING_DATA_SIZE],
    },
    Emerald {
        security_key: u32,
        trailing_data: [u8; RS_EM_PLAYERINFO_TRAILING_DATA_SIZE],
    },
}

#[derive(Clone, Copy)]
enum GameType {
    RubyOrSapphire,
    FireredOrLeafgreen,
    Emerald,
}

impl<'a> From<&'a Game> for GameType {
    fn from(src: &Game) -> Self {
        match *src {
            Game::RubyOrSapphire { .. } => GameType::RubyOrSapphire,
            Game::FireredOrLeafgreen { .. } => GameType::FireredOrLeafgreen,
            Game::Emerald { .. } => GameType::Emerald,
        }
    }
}

impl fmt::Debug for Game {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Game::RubyOrSapphire { .. } => write!(f, "Ruby/Sapphire"),
            Game::FireredOrLeafgreen { security_key, .. } => {
                write!(f, "Fire Red/Leaf Green (security key: {})", security_key)
            }
            Game::Emerald { security_key, .. } => {
                write!(f, "Emerald (security key: {})", security_key)
            }
        }
    }
}

const TRAINER_NAME_LEN: usize = 7;

pub struct TrainerInfo {
    pub name: TrainerName,
    unknown_1: u8,
    gender: Gender,
    unknown_2: u8,
    public_id: u16,
    secret_id: u16,
    time_played: Time,
    options_data: [u8; 3],
    unknown_3: [u8; TRAINER_INFO_UNKNOWN_3_SIZE],
    game: Game,
}

impl TrainerInfo {
    pub fn full_id(&self) -> u32 {
        u32::merge(self.public_id, self.secret_id)
    }
}

impl fmt::Debug for TrainerInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("== Trainer Info ==\n")?;
        writeln!(f, "name: {:?}", self.name)?;
        writeln!(f, "gender: {:?}", self.gender)?;
        writeln!(
            f,
            "id: public({:?}) secret({:?}) combined({:?})",
            self.public_id,
            self.secret_id,
            u32::merge(self.public_id, self.secret_id)
        )?;
        writeln!(f, "Time played: {:?}", self.time_played)?;
        writeln!(f, "GAME ID: {:?}", self.game)
    }
}

const EM_RU_SA_TEAMANDITEMS_UNK_LEN: usize = 0x0234;
const FR_LG_TEAMANDITEMS_UNK_LEN: usize = 0x0034;
const TEAMANDITEMS_POKE_LEN: usize = 600;
const EM_RU_SA_TEAMANDITEMS_REM_LEN: usize =
    DATA_SIZE as usize - (EM_RU_SA_TEAMANDITEMS_UNK_LEN + TEAMANDITEMS_POKE_LEN + 4);
const FR_LG_TEAMANDITEMS_REM_LEN: usize =
    DATA_SIZE as usize - (FR_LG_TEAMANDITEMS_UNK_LEN + TEAMANDITEMS_POKE_LEN + 4);

#[allow(clippy::large_enum_variant)]
enum TeamAndItemsUnknown {
    EmeraldOrRubyOrSapphire([u8; EM_RU_SA_TEAMANDITEMS_UNK_LEN]),
    FireRedOrLeafGreen([u8; FR_LG_TEAMANDITEMS_UNK_LEN]),
}

#[allow(clippy::large_enum_variant)]
enum TeamAndItemsRemaining {
    EmeraldOrRubyOrSapphire([u8; EM_RU_SA_TEAMANDITEMS_REM_LEN]),
    FireredOrLeafgreen([u8; FR_LG_TEAMANDITEMS_REM_LEN]),
}

struct TeamAndItems {
    unknown: TeamAndItemsUnknown,
    team: Vec<Pokemon>,
    orig_pokemon_data: [u8; TEAMANDITEMS_POKE_LEN],
    remaining_data: TeamAndItemsRemaining,
}

impl fmt::Debug for TeamAndItems {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("=== Team And Items ===\nTeam listing:\n")?;
        for pokemon in &self.team {
            pokemon.fmt(f)?
        }
        Ok(())
    }
}

const POKEMON_NICK_LEN: usize = 10;

#[derive(Default, Clone, Copy)]
pub struct PokemonNick(pub [u8; POKEMON_NICK_LEN]);
#[derive(Default, Clone, Copy)]
pub struct TrainerName(pub [u8; TRAINER_NAME_LEN]);
#[derive(Default, Clone, Copy)]
pub struct BoxName(pub [u8; BOX_NAME_LEN]);

const BOX_NAME_LEN: usize = 8;

macro_rules! debug_impl {
    ($target:ident) => {
        impl fmt::Debug for $target {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "{}", rgen3_string::decode_string(&self.0[..]))
            }
        }
    };
}

debug_impl!(PokemonNick);
debug_impl!(TrainerName);
debug_impl!(BoxName);

/// A Pokemon.
#[derive(Debug, Default)]
#[allow(missing_docs)]
pub struct Pokemon {
    pub personality: u32,
    pub ot_id: u32,
    pub nickname: PokemonNick,
    language: u16,
    pub ot_name: TrainerName,
    markings: u8,
    checksum: u16,
    unknown_1: u16,
    pub data: PokemonData,
    pub active_data: Option<PokemonActiveData>,
}

#[derive(Debug)]
pub struct InvalidSpecies;

impl Pokemon {
    pub fn set_species(&mut self, num: u16) -> Result<(), InvalidSpecies> {
        match num {
            1...251 | 277...411 => {
                self.data.growth.species = num;
                Ok(())
            }
            _ => Err(InvalidSpecies),
        }
    }
}

/// "Active" data that is not stored in the PC boxes.
#[derive(Debug, Default)]
pub struct PokemonActiveData {
    status_condition: u32,
    pub level: u8,
    pokerus_remaining: u8,
    pub current_hp: u16,
    pub total_hp: u16,
    pub attack: u16,
    pub defense: u16,
    pub speed: u16,
    pub sp_attack: u16,
    pub sp_defense: u16,
}

#[derive(Debug, Default)]
pub struct PokemonData {
    pub growth: PokemonGrowth,
    pub attacks: PokemonAttacks,
    pub evs_and_condition: PokemonEvsAndCondition,
    misc: PokemonMisc,
}

#[derive(Debug, Default)]
pub struct PokemonGrowth {
    pub species: u16,
    item_held: u16,
    pub experience: u32,
    pub pp_bonuses: u8,
    pub friendship: u8,
    unknown: u16,
}

#[derive(Debug, Default)]
pub struct PokemonAttacks {
    pub move1: u16,
    pub move2: u16,
    pub move3: u16,
    pub move4: u16,
    pub pp1: u8,
    pub pp2: u8,
    pub pp3: u8,
    pub pp4: u8,
}

#[derive(Debug, Default)]
pub struct PokemonEvsAndCondition {
    pub hp: u8,
    pub attack: u8,
    pub defense: u8,
    pub speed: u8,
    pub sp_attack: u8,
    pub sp_defense: u8,
    pub coolness: u8,
    pub beauty: u8,
    pub cuteness: u8,
    pub smartness: u8,
    pub toughness: u8,
    pub feel: u8,
}

#[derive(Debug, Default)]
struct PokemonMisc {
    pokerus_status: u8,
    met_location: u8,
    origins_info: u16,
    ivs_eggs_and_ability: u32,
    ribbons_and_obedience: u32,
}

struct PcBuffer {
    data: [u8; DATA_SIZE as usize],
    index: usize,
}

impl fmt::Debug for PcBuffer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "PC Buffer {}", self.index)
    }
}

const N_BOXES: usize = 14;

#[derive(Default)]
pub struct PokemonStorage {
    current_box: usize,
    boxes: Vec<PokeBox>,
}

impl fmt::Debug for PokemonStorage {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Pokemon storage: (current box: {})", self.current_box)?;
        for b in &self.boxes {
            b.fmt(f)?;
        }
        Ok(())
    }
}

const N_POKEMON_PER_BOX: usize = 30;

#[derive(Debug, Default)]
pub struct PokeBox {
    name: BoxName,
    wallpaper: u8,
    pub pokemon: [Option<Pokemon>; N_POKEMON_PER_BOX],
}
<|endoftext|>


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

//! Servo's compiler plugin/macro crate
//!
//! Attributes this crate provides:
//!
//!  - `#[derive(DenyPublicFields)]` : Forces all fields in a struct/enum to be private
//!  - `#[derive(JSTraceable)]` : Auto-derives an implementation of `JSTraceable` for a struct in the script crate
//!  - `#[must_root]` : Prevents data of the marked type from being used on the stack.
//!                     See the lints module for more details
//!  - `#[dom_struct]` : Implies #[derive(JSTraceable, DenyPublicFields)]`, and `#[must_root]`.
//!                       Use this for structs that correspond to a DOM type

#![deny(unsafe_code)]
#![feature(plugin)]
#![feature(plugin_registrar)]
#![feature(rustc_private)]

#[macro_use]
extern crate rustc;
extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::Registry;
use syntax::feature_gate::AttributeType::Whitelisted;

mod unrooted_must_root;
/// Utilities for writing plugins
mod utils;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_late_lint_pass(Box::new(unrooted_must_root::UnrootedPass::new()));
    reg.register_attribute("allow_unrooted_interior".to_string(), Whitelisted);
    reg.register_attribute("must_root".to_string(), Whitelisted);
}
<commit_msg>Fix new failure in Nightly 2017-11-01.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Servo's compiler plugin/macro crate
//!
//! Attributes this crate provides:
//!
//!  - `#[derive(DenyPublicFields)]` : Forces all fields in a struct/enum to be private
//!  - `#[derive(JSTraceable)]` : Auto-derives an implementation of `JSTraceable` for a struct in the script crate
//!  - `#[must_root]` : Prevents data of the marked type from being used on the stack.
//!                     See the lints module for more details
//!  - `#[dom_struct]` : Implies #[derive(JSTraceable, DenyPublicFields)]`, and `#[must_root]`.
//!                       Use this for structs that correspond to a DOM type

#![deny(unsafe_code)]
#![feature(macro_vis_matcher)]
#![feature(plugin)]
#![feature(plugin_registrar)]
#![feature(rustc_private)]

#[macro_use]
extern crate rustc;
extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::Registry;
use syntax::feature_gate::AttributeType::Whitelisted;

mod unrooted_must_root;
/// Utilities for writing plugins
mod utils;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_late_lint_pass(Box::new(unrooted_must_root::UnrootedPass::new()));
    reg.register_attribute("allow_unrooted_interior".to_string(), Whitelisted);
    reg.register_attribute("must_root".to_string(), Whitelisted);
}
<|endoftext|>


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

use error::{Result, Error};
use hcore::os::users;
use hcore::package::PackageInstall;

static LOGKEY: &'static str = "UR";

const DEFAULT_USER: &'static str = "hab";
const DEFAULT_GROUP: &'static str = "hab";

/// This function checks to see if a custom SVC_USER and SVC_GROUP has
/// been specified as part of the package metadata.
/// If a pkg_svc_user and pkg_svc_group have been defined, check if:
///     a) we are root
///     b) we are the specified user:group
///     c) fail otherwise
/// If pkg_svc_user and pkg_svc_group have NOT been defined, return None.
fn check_pkg_user_and_group(pkg_install: &PackageInstall) -> Result<Option<(String, String)>> {
    let svc_user = try!(pkg_install.svc_user());
    let svc_group = try!(pkg_install.svc_group());
    match (svc_user, svc_group) {
        (Some(user), Some(group)) => {
            if let None = users::get_uid_by_name(&user) {
                return Err(sup_error!(Error::Permissions(format!("Package requires user {} to \
                                                                  exist, but it doesn't",
                                                                 user))));
            }
            if let None = users::get_gid_by_name(&group) {
                return Err(sup_error!(Error::Permissions(format!("Package requires group {} \
                                                                  to exist, but it doesn't",
                                                                 group))));
            }

            let current_user = users::get_current_username();
            let current_group = users::get_current_groupname();

            if let None = current_user {
                return Err(sup_error!(Error::Permissions("Can't determine current user"
                    .to_string())));
            }

            if let None = current_group {
                return Err(sup_error!(Error::Permissions("Can't determine current group"
                    .to_string())));
            }

            let current_user = current_user.unwrap();
            let current_group = current_group.unwrap();

            if current_user == users::root_level_account() {
                Ok(Some((user, group)))
            } else {
                if current_user == user && (cfg!(target_os = "windows") || current_group == group) {
                    // ok, sup is running as svc_user/svc_group already
                    Ok(Some((user, group)))
                } else {
                    let msg = format!("Package must run as {}:{} or root", &user, &group);
                    return Err(sup_error!(Error::Permissions(msg)));
                }
            }
        }
        _ => {
            debug!("User/group not specified in package, running with default");
            Ok(None)
        }
    }
}

/// checks to see if hab/hab exists, if not, fall back to
/// current user/group. If that fails, then return an error.
fn get_default_user_and_group() -> Result<(String, String)> {
    let uid = users::get_uid_by_name(DEFAULT_USER);
    let gid = users::get_gid_by_name(DEFAULT_GROUP);
    match (uid, gid) {
        (Some(_), Some(_)) => return Ok((DEFAULT_USER.to_string(), DEFAULT_GROUP.to_string())),
        _ => {
            debug!("hab:hab does NOT exist");
            let user = users::get_current_username();
            let group = users::get_current_groupname();
            match (user, group) {
                (Some(user), Some(group)) => {
                    debug!("Running as {}/{}", user, group);
                    return Ok((user, group));
                }
                _ => {
                    return Err(sup_error!(Error::Permissions("Can't determine current user:group"
                        .to_string())))
                }
            }
        }
    }
}

/// check and see if a user/group is specified in package metadata.
/// if not, we'll try and use hab/hab.
/// If hab/hab doesn't exist, try to use (current username, current group).
/// If that doesn't work, then give up.
pub fn get_user_and_group(pkg_install: &PackageInstall) -> Result<(String, String)> {
    if let Some((user, group)) = try!(check_pkg_user_and_group(&pkg_install)) {
        Ok((user, group))
    } else {
        let defaults = try!(get_default_user_and_group());
        Ok(defaults)
    }
}
<commit_msg>ignoring configured user and group validation on windows<commit_after>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use error::{Result, Error};
use hcore::os::users;
use hcore::package::PackageInstall;

static LOGKEY: &'static str = "UR";

const DEFAULT_USER: &'static str = "hab";
const DEFAULT_GROUP: &'static str = "hab";

/// This function checks to see if a custom SVC_USER and SVC_GROUP has
/// been specified as part of the package metadata.
/// If a pkg_svc_user and pkg_svc_group have been defined, check if:
///     a) we are root
///     b) we are the specified user:group
///     c) fail otherwise
/// If pkg_svc_user and pkg_svc_group have NOT been defined, return None.
fn check_pkg_user_and_group(pkg_install: &PackageInstall) -> Result<Option<(String, String)>> {
    let svc_user = try!(pkg_install.svc_user());
    let svc_group = try!(pkg_install.svc_group());
    match (svc_user, svc_group) {
        (Some(user), Some(group)) => {
            if let None = users::get_uid_by_name(&user) {
                return Err(sup_error!(Error::Permissions(format!("Package requires user {} to \
                                                                  exist, but it doesn't",
                                                                 user))));
            }
            if let None = users::get_gid_by_name(&group) {
                return Err(sup_error!(Error::Permissions(format!("Package requires group {} \
                                                                  to exist, but it doesn't",
                                                                 group))));
            }

            let current_user = users::get_current_username();
            let current_group = users::get_current_groupname();

            if let None = current_user {
                return Err(sup_error!(Error::Permissions("Can't determine current user"
                    .to_string())));
            }

            if let None = current_group {
                return Err(sup_error!(Error::Permissions("Can't determine current group"
                    .to_string())));
            }

            let current_user = current_user.unwrap();
            let current_group = current_group.unwrap();

            if current_user == users::root_level_account() {
                Ok(Some((user, group)))
            } else {
                if current_user == user && (cfg!(target_os = "windows") || current_group == group) {
                    // ok, sup is running as svc_user/svc_group already
                    Ok(Some((user, group)))
                } else {
                    let msg = format!("Package must run as {}:{} or root", &user, &group);
                    return Err(sup_error!(Error::Permissions(msg)));
                }
            }
        }
        _ => {
            debug!("User/group not specified in package, running with default");
            Ok(None)
        }
    }
}

/// checks to see if hab/hab exists, if not, fall back to
/// current user/group. If that fails, then return an error.
fn get_default_user_and_group() -> Result<(String, String)> {
    let uid = users::get_uid_by_name(DEFAULT_USER);
    let gid = users::get_gid_by_name(DEFAULT_GROUP);
    match (uid, gid) {
        (Some(_), Some(_)) => return Ok((DEFAULT_USER.to_string(), DEFAULT_GROUP.to_string())),
        _ => {
            debug!("hab:hab does NOT exist");
            let user = users::get_current_username();
            let group = users::get_current_groupname();
            match (user, group) {
                (Some(user), Some(group)) => {
                    debug!("Running as {}/{}", user, group);
                    return Ok((user, group));
                }
                _ => {
                    return Err(sup_error!(Error::Permissions("Can't determine current user:group"
                        .to_string())))
                }
            }
        }
    }
}

/// check and see if a user/group is specified in package metadata.
/// if not, we'll try and use hab/hab.
/// If hab/hab doesn't exist, try to use (current username, current group).
/// If that doesn't work, then give up.
#[cfg(unix)]
pub fn get_user_and_group(pkg_install: &PackageInstall) -> Result<(String, String)> {
    if let Some((user, group)) = try!(check_pkg_user_and_group(&pkg_install)) {
        Ok((user, group))
    } else {
        let defaults = try!(get_default_user_and_group());
        Ok(defaults)
    }
}

/// For now we are ignoring any configured user and group
/// because we do not start the supervisor on windows under
/// alternate credentials
#[cfg(windows)]
pub fn get_user_and_group(pkg_install: &PackageInstall) -> Result<(String, String)> {
    let defaults = try!(get_default_user_and_group());
    Ok(defaults)
}
<|endoftext|>