<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/.

/// Code to handle management of a pool's thinpool device.

use std::process::Command;

use devicemapper;
use devicemapper::{Bytes, DM, DataBlocks, DmError, DmResult, LinearDev, MetaBlocks, Sectors,
                   Segment, ThinDev, ThinDevId, ThinPoolDev, ThinPoolStatus};

use super::super::consts::IEC;
use super::super::errors::{EngineError, EngineResult, ErrorEnum};
use super::super::types::PoolUuid;

use super::dmdevice::{FlexRole, ThinDevIdPool, ThinPoolRole, format_flex_name,
                      format_thinpool_name};
use super::serde_structs::{Recordable, ThinPoolDevSave};

pub const DATA_BLOCK_SIZE: Sectors = Sectors(2048);
pub const DATA_LOWATER: DataBlocks = DataBlocks(512);
pub const META_LOWATER: MetaBlocks = MetaBlocks(512);

/// A ThinPool struct contains the thinpool itself, but also the spare
/// segments for its metadata device.
#[derive(Debug)]
pub struct ThinPool {
    thin_pool: ThinPoolDev,
    meta_spare: Vec<Segment>,
    id_gen: ThinDevIdPool,
}

impl ThinPool {
    /// Make a new thin pool.
    pub fn new(pool_uuid: PoolUuid,
               dm: &DM,
               data_block_size: Sectors,
               low_water_mark: DataBlocks,
               spare_segments: Vec<Segment>,
               meta_dev: LinearDev,
               data_dev: LinearDev)
               -> EngineResult<ThinPool> {
        let name = format_thinpool_name(&pool_uuid, ThinPoolRole::Pool);
        let thinpool_dev = try!(ThinPoolDev::new(&name,
                                                 dm,
                                                 try!(data_dev.size()),
                                                 data_block_size,
                                                 low_water_mark,
                                                 meta_dev,
                                                 data_dev));
        Ok(ThinPool {
               thin_pool: thinpool_dev,
               meta_spare: spare_segments,
               id_gen: ThinDevIdPool::new_from_ids(&[]),
           })
    }

    /// Set up an "existing" thin pool.
    /// A thin pool must store the metadata for its thin devices, regardless of
    /// whether it has an existing device node. An existing thin pool device
    /// is a device where the metadata is already stored on its meta device.
    /// If initial setup fails due to a thin_check failure, attempt to fix
    /// the problem by running thin_repair. If failure recurs, return an
    /// error.
    #[allow(too_many_arguments)]
    pub fn setup(pool_uuid: PoolUuid,
                 dm: &DM,
                 data_block_size: Sectors,
                 low_water_mark: DataBlocks,
                 thin_ids: &[ThinDevId],
                 spare_segments: Vec<Segment>,
                 meta_dev: LinearDev,
                 data_dev: LinearDev)
                 -> EngineResult<ThinPool> {
        let name = format_thinpool_name(&pool_uuid, ThinPoolRole::Pool);
        let size = try!(data_dev.size());
        match ThinPoolDev::setup(&name,
                                 dm,
                                 size,
                                 data_block_size,
                                 low_water_mark,
                                 meta_dev,
                                 data_dev) {
            Ok(dev) => {
                Ok(ThinPool {
                       thin_pool: dev,
                       meta_spare: spare_segments,
                       id_gen: ThinDevIdPool::new_from_ids(thin_ids),
                   })
            }
            Err(DmError::Dm(devicemapper::ErrorEnum::CheckFailed(meta_dev, data_dev), _)) => {
                let (new_meta_dev, new_spare_segments) =
                    try!(attempt_thin_repair(pool_uuid, dm, meta_dev, spare_segments));
                Ok(ThinPool {
                       thin_pool: try!(ThinPoolDev::setup(&name,
                                                          dm,
                                                          size,
                                                          data_block_size,
                                                          low_water_mark,
                                                          new_meta_dev,
                                                          data_dev)),
                       meta_spare: new_spare_segments,
                       id_gen: ThinDevIdPool::new_from_ids(thin_ids),
                   })
            }
            Err(err) => Err(err.into()),
        }
    }

    /// The status of the thin pool as calculated by DM.
    pub fn thin_pool_status(&self, dm: &DM) -> EngineResult<ThinPoolStatus> {
        Ok(try!(self.thin_pool.status(dm)))
    }

    /// Make a new thin device.
    pub fn make_thin_device(&mut self,
                            dm: &DM,
                            name: &str,
                            size: Option<Sectors>)
                            -> EngineResult<ThinDev> {
        Ok(try!(ThinDev::new(name,
                             dm,
                             &self.thin_pool,
                             try!(self.id_gen.new_id()),
                             size.unwrap_or(Bytes(IEC::Ti).sectors()))))
    }

    /// Setup a previously constructed thin device.
    pub fn setup_thin_device(&self,
                             dm: &DM,
                             name: &str,
                             id: ThinDevId,
                             size: Sectors)
                             -> EngineResult<ThinDev> {
        Ok(try!(ThinDev::setup(name, dm, &self.thin_pool, id, size)))
    }

    /// Tear down the thin pool.
    pub fn teardown(self, dm: &DM) -> DmResult<()> {
        self.thin_pool.teardown(dm)
    }

    /// Get an immutable reference to the sparse segments of the ThinPool.
    pub fn spare_segments(&self) -> &[Segment] {
        &self.meta_spare
    }

    /// The segments belonging to the thin pool meta device.
    pub fn thin_pool_meta_segments(&self) -> &[Segment] {
        self.thin_pool.meta_dev().segments()
    }

    /// The segments belonging to the thin pool data device.
    pub fn thin_pool_data_segments(&self) -> &[Segment] {
        self.thin_pool.data_dev().segments()
    }

    /// Extend the thinpool with new data regions.
    pub fn extend_data(&mut self, dm: &DM, segs: Vec<Segment>) -> EngineResult<()> {
        Ok(try!(self.thin_pool.extend_data(dm, segs)))
    }

    /// The number of physical sectors in use, that is, unavailable for storage
    /// of additional user data, by this pool.
    // This includes all the sectors being held as spares for the meta device,
    // all the sectors allocated to the meta data device, and all the sectors
    // in use on the data device.
    pub fn total_physical_used(&self) -> EngineResult<Sectors> {
        let data_dev_used = match try!(self.thin_pool.status(&try!(DM::new()))) {
            ThinPoolStatus::Good(_, usage) => *usage.used_data * DATA_BLOCK_SIZE,
            _ => {
                let err_msg = "thin pool failed, could not obtain usage";
                return Err(EngineError::Engine(ErrorEnum::Invalid, err_msg.into()));
            }
        };

        let spare_total = self.spare_segments().iter().map(|s| s.length).sum();
        let meta_dev_total = self.thin_pool
            .meta_dev()
            .segments()
            .iter()
            .map(|s| s.length)
            .sum();

        Ok(data_dev_used + spare_total + meta_dev_total)
    }
}

impl Recordable<ThinPoolDevSave> for ThinPool {
    fn record(&self) -> EngineResult<ThinPoolDevSave> {
        Ok(ThinPoolDevSave { data_block_size: self.thin_pool.data_block_size() })
    }
}

/// Attempt a thin repair operation on the meta device.
/// If the operation succeeds, teardown the old meta device,
/// and return the new meta device and the new spare segments.
fn attempt_thin_repair(pool_uuid: PoolUuid,
                       dm: &DM,
                       meta_dev: LinearDev,
                       mut spare_segments: Vec<Segment>)
                       -> EngineResult<(LinearDev, Vec<Segment>)> {
    let mut new_meta_dev = try!(LinearDev::new(&format_flex_name(&pool_uuid,
                                                                 FlexRole::ThinMetaSpare),
                                               dm,
                                               spare_segments.drain(..).collect()));

    if !try!(Command::new("thin_repair")
                 .arg("-i")
                 .arg(&try!(meta_dev.devnode()))
                 .arg("-o")
                 .arg(&try!(new_meta_dev.devnode()))
                 .status())
                .success() {
        return Err(EngineError::Engine(ErrorEnum::Error,
                                       "thin_repair failed, pool unusable".into()));
    }

    let name = meta_dev.name().to_owned();
    let new_spare_segments = meta_dev
        .segments()
        .iter()
        .map(|x| {
                 Segment {
                     start: x.start,
                     length: x.length,
                     device: x.device,
                 }
             })
        .collect();
    try!(meta_dev.teardown(dm));
    try!(new_meta_dev.set_name(dm, &name));

    Ok((new_meta_dev, new_spare_segments))
}
<commit_msg>Make default thin dev size a constant<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/.

/// Code to handle management of a pool's thinpool device.

use std::process::Command;

use devicemapper;
use devicemapper::{DM, DataBlocks, DmError, DmResult, LinearDev, MetaBlocks, Sectors, Segment,
                   ThinDev, ThinDevId, ThinPoolDev, ThinPoolStatus};

use super::super::consts::IEC;
use super::super::errors::{EngineError, EngineResult, ErrorEnum};
use super::super::types::PoolUuid;

use super::dmdevice::{FlexRole, ThinDevIdPool, ThinPoolRole, format_flex_name,
                      format_thinpool_name};
use super::serde_structs::{Recordable, ThinPoolDevSave};

pub const DATA_BLOCK_SIZE: Sectors = Sectors(2048);
pub const DATA_LOWATER: DataBlocks = DataBlocks(512);
pub const META_LOWATER: MetaBlocks = MetaBlocks(512);

const DEFAULT_THIN_DEV_SIZE: Sectors = Sectors(2 * IEC::Gi); // 1 TiB

/// A ThinPool struct contains the thinpool itself, but also the spare
/// segments for its metadata device.
#[derive(Debug)]
pub struct ThinPool {
    thin_pool: ThinPoolDev,
    meta_spare: Vec<Segment>,
    id_gen: ThinDevIdPool,
}

impl ThinPool {
    /// Make a new thin pool.
    pub fn new(pool_uuid: PoolUuid,
               dm: &DM,
               data_block_size: Sectors,
               low_water_mark: DataBlocks,
               spare_segments: Vec<Segment>,
               meta_dev: LinearDev,
               data_dev: LinearDev)
               -> EngineResult<ThinPool> {
        let name = format_thinpool_name(&pool_uuid, ThinPoolRole::Pool);
        let thinpool_dev = try!(ThinPoolDev::new(&name,
                                                 dm,
                                                 try!(data_dev.size()),
                                                 data_block_size,
                                                 low_water_mark,
                                                 meta_dev,
                                                 data_dev));
        Ok(ThinPool {
               thin_pool: thinpool_dev,
               meta_spare: spare_segments,
               id_gen: ThinDevIdPool::new_from_ids(&[]),
           })
    }

    /// Set up an "existing" thin pool.
    /// A thin pool must store the metadata for its thin devices, regardless of
    /// whether it has an existing device node. An existing thin pool device
    /// is a device where the metadata is already stored on its meta device.
    /// If initial setup fails due to a thin_check failure, attempt to fix
    /// the problem by running thin_repair. If failure recurs, return an
    /// error.
    #[allow(too_many_arguments)]
    pub fn setup(pool_uuid: PoolUuid,
                 dm: &DM,
                 data_block_size: Sectors,
                 low_water_mark: DataBlocks,
                 thin_ids: &[ThinDevId],
                 spare_segments: Vec<Segment>,
                 meta_dev: LinearDev,
                 data_dev: LinearDev)
                 -> EngineResult<ThinPool> {
        let name = format_thinpool_name(&pool_uuid, ThinPoolRole::Pool);
        let size = try!(data_dev.size());
        match ThinPoolDev::setup(&name,
                                 dm,
                                 size,
                                 data_block_size,
                                 low_water_mark,
                                 meta_dev,
                                 data_dev) {
            Ok(dev) => {
                Ok(ThinPool {
                       thin_pool: dev,
                       meta_spare: spare_segments,
                       id_gen: ThinDevIdPool::new_from_ids(thin_ids),
                   })
            }
            Err(DmError::Dm(devicemapper::ErrorEnum::CheckFailed(meta_dev, data_dev), _)) => {
                let (new_meta_dev, new_spare_segments) =
                    try!(attempt_thin_repair(pool_uuid, dm, meta_dev, spare_segments));
                Ok(ThinPool {
                       thin_pool: try!(ThinPoolDev::setup(&name,
                                                          dm,
                                                          size,
                                                          data_block_size,
                                                          low_water_mark,
                                                          new_meta_dev,
                                                          data_dev)),
                       meta_spare: new_spare_segments,
                       id_gen: ThinDevIdPool::new_from_ids(thin_ids),
                   })
            }
            Err(err) => Err(err.into()),
        }
    }

    /// The status of the thin pool as calculated by DM.
    pub fn thin_pool_status(&self, dm: &DM) -> EngineResult<ThinPoolStatus> {
        Ok(try!(self.thin_pool.status(dm)))
    }

    /// Make a new thin device.
    pub fn make_thin_device(&mut self,
                            dm: &DM,
                            name: &str,
                            size: Option<Sectors>)
                            -> EngineResult<ThinDev> {
        Ok(try!(ThinDev::new(name,
                             dm,
                             &self.thin_pool,
                             try!(self.id_gen.new_id()),
                             size.unwrap_or(DEFAULT_THIN_DEV_SIZE))))
    }

    /// Setup a previously constructed thin device.
    pub fn setup_thin_device(&self,
                             dm: &DM,
                             name: &str,
                             id: ThinDevId,
                             size: Sectors)
                             -> EngineResult<ThinDev> {
        Ok(try!(ThinDev::setup(name, dm, &self.thin_pool, id, size)))
    }

    /// Tear down the thin pool.
    pub fn teardown(self, dm: &DM) -> DmResult<()> {
        self.thin_pool.teardown(dm)
    }

    /// Get an immutable reference to the sparse segments of the ThinPool.
    pub fn spare_segments(&self) -> &[Segment] {
        &self.meta_spare
    }

    /// The segments belonging to the thin pool meta device.
    pub fn thin_pool_meta_segments(&self) -> &[Segment] {
        self.thin_pool.meta_dev().segments()
    }

    /// The segments belonging to the thin pool data device.
    pub fn thin_pool_data_segments(&self) -> &[Segment] {
        self.thin_pool.data_dev().segments()
    }

    /// Extend the thinpool with new data regions.
    pub fn extend_data(&mut self, dm: &DM, segs: Vec<Segment>) -> EngineResult<()> {
        Ok(try!(self.thin_pool.extend_data(dm, segs)))
    }

    /// The number of physical sectors in use, that is, unavailable for storage
    /// of additional user data, by this pool.
    // This includes all the sectors being held as spares for the meta device,
    // all the sectors allocated to the meta data device, and all the sectors
    // in use on the data device.
    pub fn total_physical_used(&self) -> EngineResult<Sectors> {
        let data_dev_used = match try!(self.thin_pool.status(&try!(DM::new()))) {
            ThinPoolStatus::Good(_, usage) => *usage.used_data * DATA_BLOCK_SIZE,
            _ => {
                let err_msg = "thin pool failed, could not obtain usage";
                return Err(EngineError::Engine(ErrorEnum::Invalid, err_msg.into()));
            }
        };

        let spare_total = self.spare_segments().iter().map(|s| s.length).sum();
        let meta_dev_total = self.thin_pool
            .meta_dev()
            .segments()
            .iter()
            .map(|s| s.length)
            .sum();

        Ok(data_dev_used + spare_total + meta_dev_total)
    }
}

impl Recordable<ThinPoolDevSave> for ThinPool {
    fn record(&self) -> EngineResult<ThinPoolDevSave> {
        Ok(ThinPoolDevSave { data_block_size: self.thin_pool.data_block_size() })
    }
}

/// Attempt a thin repair operation on the meta device.
/// If the operation succeeds, teardown the old meta device,
/// and return the new meta device and the new spare segments.
fn attempt_thin_repair(pool_uuid: PoolUuid,
                       dm: &DM,
                       meta_dev: LinearDev,
                       mut spare_segments: Vec<Segment>)
                       -> EngineResult<(LinearDev, Vec<Segment>)> {
    let mut new_meta_dev = try!(LinearDev::new(&format_flex_name(&pool_uuid,
                                                                 FlexRole::ThinMetaSpare),
                                               dm,
                                               spare_segments.drain(..).collect()));

    if !try!(Command::new("thin_repair")
                 .arg("-i")
                 .arg(&try!(meta_dev.devnode()))
                 .arg("-o")
                 .arg(&try!(new_meta_dev.devnode()))
                 .status())
                .success() {
        return Err(EngineError::Engine(ErrorEnum::Error,
                                       "thin_repair failed, pool unusable".into()));
    }

    let name = meta_dev.name().to_owned();
    let new_spare_segments = meta_dev
        .segments()
        .iter()
        .map(|x| {
                 Segment {
                     start: x.start,
                     length: x.length,
                     device: x.device,
                 }
             })
        .collect();
    try!(meta_dev.teardown(dm));
    try!(new_meta_dev.set_name(dm, &name));

    Ok((new_meta_dev, new_spare_segments))
}
<|endoftext|>


<commit_before>// A function which takes a closure as an argument and calls it.
fn apply<F>(f: F) where
    // The closure takes no input and returns nothing.
    F: FnOnce() {
    // ^ TODO: Try changing this to `Fn` or `FnMut`.

    f()
}

// A function which takes a closure and returns an `i32`.
fn apply_to_3<F>(f: F) -> i32 where
    // The closure takes an `i32` and returns an `i32`.
    F: Fn(i32) -> i32 {

    f(3)
}

fn main() {
    use std::mem;

    let greeting = "hello";
    // A non-copy type.
    let mut farewell = "goodbye".to_owned();

    // Capture 2 variables: `greeting` by reference and
    // `farewell` by value.
    let diary = || {
        // `greeting` is by reference: requires `Fn`.
        println!("I said {}.", greeting);

        // Mutation forces `farewell` to be captured by
        // mutable reference. Now requires `FnMut`.
        farewell.push_str("!!!");
        println!("Then I screamed {}.", farewell);
        println!("Now I can sleep. zzzzz");

        // Manually calling drop forces `farewell` to
        // be captured by value. Now requires `FnOnce`.
        mem::drop(farewell);
    };

    // Call the function which applies the closure.
    apply(diary);

    let double = |x| 2 * x;

    println!("3 doubled: {}", apply_to_3(double));
}
<commit_msg>Implicit return<commit_after>// A function which takes a closure as an argument and calls it.
fn apply<F>(f: F) where
    // The closure takes no input and returns nothing.
    F: FnOnce() {
    // ^ TODO: Try changing this to `Fn` or `FnMut`.

    f();
}

// A function which takes a closure and returns an `i32`.
fn apply_to_3<F>(f: F) -> i32 where
    // The closure takes an `i32` and returns an `i32`.
    F: Fn(i32) -> i32 {

    f(3)
}

fn main() {
    use std::mem;

    let greeting = "hello";
    // A non-copy type.
    let mut farewell = "goodbye".to_owned();

    // Capture 2 variables: `greeting` by reference and
    // `farewell` by value.
    let diary = || {
        // `greeting` is by reference: requires `Fn`.
        println!("I said {}.", greeting);

        // Mutation forces `farewell` to be captured by
        // mutable reference. Now requires `FnMut`.
        farewell.push_str("!!!");
        println!("Then I screamed {}.", farewell);
        println!("Now I can sleep. zzzzz");

        // Manually calling drop forces `farewell` to
        // be captured by value. Now requires `FnOnce`.
        mem::drop(farewell);
    };

    // Call the function which applies the closure.
    apply(diary);

    let double = |x| 2 * x;

    println!("3 doubled: {}", apply_to_3(double));
}
<|endoftext|>


<commit_before>extern crate rgen3_save;
extern crate rgen3_string;
extern crate rand;

use rand::{Rng, thread_rng};
use rgen3_save::{Pokemon, SaveSections};
use std::collections::HashSet;

static NAMES: [&'static str; 16] = [
    "Tubby",
    "Chewbacca",
    "Huey",
    "Dewey",
    "Louie",
    "Abby",
    "Jay Leno",
    "Bird Jesus",
    "Cutie Pie",
    "Saitama",
    "Genos",
    "Princess",
    "Duke Nukem",
    "Jaden",
    "Goku",
    "Vegeta",
];

fn main() {
    let mut args = std::env::args().skip(1);
    let path = args.next().expect("Need path to save as first arg");
    let mut save = rgen3_save::Save::load_from_file(&path).unwrap();
    let mut rng = thread_rng();
    {
        let SaveSections { trainer, team } = save.sections();
        let mut chosen_names = HashSet::new();
        team.clear();
        for _ in 0..6 {
            let mut pokemon = Pokemon::default();
            let mut name;
            loop {
                name = rng.choose(&NAMES).unwrap();
                // Make sure we don't use the same name twice in our team
                if chosen_names.get(name).is_none() {
                    break;
                }
            };
            chosen_names.insert(name);
            rgen3_string::encode_string(name, &mut pokemon.nickname.0);
            pokemon.personality = rng.gen();
            pokemon.level = rng.gen_range(80, 100);
            pokemon.total_hp = rng.gen_range(800, 999);
            pokemon.current_hp = pokemon.total_hp;
            pokemon.attack = rng.gen_range(800, 999);
            pokemon.defense = rng.gen_range(800, 999);
            pokemon.speed = rng.gen_range(800, 999);
            pokemon.sp_attack = rng.gen_range(800, 999);
            pokemon.sp_defense = rng.gen_range(800, 999);
            pokemon.data.growth.species = rng.gen_range(0, 386);
            pokemon.data.growth.experience = std::u32::MAX / 2;
            pokemon.data.attacks.move1 = rng.gen_range(0, 354);
            pokemon.data.attacks.move2 = rng.gen_range(0, 354);
            pokemon.data.attacks.move3 = rng.gen_range(0, 354);
            pokemon.data.attacks.move4 = rng.gen_range(0, 354);
            pokemon.data.attacks.pp1 = 99;
            pokemon.data.attacks.pp2 = 99;
            pokemon.data.attacks.pp3 = 99;
            pokemon.data.attacks.pp4 = 99;
            pokemon.ot_id = trainer.full_id();
            pokemon.ot_name = trainer.name;
            team.push(pokemon);
        }
    }
    save.save_to_file(path).unwrap();
}
<commit_msg>Rustfmt random-team example<commit_after>extern crate rgen3_save;
extern crate rgen3_string;
extern crate rand;

use rand::{Rng, thread_rng};
use rgen3_save::{Pokemon, SaveSections};
use std::collections::HashSet;

static NAMES: [&'static str; 16] = ["Tubby",
                                    "Chewbacca",
                                    "Huey",
                                    "Dewey",
                                    "Louie",
                                    "Abby",
                                    "Jay Leno",
                                    "Bird Jesus",
                                    "Cutie Pie",
                                    "Saitama",
                                    "Genos",
                                    "Princess",
                                    "Duke Nukem",
                                    "Jaden",
                                    "Goku",
                                    "Vegeta"];

fn main() {
    let mut args = std::env::args().skip(1);
    let path = args.next().expect("Need path to save as first arg");
    let mut save = rgen3_save::Save::load_from_file(&path).unwrap();
    let mut rng = thread_rng();
    {
        let SaveSections { trainer, team } = save.sections();
        let mut chosen_names = HashSet::new();
        team.clear();
        for _ in 0..6 {
            let mut pokemon = Pokemon::default();
            let mut name;
            loop {
                name = rng.choose(&NAMES).unwrap();
                // Make sure we don't use the same name twice in our team
                if chosen_names.get(name).is_none() {
                    break;
                }
            }
            chosen_names.insert(name);
            rgen3_string::encode_string(name, &mut pokemon.nickname.0);
            pokemon.personality = rng.gen();
            pokemon.level = rng.gen_range(80, 100);
            pokemon.total_hp = rng.gen_range(800, 999);
            pokemon.current_hp = pokemon.total_hp;
            pokemon.attack = rng.gen_range(800, 999);
            pokemon.defense = rng.gen_range(800, 999);
            pokemon.speed = rng.gen_range(800, 999);
            pokemon.sp_attack = rng.gen_range(800, 999);
            pokemon.sp_defense = rng.gen_range(800, 999);
            pokemon.data.growth.species = rng.gen_range(0, 386);
            pokemon.data.growth.experience = std::u32::MAX / 2;
            pokemon.data.attacks.move1 = rng.gen_range(0, 354);
            pokemon.data.attacks.move2 = rng.gen_range(0, 354);
            pokemon.data.attacks.move3 = rng.gen_range(0, 354);
            pokemon.data.attacks.move4 = rng.gen_range(0, 354);
            pokemon.data.attacks.pp1 = 99;
            pokemon.data.attacks.pp2 = 99;
            pokemon.data.attacks.pp3 = 99;
            pokemon.data.attacks.pp4 = 99;
            pokemon.ot_id = trainer.full_id();
            pokemon.ot_name = trainer.name;
            team.push(pokemon);
        }
    }
    save.save_to_file(path).unwrap();
}
<|endoftext|>


<commit_before>use cairo;
use cssparser;
use glib::translate::*;
use glib_sys;
use libc;

use std::ptr;
use std::rc::Rc;

use bbox::RsvgBbox;
use drawing_ctx;
use error::*;
use gradient;
use node::NodeType;
use parsers::{Parse, ParseError};
use pattern;
use util::utf8_cstr;

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PaintServerSpread(pub cairo::enums::Extend);

impl Parse for PaintServerSpread {
    type Data = ();
    type Err = AttributeError;

    fn parse(s: &str, _: ()) -> Result<PaintServerSpread, AttributeError> {
        match s {
            "pad" => Ok(PaintServerSpread(cairo::enums::Extend::Pad)),
            "reflect" => Ok(PaintServerSpread(cairo::enums::Extend::Reflect)),
            "repeat" => Ok(PaintServerSpread(cairo::enums::Extend::Repeat)),
            _ => Err(AttributeError::Parse(ParseError::new(
                "expected 'pad' | 'reflect' | 'repeat'",
            ))),
        }
    }
}

impl Default for PaintServerSpread {
    fn default() -> PaintServerSpread {
        PaintServerSpread(cairo::enums::Extend::Pad)
    }
}

#[derive(Debug, Clone, PartialEq)]
pub enum PaintServer {
    Inherit,
    Iri {
        iri: String,
        alternate: Option<cssparser::Color>,
    },
    SolidColor(cssparser::Color),
}

impl Parse for PaintServer {
    type Data = ();
    type Err = AttributeError;

    fn parse(s: &str, _: ()) -> Result<PaintServer, AttributeError> {
        let mut input = cssparser::ParserInput::new(s);
        let mut parser = cssparser::Parser::new(&mut input);

        if parser.try(|i| i.expect_ident_matching("inherit")).is_ok() {
            Ok(PaintServer::Inherit)
        } else if let Ok(url) = parser.try(|i| i.expect_url()) {
            let alternate = if !parser.is_exhausted() {
                if parser.try(|i| i.expect_ident_matching("none")).is_ok() {
                    None
                } else {
                    Some(parser.try(|i| cssparser::Color::parse(i))?)
                }
            } else {
                None
            };

            Ok(PaintServer::Iri {
                iri: String::from(url.as_ref()),
                alternate,
            })
        } else {
            cssparser::Color::parse(&mut parser)
                .map(PaintServer::SolidColor)
                .map_err(AttributeError::from)
        }
    }
}

fn _set_source_rsvg_solid_color(
    ctx: *mut drawing_ctx::RsvgDrawingCtx,
    color: &cssparser::Color,
    opacity: u8,
    current_color: &cssparser::RGBA,
) {
    let rgba = match *color {
        cssparser::Color::RGBA(ref rgba) => rgba,
        cssparser::Color::CurrentColor => current_color,
    };

    drawing_ctx::get_cairo_context(ctx).set_source_rgba(
        f64::from(rgba.red_f32()),
        f64::from(rgba.green_f32()),
        f64::from(rgba.blue_f32()),
        f64::from(rgba.alpha_f32()) * (f64::from(opacity) / 255.0),
    );
}

/// Parses the paint specification, creating a new paint server object.
/// Return value: (nullable): The newly created paint server, or NULL on error.
///
/// # Arguments
///
/// * `str` - The SVG paint specification string to parse.
#[no_mangle]
pub extern "C" fn rsvg_paint_server_parse(
    inherit: *mut glib_sys::gboolean,
    str: *const libc::c_char,
) -> *const PaintServer {
    if !inherit.is_null() {
        unsafe {
            *inherit = true.to_glib();
        }
    }

    let paint_server = PaintServer::parse(unsafe { utf8_cstr(str) }, ());

    if let Ok(PaintServer::Inherit) = paint_server {
        if !inherit.is_null() {
            unsafe {
                *inherit = false.to_glib();
            }
        }
    }

    match paint_server {
        Ok(m) => Rc::into_raw(Rc::new(m)),
        Err(_) => ptr::null_mut(),
    }
}

/// Increase references counter of `PaintServer`.
///
/// # Arguments
///
/// * `paint_server` - must be constructed with `rsvg_paint_server_parse`.
#[no_mangle]
pub extern "C" fn rsvg_paint_server_ref(paint_server: *const PaintServer) {
    if paint_server.is_null() {
        return;
    }

    let server: Rc<PaintServer> = unsafe { Rc::from_raw(paint_server) };

    // forget about references
    Rc::into_raw(server.clone());
    Rc::into_raw(server);
}

/// Decrease references counter of `PaintServer`.
///
/// # Arguments
///
/// * `paint_server` - must be constructed with `rsvg_paint_server_parse`.
#[no_mangle]
pub extern "C" fn rsvg_paint_server_unref(paint_server: *const PaintServer) {
    if paint_server.is_null() {
        return;
    }

    // drop reference
    unsafe { Rc::from_raw(paint_server) };
}

pub fn _set_source_rsvg_paint_server(
    c_ctx: *mut drawing_ctx::RsvgDrawingCtx,
    ps: &PaintServer,
    opacity: u8,
    bbox: &RsvgBbox,
    current_color: &cssparser::RGBA,
) -> bool {
    let mut had_paint_server = false;

    match *ps {
        PaintServer::Iri {
            ref iri,
            ref alternate,
        } => {
            if let Some(acquired) = drawing_ctx::get_acquired_node(c_ctx, iri.as_str()) {
                let node = acquired.get();

                if node.get_type() == NodeType::LinearGradient
                    || node.get_type() == NodeType::RadialGradient
                {
                    had_paint_server = gradient::gradient_resolve_fallbacks_and_set_pattern(
                        &node, c_ctx, opacity, bbox,
                    );
                } else if node.get_type() == NodeType::Pattern {
                    had_paint_server =
                        pattern::pattern_resolve_fallbacks_and_set_pattern(&node, c_ctx, bbox);
                }
            }

            if !had_paint_server && alternate.is_some() {
                _set_source_rsvg_solid_color(
                    c_ctx,
                    alternate.as_ref().unwrap(),
                    opacity,
                    current_color,
                );
                had_paint_server = true;
            }
        }

        PaintServer::SolidColor(color) => {
            _set_source_rsvg_solid_color(c_ctx, &color, opacity, current_color);
            had_paint_server = true;
        }

        _ => {}
    };

    had_paint_server
}

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

    #[test]
    fn parses_spread_method() {
        assert_eq!(
            PaintServerSpread::parse("pad", ()),
            Ok(PaintServerSpread(cairo::enums::Extend::Pad))
        );

        assert_eq!(
            PaintServerSpread::parse("reflect", ()),
            Ok(PaintServerSpread(cairo::enums::Extend::Reflect))
        );

        assert_eq!(
            PaintServerSpread::parse("repeat", ()),
            Ok(PaintServerSpread(cairo::enums::Extend::Repeat))
        );

        assert!(PaintServerSpread::parse("foobar", ()).is_err());
    }

    #[test]
    fn parses_inherit() {
        assert_eq!(PaintServer::parse("inherit", ()), Ok(PaintServer::Inherit));
    }

    #[test]
    fn parses_solid_color() {
        assert_eq!(
            PaintServer::parse("rgb(255, 128, 64, 0.5)", ()),
            Ok(PaintServer::SolidColor(cssparser::Color::RGBA(
                cssparser::RGBA::new(255, 128, 64, 128)
            )))
        );

        assert_eq!(
            PaintServer::parse("currentColor", ()),
            Ok(PaintServer::SolidColor(cssparser::Color::CurrentColor))
        );
    }

    #[test]
    fn parses_iri() {
        assert_eq!(
            PaintServer::parse("url(#link)", ()),
            Ok(PaintServer::Iri {
                iri: "#link".to_string(),
                alternate: None,
            },)
        );

        assert_eq!(
            PaintServer::parse("url(#link) none", ()),
            Ok(PaintServer::Iri {
                iri: "#link".to_string(),
                alternate: None,
            },)
        );

        assert_eq!(
            PaintServer::parse("url(#link) #ff8040", ()),
            Ok(PaintServer::Iri {
                iri: "#link".to_string(),
                alternate: Some(cssparser::Color::RGBA(cssparser::RGBA::new(
                    255, 128, 64, 255
                ))),
            },)
        );

        assert_eq!(
            PaintServer::parse("url(#link) rgb(255, 128, 64, 0.5)", ()),
            Ok(PaintServer::Iri {
                iri: "#link".to_string(),
                alternate: Some(cssparser::Color::RGBA(cssparser::RGBA::new(
                    255, 128, 64, 128
                ))),
            },)
        );

        assert_eq!(
            PaintServer::parse("url(#link) currentColor", ()),
            Ok(PaintServer::Iri {
                iri: "#link".to_string(),
                alternate: Some(cssparser::Color::CurrentColor),
            },)
        );

        assert!(PaintServer::parse("url(#link) invalid", ()).is_err());
    }

    #[test]
    fn paint_server_refs_and_unrefs() {
        let rc = Rc::new(PaintServer::parse("#ffffff", ()).unwrap());
        let weak = Rc::downgrade(&rc);
        let ps = Rc::into_raw(rc);

        rsvg_paint_server_ref(ps);
        assert!(weak.upgrade().is_some());

        rsvg_paint_server_unref(ps);
        assert!(weak.upgrade().is_some());

        rsvg_paint_server_unref(ps);
        assert!(weak.upgrade().is_none());
    }
}
<commit_msg>paint_server.rs: Test that invalid syntax is caught<commit_after>use cairo;
use cssparser;
use glib::translate::*;
use glib_sys;
use libc;

use std::ptr;
use std::rc::Rc;

use bbox::RsvgBbox;
use drawing_ctx;
use error::*;
use gradient;
use node::NodeType;
use parsers::{Parse, ParseError};
use pattern;
use util::utf8_cstr;

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PaintServerSpread(pub cairo::enums::Extend);

impl Parse for PaintServerSpread {
    type Data = ();
    type Err = AttributeError;

    fn parse(s: &str, _: ()) -> Result<PaintServerSpread, AttributeError> {
        match s {
            "pad" => Ok(PaintServerSpread(cairo::enums::Extend::Pad)),
            "reflect" => Ok(PaintServerSpread(cairo::enums::Extend::Reflect)),
            "repeat" => Ok(PaintServerSpread(cairo::enums::Extend::Repeat)),
            _ => Err(AttributeError::Parse(ParseError::new(
                "expected 'pad' | 'reflect' | 'repeat'",
            ))),
        }
    }
}

impl Default for PaintServerSpread {
    fn default() -> PaintServerSpread {
        PaintServerSpread(cairo::enums::Extend::Pad)
    }
}

#[derive(Debug, Clone, PartialEq)]
pub enum PaintServer {
    Inherit,
    Iri {
        iri: String,
        alternate: Option<cssparser::Color>,
    },
    SolidColor(cssparser::Color),
}

impl Parse for PaintServer {
    type Data = ();
    type Err = AttributeError;

    fn parse(s: &str, _: ()) -> Result<PaintServer, AttributeError> {
        let mut input = cssparser::ParserInput::new(s);
        let mut parser = cssparser::Parser::new(&mut input);

        if parser.try(|i| i.expect_ident_matching("inherit")).is_ok() {
            Ok(PaintServer::Inherit)
        } else if let Ok(url) = parser.try(|i| i.expect_url()) {
            let alternate = if !parser.is_exhausted() {
                if parser.try(|i| i.expect_ident_matching("none")).is_ok() {
                    None
                } else {
                    Some(parser.try(|i| cssparser::Color::parse(i))?)
                }
            } else {
                None
            };

            Ok(PaintServer::Iri {
                iri: String::from(url.as_ref()),
                alternate,
            })
        } else {
            cssparser::Color::parse(&mut parser)
                .map(PaintServer::SolidColor)
                .map_err(AttributeError::from)
        }
    }
}

fn _set_source_rsvg_solid_color(
    ctx: *mut drawing_ctx::RsvgDrawingCtx,
    color: &cssparser::Color,
    opacity: u8,
    current_color: &cssparser::RGBA,
) {
    let rgba = match *color {
        cssparser::Color::RGBA(ref rgba) => rgba,
        cssparser::Color::CurrentColor => current_color,
    };

    drawing_ctx::get_cairo_context(ctx).set_source_rgba(
        f64::from(rgba.red_f32()),
        f64::from(rgba.green_f32()),
        f64::from(rgba.blue_f32()),
        f64::from(rgba.alpha_f32()) * (f64::from(opacity) / 255.0),
    );
}

/// Parses the paint specification, creating a new paint server object.
/// Return value: (nullable): The newly created paint server, or NULL on error.
///
/// # Arguments
///
/// * `str` - The SVG paint specification string to parse.
#[no_mangle]
pub extern "C" fn rsvg_paint_server_parse(
    inherit: *mut glib_sys::gboolean,
    str: *const libc::c_char,
) -> *const PaintServer {
    if !inherit.is_null() {
        unsafe {
            *inherit = true.to_glib();
        }
    }

    let paint_server = PaintServer::parse(unsafe { utf8_cstr(str) }, ());

    if let Ok(PaintServer::Inherit) = paint_server {
        if !inherit.is_null() {
            unsafe {
                *inherit = false.to_glib();
            }
        }
    }

    match paint_server {
        Ok(m) => Rc::into_raw(Rc::new(m)),
        Err(_) => ptr::null_mut(),
    }
}

/// Increase references counter of `PaintServer`.
///
/// # Arguments
///
/// * `paint_server` - must be constructed with `rsvg_paint_server_parse`.
#[no_mangle]
pub extern "C" fn rsvg_paint_server_ref(paint_server: *const PaintServer) {
    if paint_server.is_null() {
        return;
    }

    let server: Rc<PaintServer> = unsafe { Rc::from_raw(paint_server) };

    // forget about references
    Rc::into_raw(server.clone());
    Rc::into_raw(server);
}

/// Decrease references counter of `PaintServer`.
///
/// # Arguments
///
/// * `paint_server` - must be constructed with `rsvg_paint_server_parse`.
#[no_mangle]
pub extern "C" fn rsvg_paint_server_unref(paint_server: *const PaintServer) {
    if paint_server.is_null() {
        return;
    }

    // drop reference
    unsafe { Rc::from_raw(paint_server) };
}

pub fn _set_source_rsvg_paint_server(
    c_ctx: *mut drawing_ctx::RsvgDrawingCtx,
    ps: &PaintServer,
    opacity: u8,
    bbox: &RsvgBbox,
    current_color: &cssparser::RGBA,
) -> bool {
    let mut had_paint_server = false;

    match *ps {
        PaintServer::Iri {
            ref iri,
            ref alternate,
        } => {
            if let Some(acquired) = drawing_ctx::get_acquired_node(c_ctx, iri.as_str()) {
                let node = acquired.get();

                if node.get_type() == NodeType::LinearGradient
                    || node.get_type() == NodeType::RadialGradient
                {
                    had_paint_server = gradient::gradient_resolve_fallbacks_and_set_pattern(
                        &node, c_ctx, opacity, bbox,
                    );
                } else if node.get_type() == NodeType::Pattern {
                    had_paint_server =
                        pattern::pattern_resolve_fallbacks_and_set_pattern(&node, c_ctx, bbox);
                }
            }

            if !had_paint_server && alternate.is_some() {
                _set_source_rsvg_solid_color(
                    c_ctx,
                    alternate.as_ref().unwrap(),
                    opacity,
                    current_color,
                );
                had_paint_server = true;
            }
        }

        PaintServer::SolidColor(color) => {
            _set_source_rsvg_solid_color(c_ctx, &color, opacity, current_color);
            had_paint_server = true;
        }

        _ => {}
    };

    had_paint_server
}

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

    #[test]
    fn parses_spread_method() {
        assert_eq!(
            PaintServerSpread::parse("pad", ()),
            Ok(PaintServerSpread(cairo::enums::Extend::Pad))
        );

        assert_eq!(
            PaintServerSpread::parse("reflect", ()),
            Ok(PaintServerSpread(cairo::enums::Extend::Reflect))
        );

        assert_eq!(
            PaintServerSpread::parse("repeat", ()),
            Ok(PaintServerSpread(cairo::enums::Extend::Repeat))
        );

        assert!(PaintServerSpread::parse("foobar", ()).is_err());
    }

    #[test]
    fn catches_invalid_syntax() {
        assert!(PaintServer::parse("", ()).is_err());
        assert!(PaintServer::parse("42", ()).is_err());
        assert!(PaintServer::parse("invalid", ()).is_err());
    }

    #[test]
    fn parses_inherit() {
        assert_eq!(PaintServer::parse("inherit", ()), Ok(PaintServer::Inherit));
    }

    #[test]
    fn parses_solid_color() {
        assert_eq!(
            PaintServer::parse("rgb(255, 128, 64, 0.5)", ()),
            Ok(PaintServer::SolidColor(cssparser::Color::RGBA(
                cssparser::RGBA::new(255, 128, 64, 128)
            )))
        );

        assert_eq!(
            PaintServer::parse("currentColor", ()),
            Ok(PaintServer::SolidColor(cssparser::Color::CurrentColor))
        );
    }

    #[test]
    fn parses_iri() {
        assert_eq!(
            PaintServer::parse("url(#link)", ()),
            Ok(PaintServer::Iri {
                iri: "#link".to_string(),
                alternate: None,
            },)
        );

        assert_eq!(
            PaintServer::parse("url(#link) none", ()),
            Ok(PaintServer::Iri {
                iri: "#link".to_string(),
                alternate: None,
            },)
        );

        assert_eq!(
            PaintServer::parse("url(#link) #ff8040", ()),
            Ok(PaintServer::Iri {
                iri: "#link".to_string(),
                alternate: Some(cssparser::Color::RGBA(cssparser::RGBA::new(
                    255, 128, 64, 255
                ))),
            },)
        );

        assert_eq!(
            PaintServer::parse("url(#link) rgb(255, 128, 64, 0.5)", ()),
            Ok(PaintServer::Iri {
                iri: "#link".to_string(),
                alternate: Some(cssparser::Color::RGBA(cssparser::RGBA::new(
                    255, 128, 64, 128
                ))),
            },)
        );

        assert_eq!(
            PaintServer::parse("url(#link) currentColor", ()),
            Ok(PaintServer::Iri {
                iri: "#link".to_string(),
                alternate: Some(cssparser::Color::CurrentColor),
            },)
        );

        assert!(PaintServer::parse("url(#link) invalid", ()).is_err());
    }

    #[test]
    fn paint_server_refs_and_unrefs() {
        let rc = Rc::new(PaintServer::parse("#ffffff", ()).unwrap());
        let weak = Rc::downgrade(&rc);
        let ps = Rc::into_raw(rc);

        rsvg_paint_server_ref(ps);
        assert!(weak.upgrade().is_some());

        rsvg_paint_server_unref(ps);
        assert!(weak.upgrade().is_some());

        rsvg_paint_server_unref(ps);
        assert!(weak.upgrade().is_none());
    }
}
<|endoftext|>


<commit_before>extern crate clap;

use cli::CliConfig;

use std::path::Path;
use config::reader::from_file;
use config::types::Config as Cfg;
use config::types::Value as V;
use config::types::ScalarValue as S;

pub struct Configuration {
    pub rtp         : String,
    pub store_sub   : String,
    pub verbose     : bool,
    pub debugging   : bool,
}

impl Configuration {

    pub fn new(config: &CliConfig) -> Configuration {
        let rtp = rtp_path(config);

        let mut verbose     = false;
        let mut debugging   = false;
        let mut store_sub   = String::from("/store");

        if let Some(cfg) = fetch_config(&rtp) {
            if let Some(v) = cfg.lookup_boolean("verbose") {
                verbose = v;
            }
            if let Some(d) = cfg.lookup_boolean("debug") {
                debugging = d;
            }
            if let Some(s) = cfg.lookup_str("store") {
                store_sub = String::from(s);
            }
        }

        Configuration {
            verbose: verbose,
            debugging: debugging,
            store_sub: store_sub,
            rtp: rtp,
        }
    }

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

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

    pub fn store_path_str(&self) -> String {
        format!("{}{}", self.rtp, self.store_sub)
    }

    pub fn get_rtp(&self) -> String {
        self.rtp.clone()
    }

}

fn rtp_path(config: &CliConfig) -> String {
    String::from(config.cli_matches.value_of("rtp").unwrap_or("~/.imag/store/"))
}

fn fetch_config(rtp: &String) -> Option<Cfg> {
    from_file(Path::new(&(rtp.clone() + "/config"))).ok()
}

<commit_msg>Fix: unused import<commit_after>extern crate clap;

use cli::CliConfig;

use std::path::Path;
use config::reader::from_file;
use config::types::Config as Cfg;
use config::types::ScalarValue as S;

pub struct Configuration {
    pub rtp         : String,
    pub store_sub   : String,
    pub verbose     : bool,
    pub debugging   : bool,
}

impl Configuration {

    pub fn new(config: &CliConfig) -> Configuration {
        let rtp = rtp_path(config);

        let mut verbose     = false;
        let mut debugging   = false;
        let mut store_sub   = String::from("/store");

        if let Some(cfg) = fetch_config(&rtp) {
            if let Some(v) = cfg.lookup_boolean("verbose") {
                verbose = v;
            }
            if let Some(d) = cfg.lookup_boolean("debug") {
                debugging = d;
            }
            if let Some(s) = cfg.lookup_str("store") {
                store_sub = String::from(s);
            }
        }

        Configuration {
            verbose: verbose,
            debugging: debugging,
            store_sub: store_sub,
            rtp: rtp,
        }
    }

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

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

    pub fn store_path_str(&self) -> String {
        format!("{}{}", self.rtp, self.store_sub)
    }

    pub fn get_rtp(&self) -> String {
        self.rtp.clone()
    }

}

fn rtp_path(config: &CliConfig) -> String {
    String::from(config.cli_matches.value_of("rtp").unwrap_or("~/.imag/store/"))
}

fn fetch_config(rtp: &String) -> Option<Cfg> {
    from_file(Path::new(&(rtp.clone() + "/config"))).ok()
}

<|endoftext|>


<commit_before>// This is to facillitate the two different ways to call
// `impl_var`: one with doc comments and one without.
#[macro_export]
#[doc(hidden)]
macro_rules! impl_var_base {
    ($name:ident, $ty:ty, $( $( #[cfg($meta:meta)] )* $var:ident => $val:expr ),* ) => {
        impl From<$ty> for $name {
            fn from(v: $ty) -> Self {
                match v {
                    $(
                        $(
                            #[cfg($meta)]
                        )*
                        i if i == $val => $name::$var,
                    )*
                    i => $name::UnrecognizedVariant(i)
                }
            }
        }

        impl From<$name> for $ty {
            fn from(v: $name) -> Self {
                match v {
                    $(
                        $(
                            #[cfg($meta)]
                        )*
                        $name::$var => $val,
                    )*
                    $name::UnrecognizedVariant(i) => i,
                }
            }
        }

        impl<'a> From<&'a $name> for $ty {
            fn from(v: &'a $name) -> Self {
                match *v {
                    $(
                        $(
                            #[cfg($meta)]
                        )*
                        $name::$var => $val,
                    )*
                    $name::UnrecognizedVariant(i) => i,
                }
            }
        }

        impl $crate::Nl for $name {
            fn serialize(&self, mem: &mut $crate::StreamWriteBuffer) -> Result<(), $crate::err::SerError> {
                let v: $ty = self.clone().into();
                v.serialize(mem)
            }

            fn deserialize<T>(mem: &mut $crate::StreamReadBuffer<T>) -> Result<Self, $crate::err::DeError>
                    where T: AsRef<[u8]> {
                let v = <$ty>::deserialize(mem)?;
                Ok(v.into())
            }

            fn size(&self) -> usize {
                std::mem::size_of::<$ty>()
            }
        }
    };
}

#[macro_export]
/// For naming a new enum, passing in what type it serializes to and deserializes
/// from, and providing a mapping from variants to expressions (such as libc consts) that
/// will ultimately be used in the serialization/deserialization step when sending the netlink
/// message over the wire.
///
/// # Usage
///  Create an `enum` named "MyNetlinkProtoAttrs" that can be serialized into `u16`s to use with Netlink.
///  Possibly represents the fields on a message you received from Netlink.
///  ```ignore
///  impl_var!(MyNetlinkProtoAttrs, u16,
///     Id => 16 as u16,
///     Name => 17 as u16,
///     Size => 18 as u16
///  );
/// ```
/// Or, with doc comments (if you're developing a library)
/// ```ignore
///  impl_var!(
///     /// These are the attributes returned
///     /// by a fake netlink protocol.
///     ( MyNetlinkProtoAttrs, u16,
///     Id => 16 as u16,
///     Name => 17 as u16,
///     Size => 18 as u16 )
///  );
/// ```
///
macro_rules! impl_var {
    (
        $( #[$outer:meta] )*
        $name:ident, $ty:ty, $( $( #[cfg($meta:meta)] )* $var:ident => $val:expr ),*
    ) => ( // with comments
        $(#[$outer])*
        #[derive(Clone,Debug,Eq,PartialEq)]
        pub enum $name {
            $(
                $(
                    #[cfg($meta)]
                )*
                #[allow(missing_docs)]
                $var,
            )*
            /// Variant that signifies an invalid value while deserializing
            UnrecognizedVariant($ty),
        }

        impl_var_base!($name, $ty, $( $( #[cfg($meta)] )* $var => $val),* );
    );
    (
        $name:ident, $ty:ty,
        $( $( #[cfg($meta:meta)] )* $var:ident => $val:expr ),*
    ) => ( // without comments
        #[allow(missing_docs)]
        #[derive(Clone,Debug,Eq,PartialEq)]
        pub enum $name {
            #[allow(missing_docs)]
            $(
                $(
                    #[cfg($meta)]
                )*
                #[allow(missing_docs)]
                $var,
            )*
            /// Variant that signifies an invalid value while deserializing
            UnrecognizedVariant($ty),
        }

        impl_var_base!($name, $ty, $( $( #[cfg($meta:meta)] )* $var => $val),* );
    );
}

#[macro_export]
/// For generating a marker trait that flags a new enum as usable in a field that accepts a generic
/// type.
/// This way, the type can be constrained when the impl is provided to only accept enums that
/// implement the marker trait that corresponds to the given marker trait. The current
/// convention is to use `impl_trait` to create the trait with the name of the field that
/// is the generic type and then use `impl_var_trait` to flag the new enum as usable in
/// this field. See the examples below for more details.
macro_rules! impl_trait {
    ( $(#[$outer:meta])* $trait_name:ident, $to_from_ty:ty ) => { // with comments
        $(#[$outer])*
        pub trait $trait_name: $crate::Nl + PartialEq + From<$to_from_ty> + Into<$to_from_ty> {}

        impl $trait_name for $to_from_ty {}
    };
    ( $trait_name:ident, $to_from_ty:ty ) => { // without comments
        #[allow(missing_docs)]
        pub trait $trait_name: $crate::Nl + PartialEq + From<$to_from_ty> + Into<$to_from_ty> {}

        impl $trait_name for $to_from_ty {}
    };
}

#[macro_export]
/// For defining a new enum implementing the provided marker trait.
/// It accepts a name for the enum and the target type for serialization and
/// deserialization conversions, as well as value conversions
/// for serialization and deserialization.
macro_rules! impl_var_trait {
    ( $( #[$outer:meta] )* $name:ident, $ty:ty, $impl_name:ident,
      $( $( #[cfg($meta:meta)] )* $var:ident => $val:expr ),* ) => ( // with comments
        impl_var!( $(#[$outer])*
            $name, $ty, $( $( #[cfg($meta)] )* $var => $val ),*
        );

        impl $impl_name for $name {}
    );
    ( $name:ident, $ty:ty, $impl_name:ident,
      $( $( #[cfg($meta:meta)] )* $var:ident => $val:expr ),* ) => ( // without comments
        impl_var!($name, $ty, $( $( #[cfg($meta)] )* $var => $val ),* );

        impl $impl_name for $name {}
    );
}
<commit_msg>Derive (Partial)Eq, (Partial)Ord and Hash traits for enums.<commit_after>// This is to facillitate the two different ways to call
// `impl_var`: one with doc comments and one without.
#[macro_export]
#[doc(hidden)]
macro_rules! impl_var_base {
    ($name:ident, $ty:ty, $( $( #[cfg($meta:meta)] )* $var:ident => $val:expr ),* ) => {
        impl From<$ty> for $name {
            fn from(v: $ty) -> Self {
                match v {
                    $(
                        $(
                            #[cfg($meta)]
                        )*
                        i if i == $val => $name::$var,
                    )*
                    i => $name::UnrecognizedVariant(i)
                }
            }
        }

        impl From<$name> for $ty {
            fn from(v: $name) -> Self {
                match v {
                    $(
                        $(
                            #[cfg($meta)]
                        )*
                        $name::$var => $val,
                    )*
                    $name::UnrecognizedVariant(i) => i,
                }
            }
        }

        impl<'a> From<&'a $name> for $ty {
            fn from(v: &'a $name) -> Self {
                match *v {
                    $(
                        $(
                            #[cfg($meta)]
                        )*
                        $name::$var => $val,
                    )*
                    $name::UnrecognizedVariant(i) => i,
                }
            }
        }

        impl $crate::Nl for $name {
            fn serialize(&self, mem: &mut $crate::StreamWriteBuffer) -> Result<(), $crate::err::SerError> {
                let v: $ty = self.clone().into();
                v.serialize(mem)
            }

            fn deserialize<T>(mem: &mut $crate::StreamReadBuffer<T>) -> Result<Self, $crate::err::DeError>
                    where T: AsRef<[u8]> {
                let v = <$ty>::deserialize(mem)?;
                Ok(v.into())
            }

            fn size(&self) -> usize {
                std::mem::size_of::<$ty>()
            }
        }
    };
}

#[macro_export]
/// For naming a new enum, passing in what type it serializes to and deserializes
/// from, and providing a mapping from variants to expressions (such as libc consts) that
/// will ultimately be used in the serialization/deserialization step when sending the netlink
/// message over the wire.
///
/// # Usage
///  Create an `enum` named "MyNetlinkProtoAttrs" that can be serialized into `u16`s to use with Netlink.
///  Possibly represents the fields on a message you received from Netlink.
///  ```ignore
///  impl_var!(MyNetlinkProtoAttrs, u16,
///     Id => 16 as u16,
///     Name => 17 as u16,
///     Size => 18 as u16
///  );
/// ```
/// Or, with doc comments (if you're developing a library)
/// ```ignore
///  impl_var!(
///     /// These are the attributes returned
///     /// by a fake netlink protocol.
///     ( MyNetlinkProtoAttrs, u16,
///     Id => 16 as u16,
///     Name => 17 as u16,
///     Size => 18 as u16 )
///  );
/// ```
///
macro_rules! impl_var {
    (
        $( #[$outer:meta] )*
        $name:ident, $ty:ty, $( $( #[cfg($meta:meta)] )* $var:ident => $val:expr ),*
    ) => ( // with comments
        $(#[$outer])*
        #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
        pub enum $name {
            $(
                $(
                    #[cfg($meta)]
                )*
                #[allow(missing_docs)]
                $var,
            )*
            /// Variant that signifies an invalid value while deserializing
            UnrecognizedVariant($ty),
        }

        impl_var_base!($name, $ty, $( $( #[cfg($meta)] )* $var => $val),* );
    );
    (
        $name:ident, $ty:ty,
        $( $( #[cfg($meta:meta)] )* $var:ident => $val:expr ),*
    ) => ( // without comments
        #[allow(missing_docs)]
        #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
        pub enum $name {
            #[allow(missing_docs)]
            $(
                $(
                    #[cfg($meta)]
                )*
                #[allow(missing_docs)]
                $var,
            )*
            /// Variant that signifies an invalid value while deserializing
            UnrecognizedVariant($ty),
        }

        impl_var_base!($name, $ty, $( $( #[cfg($meta:meta)] )* $var => $val),* );
    );
}

#[macro_export]
/// For generating a marker trait that flags a new enum as usable in a field that accepts a generic
/// type.
/// This way, the type can be constrained when the impl is provided to only accept enums that
/// implement the marker trait that corresponds to the given marker trait. The current
/// convention is to use `impl_trait` to create the trait with the name of the field that
/// is the generic type and then use `impl_var_trait` to flag the new enum as usable in
/// this field. See the examples below for more details.
macro_rules! impl_trait {
    ( $(#[$outer:meta])* $trait_name:ident, $to_from_ty:ty ) => { // with comments
        $(#[$outer])*
        pub trait $trait_name: $crate::Nl + PartialEq + From<$to_from_ty> + Into<$to_from_ty> {}

        impl $trait_name for $to_from_ty {}
    };
    ( $trait_name:ident, $to_from_ty:ty ) => { // without comments
        #[allow(missing_docs)]
        pub trait $trait_name: $crate::Nl + PartialEq + From<$to_from_ty> + Into<$to_from_ty> {}

        impl $trait_name for $to_from_ty {}
    };
}

#[macro_export]
/// For defining a new enum implementing the provided marker trait.
/// It accepts a name for the enum and the target type for serialization and
/// deserialization conversions, as well as value conversions
/// for serialization and deserialization.
macro_rules! impl_var_trait {
    ( $( #[$outer:meta] )* $name:ident, $ty:ty, $impl_name:ident,
      $( $( #[cfg($meta:meta)] )* $var:ident => $val:expr ),* ) => ( // with comments
        impl_var!( $(#[$outer])*
            $name, $ty, $( $( #[cfg($meta)] )* $var => $val ),*
        );

        impl $impl_name for $name {}
    );
    ( $name:ident, $ty:ty, $impl_name:ident,
      $( $( #[cfg($meta:meta)] )* $var:ident => $val:expr ),* ) => ( // without comments
        impl_var!($name, $ty, $( $( #[cfg($meta)] )* $var => $val ),* );

        impl $impl_name for $name {}
    );
}
<|endoftext|>


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

use std::path::{PathBuf, Path};
use serde_json::{self, Value};
use serde::Deserialize;

use xi_core::{ViewIdentifier, PluginPid, BufferConfig, ConfigTable};
use xi_core::plugin_rpc::{TextUnit, GetDataResponse, ScopeSpan, PluginBufferInfo};
use xi_rope::rope::RopeDelta;
use xi_trace::trace_block;

use xi_rpc::RpcPeer;

use plugin_base::{Error, DataSource};

use global::Cache;

/// A type that acts as a proxy for a remote view. Provides access to
/// a document cache, and implements various methods for querying and modifying
/// view state.
pub struct View<C> {
    pub (crate) cache: C,
    pub (crate) peer: RpcPeer,
    pub (crate) path: Option<PathBuf>,
    pub (crate) config: BufferConfig,
    pub (crate) config_table: ConfigTable,
    plugin_id: PluginPid,
    pub (crate) rev: u64,
    pub (crate) view_id: ViewIdentifier,
}

impl<C: Cache> View<C> {
    pub (crate) fn new(peer: RpcPeer, plugin_id: PluginPid,
                       info: PluginBufferInfo) -> Self {
        let PluginBufferInfo {
            views, rev, path, config, buf_size, nb_lines, ..
        } = info;

        assert_eq!(views.len(), 1, "assuming single view");
        let view_id = views.first().unwrap().to_owned();
        let path = path.map(PathBuf::from);
        View {
            cache: C::new(buf_size, rev, nb_lines),
            peer: peer,
            config_table: config.clone(),
            config: serde_json::from_value(Value::Object(config)).unwrap(),
            path: path,
            plugin_id: plugin_id,
            view_id: view_id,
            rev: rev,
        }
    }

    pub (crate) fn update(&mut self, delta: Option<&RopeDelta>, new_len: usize,
                       new_num_lines: usize, rev: u64) {
        self.cache.update(delta, new_len, new_num_lines, rev);
        self.rev = rev;
    }

    //NOTE: (discuss in review) this feels bad, but because we're mutating cache,
    // which we own, we can't just pass in a reference to something else we own;
    // so we create this on each call. The `clone`is only cloning an `Arc`,
    // but we could maybe use a RefCell or something and make this cleaner.
    /// Returns a `FetchCtx`, a thin wrapper around an RpcPeer that implements
    /// the `DataSource` trait and can be used when updating a cache.
    pub (crate) fn make_ctx(&self) -> FetchCtx {
        FetchCtx {
            view_id: self.view_id,
            plugin_id: self.plugin_id,
            peer: self.peer.clone(),
        }
    }

    pub fn get_path(&self) -> Option<&Path> {
        self.path.as_ref().map(PathBuf::as_path)
    }

    pub fn get_config(&self) -> &BufferConfig {
        &self.config
    }

    pub fn get_cache(&mut self) -> &mut C {
        &mut self.cache
    }

    pub fn get_id(&self) -> ViewIdentifier {
        self.view_id.clone()
    }

    pub fn get_line(&mut self, line_num: usize) -> Result<&str, Error> {
        let ctx = self.make_ctx();
        self.cache.get_line(&ctx, line_num)
    }

    pub fn add_scopes(&self, scopes: &Vec<Vec<String>>) {
        let params = json!({
            "plugin_id": self.plugin_id,
            "view_id": self.view_id,
            "scopes": scopes,
        });
        self.peer.send_rpc_notification("add_scopes", &params);
    }

    pub fn update_spans(&self, start: usize, len: usize, spans: &[ScopeSpan]) {
        let params = json!({
            "plugin_id": self.plugin_id,
            "view_id": self.view_id,
            "start": start,
            "len": len,
            "rev": self.rev,
            "spans": spans,
        });
        self.peer.send_rpc_notification("update_spans", &params);
    }

    pub fn schedule_idle(&self) {
        let token: usize = self.view_id.into();
        self.peer.schedule_idle(token);
    }

    /// Returns `true` if an incoming RPC is pending. This is intended
    /// to reduce latency for bulk operations done in the background.
    pub fn request_is_pending(&self) -> bool {
        self.peer.request_is_pending()
    }

}

/// A simple wrapper type that acts as a `DataSource`.
pub struct FetchCtx {
    plugin_id: PluginPid,
    view_id: ViewIdentifier,
    peer: RpcPeer,
}

impl DataSource for FetchCtx {
    fn get_data(&self, start: usize, unit: TextUnit, max_size: usize, rev: u64)
        -> Result<GetDataResponse, Error> {
        let _t = trace_block("FetchCtx::get_data", &["plugin"]);
        let params = json!({
            "plugin_id": self.plugin_id,
            "view_id": self.view_id,
            "start": start,
            "unit": unit,
            "max_size": max_size,
            "rev": rev,
        });
        let result = self.peer.send_rpc_request("get_data", &params)
            .map_err(|e| Error::RpcError(e))?;
        GetDataResponse::deserialize(result)
            .map_err(|_| Error::WrongReturnType)
    }
}
<commit_msg>Additional tweaks to enable syntect migration<commit_after>// Copyright 2018 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::path::{PathBuf, Path};
use serde_json::{self, Value};
use serde::Deserialize;

use xi_core::{ViewIdentifier, PluginPid, BufferConfig, ConfigTable};
use xi_core::plugin_rpc::{TextUnit, GetDataResponse, ScopeSpan, PluginBufferInfo};
use xi_rope::rope::RopeDelta;
use xi_trace::trace_block;

use xi_rpc::RpcPeer;

use plugin_base::{Error, DataSource};

use global::Cache;

/// A type that acts as a proxy for a remote view. Provides access to
/// a document cache, and implements various methods for querying and modifying
/// view state.
pub struct View<C> {
    pub (crate) cache: C,
    pub (crate) peer: RpcPeer,
    pub (crate) path: Option<PathBuf>,
    pub (crate) config: BufferConfig,
    pub (crate) config_table: ConfigTable,
    plugin_id: PluginPid,
    // TODO: this is only public to avoid changing the syntect impl
    // this should go away with async edits
    pub rev: u64,
    buf_size: usize,
    pub (crate) view_id: ViewIdentifier,
}

impl<C: Cache> View<C> {
    pub (crate) fn new(peer: RpcPeer, plugin_id: PluginPid,
                       info: PluginBufferInfo) -> Self {
        let PluginBufferInfo {
            views, rev, path, config, buf_size, nb_lines, ..
        } = info;

        assert_eq!(views.len(), 1, "assuming single view");
        let view_id = views.first().unwrap().to_owned();
        let path = path.map(PathBuf::from);
        View {
            cache: C::new(buf_size, rev, nb_lines),
            peer: peer,
            config_table: config.clone(),
            config: serde_json::from_value(Value::Object(config)).unwrap(),
            path: path,
            plugin_id: plugin_id,
            view_id: view_id,
            rev: rev,
            buf_size: buf_size,
        }
    }

    pub (crate) fn update(&mut self, delta: Option<&RopeDelta>, new_len: usize,
                       new_num_lines: usize, rev: u64) {
        self.cache.update(delta, new_len, new_num_lines, rev);
        self.rev = rev;
        self.buf_size = new_len;
    }

    //NOTE: (discuss in review) this feels bad, but because we're mutating cache,
    // which we own, we can't just pass in a reference to something else we own;
    // so we create this on each call. The `clone`is only cloning an `Arc`,
    // but we could maybe use a RefCell or something and make this cleaner.
    /// Returns a `FetchCtx`, a thin wrapper around an RpcPeer that implements
    /// the `DataSource` trait and can be used when updating a cache.
    pub (crate) fn make_ctx(&self) -> FetchCtx {
        FetchCtx {
            view_id: self.view_id,
            plugin_id: self.plugin_id,
            peer: self.peer.clone(),
        }
    }

    /// Returns the length of the view's buffer, in bytes.
    pub fn get_buf_size(&self) -> usize {
        self.buf_size
    }

    pub fn get_path(&self) -> Option<&Path> {
        self.path.as_ref().map(PathBuf::as_path)
    }

    pub fn get_config(&self) -> &BufferConfig {
        &self.config
    }

    pub fn get_cache(&mut self) -> &mut C {
        &mut self.cache
    }

    pub fn get_id(&self) -> ViewIdentifier {
        self.view_id.clone()
    }

    pub fn get_line(&mut self, line_num: usize) -> Result<&str, Error> {
        let ctx = self.make_ctx();
        self.cache.get_line(&ctx, line_num)
    }

    pub fn add_scopes(&self, scopes: &Vec<Vec<String>>) {
        let params = json!({
            "plugin_id": self.plugin_id,
            "view_id": self.view_id,
            "scopes": scopes,
        });
        self.peer.send_rpc_notification("add_scopes", &params);
    }

    pub fn update_spans(&self, start: usize, len: usize, spans: &[ScopeSpan]) {
        let params = json!({
            "plugin_id": self.plugin_id,
            "view_id": self.view_id,
            "start": start,
            "len": len,
            "rev": self.rev,
            "spans": spans,
        });
        self.peer.send_rpc_notification("update_spans", &params);
    }

    pub fn schedule_idle(&self) {
        let token: usize = self.view_id.into();
        self.peer.schedule_idle(token);
    }

    /// Returns `true` if an incoming RPC is pending. This is intended
    /// to reduce latency for bulk operations done in the background.
    pub fn request_is_pending(&self) -> bool {
        self.peer.request_is_pending()
    }

}

/// A simple wrapper type that acts as a `DataSource`.
pub struct FetchCtx {
    plugin_id: PluginPid,
    view_id: ViewIdentifier,
    peer: RpcPeer,
}

impl DataSource for FetchCtx {
    fn get_data(&self, start: usize, unit: TextUnit, max_size: usize, rev: u64)
        -> Result<GetDataResponse, Error> {
        let _t = trace_block("FetchCtx::get_data", &["plugin"]);
        let params = json!({
            "plugin_id": self.plugin_id,
            "view_id": self.view_id,
            "start": start,
            "unit": unit,
            "max_size": max_size,
            "rev": rev,
        });
        let result = self.peer.send_rpc_request("get_data", &params)
            .map_err(|e| Error::RpcError(e))?;
        GetDataResponse::deserialize(result)
            .map_err(|_| Error::WrongReturnType)
    }
}
<|endoftext|>


<commit_before>// Use GIT to see the history of this file
fn largest_i32(list: &[i32]) -> i32 {
    let mut largest = list[0];

    for &item in list {
        if item > largest {
            largest = item;
        }
    }

    largest
}

fn largest_char(list: &[char]) -> char {
    let mut largest = list[0];

    for &item in list {
        if item > largest {
            largest = item;
        }
    }

    largest
}

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let result = largest_i32(&number_list);
    println!("The largest numern is {}", result);

    let char_list = vec!['y', 'm', 'a', 'q'];
    let result = largest_char(&char_list);
    println!("the largest char is {}", result);
}
<commit_msg>v2<commit_after>// Use GIT to see the history of this file
fn largest<T>(list: &[T]) -> T {
    let mut largest = list[0];

    for &item in list {
        if item > largest {
            largest = item;
        }
    }

    largest
}

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let result = largest(&number_list);
    println!("The largest numern is {}", result);

    let char_list = vec!['y', 'm', 'a', 'q'];
    let result = largest(&char_list);
    println!("the largest char is {}", result);
}
<|endoftext|>